webservice 的日常:webservice的测试之camel
简介
使用camel-cxf测试webservice
依赖:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
新增camel客户端配置:
@Component
@Slf4j
public class CamelClient {
private final CamelContext camelContext;
private final ProducerTemplate template;
@Autowired
private CamelTLSFactory camelTLSFactory;
CamelClient() {
this.camelContext = new DefaultCamelContext();
this.template = this.camelContext.createProducerTemplate();
}
@PostConstruct
public void init() throws Exception {
camelContext.disableJMX();
camelContext.start();
}
private void configureTLS(CxfEndpoint cxfEndpoint) {
Bus bus = new SpringBus();
ConduitInitiatorManager cim = bus.getExtension(ConduitInitiatorManager.class);
if (cim != null) {
cim.registerConduitInitiator(TRANSPORT_ID, camelTLSFactory);
cxfEndpoint.setTransportId(TRANSPORT_ID);
cxfEndpoint.setBus(bus);
}
}
public void addRoute(String endpoint, String url) throws Exception {
camelContext.addRoutes(new RouteBuilder() {
@Override
public void configure() {
CxfEndpoint cxfEndpoint = (CxfEndpoint) getContext().getEndpoint("cxf:" + url);
configureTLS(cxfEndpoint);
// cxfEndpoint.setServiceClass(RseSoapApiPortType.class); // HelloApiPort,正常ws经常xjc插件生成的对象
cxfEndpoint.setDefaultOperationName("方法名,即action:urn对应的名称");
cxfEndpoint.setBindingId(SOAPBinding.SOAP12HTTP_BINDING);
cxfEndpoint.setSynchronous(true);
from("direct:" + endpoint).routeId(endpoint).process(e -> {
if (e == null) {
return;
}
Object req = e.getIn().getBody();
e.getOut()
.setHeader(CxfConstants.OPERATION_NAME, e.getProperties().get(CxfConstants.OPERATION_NAME));
setSessionHeader(e);
e.getOut().setBody(req);
}).to(cxfEndpoint).process(e -> {
if (e == null) {
return;
}
Class retType = (Class) e.getProperties().get("ReturnType");
e.getOut().setBody(e.getIn().getBody(retType));
});
}
});
}
public void removeRoute(String uuID) {
try {
camelContext.stopRoute(uuID);
camelContext.removeRoute(uuID);
} catch (Exception e) {
// log.error("Failed to remove Route {}", uuID, e);
}
}
private void setSessionHeader(Exchange e) throws JAXBException {
// Qname填写自定义的命名空间和header
SoapHeader hdr = new SoapHeader(new QName("Namespace", "SessionHead"),
new JAXBDataBinding("Header".getClass()));
List<SoapHeader> soapHeaders = new ArrayList<>();
soapHeaders.add(hdr);
e.getOut().setHeader(Header.HEADER_LIST, soapHeaders);
}
public Object send(String uuID, String rseOperation, Object req, Class clazz, String sessionID) throws Exception {
Exchange exchange = new DefaultExchange(camelContext);
exchange.getIn().setBody(req);
if (sessionID != null) {
exchange.getProperties().put("sessionID", sessionID);
}
exchange.getProperties().put("ReturnType", clazz);
exchange.getProperties().put(CxfConstants.OPERATION_NAME, rseOperation);
template.send("direct:"+ uuID, exchange);
Exception throwable = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
if (throwable != null) {
throw throwable;
}
return exchange.getOut().getBody();
}
@PreDestroy
public void destroy() throws Exception {
// template.cleanUp();
camelContext.stop();
}
}
@Slf4j
@Component
class CamelTLSFactory implements ConduitInitiator {
private final HTTPTransportFactory factory = new HTTPTransportFactory();
@Override
public Conduit getConduit(EndpointInfo endpointInfo, Bus bus) throws IOException {
HTTPConduit httpConduit = (HTTPConduit) factory.getConduit(endpointInfo, bus);
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(3000);
httpClientPolicy.setReceiveTimeout(3000);
httpConduit.setClient(httpClientPolicy);
httpConduit.setTlsClientParameters(createTlsClientParameters());
return httpConduit;
}
@Override
public Conduit getConduit(EndpointInfo endpointInfo, EndpointReferenceType target, Bus bus) throws IOException {
HTTPConduit httpConduit = (HTTPConduit) factory.getConduit(endpointInfo, target, bus);
httpConduit.setTlsClientParameters(createTlsClientParameters());
return httpConduit;
}
@Override
public Set<String> getUriPrefixes() {
return factory.getUriPrefixes();
}
@Override
public List<String> getTransportIds() {
return factory.getTransportIds();
}
private TLSClientParameters createTlsClientParameters() throws IOException {
TLSClientParameters tlsClientParameters = new TLSClientParameters();
// DisableCNCheck
tlsClientParameters.setDisableCNCheck(true);
try {
tlsClientParameters.setTrustManagers(new TrustManager[] {new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}});
} catch (Exception e) {
log.error("error when set KeyStore", e);
throw new IOException(e.getMessage());
}
return tlsClientParameters;
}
}
测试类:
@Autowired
private CamelClient camelClient;
@PostMapping("/camel")
public void testCamel() throws Exception {
camelClient.addRoute("test", "http://localhost:8080/services/Hello?wsdl");
camelClient.send("test", "hello", new HelloRequest(), HelloResponse.class, "1234");
camelClient.removeRoute("test");
}
ps:
camel请求配置相对复杂,但配置属性详细,适合实际场景应用。
githup:
webservice源码