项目中, 因第三方不再提供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()); //自定义拦截器
问题解决。