我正在研究如何使用CXF将SOAP客户端构建到Spring Boot应用程序中。特别是我对配置请求/响应日志记录感兴趣。
前提条件:CXF Maven插件用于从WSDL文件生成Java存根。
我研究了许多教程[1] [2] [3],他们都做了不同的尝试。问题是是否有一种“正式认可”的方式将CXF客户端与Spring Boot集成。 CXF文档似乎没有说明。
选项1:BindingProvider
我正在使用的现有代码(不是我的代码)是这样的:
@Bean
public PartnerServicePortType partnerServicePortType() {
PartnerServicePortType partnerServicePortType = new PartnerServiceV0().getPartnerService();
configureService((BindingProvider) partnerServicePortType, Services.PARTNER_SERVICE.serviceName());
return partnerServicePortType;
}
private void configureService(BindingProvider bindingProvider, String path) {
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, baseUrl + path);
if (!StringUtils.isEmpty(username)) {
bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
}
/* add logging interceptors
Client client = ClientProxy.getClient(bindingProvider);
Endpoint cxfEndpoint = client.getEndpoint();
cxfEndpoint.getInInterceptors().add(new PayloadExtractingLoggingInInterceptor());
cxfEndpoint.getInFaultInterceptors().add(new PayloadExtractingLoggingInInterceptor());
cxfEndpoint.getOutInterceptors().add(new PayloadExtractingLoggingOutInterceptor());
cxfEndpoint.getOutFaultInterceptors().add(new PayloadExtractingLoggingOutInterceptor());
*/
}
PartnerServiceV0
是生成的类javax.xml.ws.Service
,如下所示:
@WebServiceClient(name = "PartnerService_v0",
wsdlLocation = "classpath:some.wsdl",
targetNamespace = "urn:some-namespace")
public class PartnerServiceV0 extends Service {
如您所见,我添加了代码以启用configureServcie
方法的请求/响应日志记录。当 工作时,我们必须为每项服务完成所有这些工作,这有点奇怪。
选项2:JaxWsProxyFactoryBean
出于验证目的,我将上述代码移植到使用JaxWsProxyFactoryBeans
:
@Bean(name = "partnerService")
public PartnerServicePortType generateProxy() {
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.setServiceClass(PartnerServicePortType.class);
proxyFactory.setAddress(baseUrl + Services.PARTNER_SERVICE.serviceName());
if (!StringUtils.isEmpty(username)) {
proxyFactory.setUsername(username);
proxyFactory.setPassword(password);
}
return (PartnerServicePortType) proxyFactory.create();
}
添加日志记录配置是我还需要弄清楚的策略。
我选中的教程
答案 0 :(得分:1)
我使用一些jx-ws web服务和cxf这样的代码
package org.roshan.framework.config;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.inject.Inject;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.roshan.framework.config.PaymentProperties.WebServiceDetail.SSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import com.tosan.modern.epayment.webservice.merchant.paymentservice.TosanIPGWS;
import com.tosan.modern.yaghut.service.SoapServices;
@Configuration
public class WebServiceClient {
@Inject
private PaymentProperties paymentProperties;
@Autowired
private ResourceLoader resourceLoader;
@Bean(name = "PaymentWebService")
public TosanIPGWS PaymentWebServiceCLient() throws MalformedURLException {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(TosanIPGWS.class);
factory.setAddress(paymentProperties.getShaparak().getWsPublicUrl());
TosanIPGWS service = (TosanIPGWS) factory.create();
try {
final Client client = ClientProxy.getClient(service);
// client.getInInterceptors().add(new LoggingInInterceptor());
// client.getOutInterceptors().add(new LoggingOutInterceptor());
setupSsl((HTTPConduit) client.getConduit(), paymentProperties.getShaparak().getSsl());
} catch (Exception e) {
// System.out.println("PaymentWebServiceCLient v9898989898");
System.out.println(e.getMessage());
}
return service;
}
private void setupSsl(HTTPConduit httpConduit, SSL ssl) throws Exception {
final String keyStoreLoc = ssl.getKeyStore();
final String keyPassword = ssl.getKeyStorePassword();
final String keystoreType = ssl.getKeyStoreType();
final String trustStoreLoc = ssl.getTrustStore();
final String trustStorePassword = ssl.getTrustStorePassword();
final String trustStoreType = ssl.getTrustStoreType();
final TLSClientParameters tlsCP = new TLSClientParameters();
tlsCP.setDisableCNCheck(true);
if (ssl.getKeyStore() != null && !ssl.getKeyStore().isEmpty()) {
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
Resource resource1 = resourceLoader.getResource(keyStoreLoc);
keyStore.load(resource1.getInputStream(), keyPassword.toCharArray());
final KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
tlsCP.setKeyManagers(myKeyManagers);
}
if (ssl.getTrustStore() != null && !ssl.getTrustStore().isEmpty()) {
final KeyStore trustStore = KeyStore.getInstance(trustStoreType);
Resource resource2 = resourceLoader.getResource(trustStoreLoc);
trustStore.load(resource2.getInputStream(), trustStorePassword.toCharArray());
final TrustManager[] myTrustStoreKeyManagers = getTrustManagers(trustStore);
tlsCP.setTrustManagers(myTrustStoreKeyManagers);
}
httpConduit.setTlsClientParameters(tlsCP);
}
private static TrustManager[] getTrustManagers(KeyStore trustStore) throws NoSuchAlgorithmException, KeyStoreException {
String alg = KeyManagerFactory.getDefaultAlgorithm();
TrustManagerFactory fac = TrustManagerFactory.getInstance(alg);
fac.init(trustStore);
return fac.getTrustManagers();
}
private static KeyManager[] getKeyManagers(KeyStore keyStore, String keyPassword) throws GeneralSecurityException, IOException {
String alg = KeyManagerFactory.getDefaultAlgorithm();
char[] keyPass = keyPassword != null ? keyPassword.toCharArray() : null;
KeyManagerFactory fac = KeyManagerFactory.getInstance(alg);
fac.init(keyStore, keyPass);
return fac.getKeyManagers();
}
}
答案 1 :(得分:1)
您可以直接使用JaxWsProxyFactoryBean
设置日志记录拦截器或直接使用日志记录功能,如下所示。
@Bean
public HelloWorld bus(SpringBus bus) {
JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
bean.setServiceClass(HelloWorld.class);
bean.setAddress(serverUrl);
bean.setBus(bus);
//bean.setInInterceptors(Collections.singletonList(new LoggingInInterceptor()));
bean.setFeatures(Collections.singletonList(new LoggingFeature()));
return bean.create(HelloWorld.class);
}
Here是完整的示例。