SpringBoot專案中使用webservice呼叫遠端服務
阿新 • • 發佈:2019-02-16
有一個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;
}
}