天天看点

关于webservice的cxf服务端与axis2客户端SOAPAction不匹配的问题解决

项目中, 因第三方不再提供webservice测试环境, 而我们有代码变动需要测试, 无奈只能自己自己开发一个模拟的仿真环境进行测试。

我们使用 cxf 根据 wsdl 文件定义了接口、实现、并顺利启动。

代码因为涉及保密不能上传原本的, 因此放点其他人的, 大同小异的。

maven

<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.2.6</version>
        </dependency>
           

定义接口

@Service
@WebService(name = "hello", // 暴露服务名称
        targetNamespace = "http://test.service.webService.com/"// 命名空间,一般是接口的包名倒序
)
@BindingType(value=SOAPBinding.SOAP11HTTP_BINDING)
public interface HelloDataHandle {
    @WebMethod
    String hello(String input);
}

           

实现

@WebService(serviceName = "hello", // 暴露服务名称
        targetNamespace = "http://test.service.webService.com/",// 命名空间,一般是接口的包名倒序
        endpointInterface = "com.webService.service.test.HelloDataHandle"// 接口地址
)
public class HelloData implements HelloDataHandle {
    @Override
    public String hello(String input) {
    	return "收到数据: "+input;
    }
}

           

启动

@Component
public class WebServiceStartMyListener implements ApplicationRunner {

    @Value("${webservice.path}")
    private String path;

    WebServiceStartMyListener(){

    }

    WebServiceStartMyListener(String path){
        this.path=path;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("发布地址:"+path);
//        Endpoint.publish(path, new SyyhConvertData());
//        System.out.println("发布成功");

        JaxWsServerFactoryBean server=new JaxWsServerFactoryBean();

    //    server.getInInterceptors().add(new MyWebServiceServerInterceptor());  //自定义拦截器
       


        server.setAddress(path);
        server.setServiceClass(HelloData.class);
        server.setServiceBean(new HelloData());
        server.create();

        System.out.println("server ready");
    }


    public static void main(String[] args) throws Exception{
        new WebServiceStartMyListener("http://127.0.0.1:8888/ckwWebService/SyyhConvertData").run(null);
    }
}
           

至此服务能够正常启动, 但是 axis2 客户端访问报错

SOAPAction 不匹配

客户端的 wsdl 文件里面的 soapaction 是"" , 但是发送到服务端内的是 urn:anonOutInop, 看了好多百度出来的这个 soapaction 的不匹配的问题的解决方法,因为客户端不能动, 都不适用, 后面想起来有cxf 的拦截器…

debug 模式看一下 message 的内容, 把SOAPAction里面的值改了。

自定义拦截器:

public class MyWebServiceServerInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    public MyWebServiceServerInterceptor() {
        super(Phase.RECEIVE); //在收到的时候调用

    }

    public void handleMessage(SoapMessage message) throws Fault {
        
//        Object headers = message.get(Message.PROTOCOL_HEADERS);//根据soap消息获取头部
        TreeMap headers =  (TreeMap)message.get(Message.PROTOCOL_HEADERS);
        ArrayList<String> soapAction = new ArrayList<>();
        soapAction.add("\"\"");
        headers.put("SOAPAction",soapAction);
    }

}
           

在服务端注册自定义拦截器:

server.getInInterceptors().add(new MyWebServiceServerInterceptor());  //自定义拦截器
           

问题解决。