有一个webservice项目,对外提供资源查询服务,使用了Apache的cxf框架,soap协议。如今都使用微服务,在一个springboot项目中需要远程调用这个资源查询服务,RPC的一种,既然是RPC,就需要有客户端的存根(stub)和服务端的骨架(skeleton)来完成调用,将webservice项目打成jar作为依赖引入当前springboot项目。
而在springboot中配置webservice也很简单,写一个配置类,设置必要的参数(例如远程服务器地址、连接超时等);最后注册为容器中的一个bean,就可以在service层直接注入这个bean来点出其中的方法进行调用了。例如再写了下面这个配置类以后,在service层这么做:
// 这里的IUserRemoteService是你webservice项目里面提供的接口,所以你看情况,需要哪个接口,就在配置
// 类里面注册哪个,然后再注入同样的bean就可以使用了
@Autowired
IUserRemoteService userRemoteService;
public void test(String id) {
// 这个对象能点出来什么方法,就看webservice项目中该接口提供了哪些方法了
User user = userRemoteService.getUserById(id);
//.........其他操作省略
}
此处配置类中有一个拦截器,有时为了安全的需要,我们需要做ak/sk的检验,这个不是必须的。这里我在header中加了一个sig,自定义soap拦截器需要实现相应的接口,当然这些webservice项目都帮你做好了,你直接在配置类中注册bean就行,客户端和服务端要保持一致,不然校验不通过。
拦截器:
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class HeaderInterceptor extends AbstractSoapInterceptor {
private String sig;
public HeaderInterceptor() {
super("write");
}
public void handleMessage(SoapMessage message) throws Fault {
Document doc = DOMUtils.createDocument();
Element headerNode = doc.createElement("sig");
headerNode.setTextContent(this.sig);
SoapHeader header = new SoapHeader(new QName("RequestSOAPHeader"), headerNode);
message.getHeaders().add(header);
}
public void setSig(String sig) {
this.sig= sig;
}
}
配置类:
import com.wisely.ws.filter.HeaderInterceptor;
import com.wisely.ws.interfaces.IUserRemoteService;
import com.google.common.collect.Lists;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "test")
public class WebServiceConfig {
private String sig;
private long connectionTimeout = 10000;
private long receiveTimeout = 10000;
private String userRemoteService;
@Bean
public HeaderInterceptor headerInterceptor() {
HeaderInterceptor headerInterceptor = new HeaderInterceptor();
headerInterceptor.setSig(sig);
return headerInterceptor;
}
/**
* 用户信息
*
* @param headerInterceptor
* @return
*/
@Bean
public IUserRemoteService userRemoteService(Interceptor<? extends Message> headerInterceptor) {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
List<Interceptor<? extends Message>> interceptors = Lists.newArrayList();
interceptors.add(headerInterceptor);
jaxWsProxyFactoryBean.setOutInterceptors(interceptors);
jaxWsProxyFactoryBean.setServiceClass(IUserRemoteService.class);
jaxWsProxyFactoryBean.setAddress(userRemoteService);
IUserRemoteService userRemoteService = (IUserRemoteService) jaxWsProxyFactoryBean.create();
setWSHttpPolicy(userRemoteService);
return userRemoteService;
}
/**
* 设置连接超时及接收超时
*
* @param service
*/
private void setWSHttpPolicy(Object service) {
Client client = ClientProxy.getClient(service);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(connectionTimeout);
policy.setReceiveTimeout(receiveTimeout);
httpConduit.setClient(policy);
}
public void setSig(String sig) {
this.sig= sig;
}
public void setUserRemoteService(String userRemoteService) {
this.userRemoteService = userRemoteService;
}
public void setConnectionTimeout(long connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public void setReceiveTimeout(long receiveTimeout) {
this.receiveTimeout = receiveTimeout;
}
}