我在调用我的webservice时遇到问题,Spring WS只返回一个WebServiceTransportException:内部服务器错误而不是预期的SoapFaultException。当我在SOAPUI中触发调用时,我得到了soap错误。
WebServiceTransportException也会抑制响应的输出,因此我不会在日志中看到问题所在。
我在配置类的Spring启动应用程序中使用Spring WS。
vg <- Vectorize(g, vectorize.args = "z")
plot(1:10, vg(1:10, 0.7, 0.5), type = "l")
当请求正确时,一切正常。但是当请求包含错误时,我不能理解肥皂错误的原因。只有WebServiceTransportException。
public class SoapClientConfig {
private static Logger log = LoggerFactory.getLogger(SoapClientConfig.class);
private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = 60000;
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = 60000;
private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 2;
public static final int CONNECTION_REQUEST_TIMEOUT = 30000;
@Value("${soap.client.proxy.host}")
protected String proxyHost;
@Value("${soap.client.proxy.port}")
protected String proxyPort;
@Value("${soap.client.max.connections}")
private int maxConnections;
public Jaxb2Marshaller createMarshaller(String packageName) throws Exception {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath(packageName);
jaxb2Marshaller.afterPropertiesSet();
return jaxb2Marshaller;
}
public WebServiceTemplate createWebServiceTemplate(Jaxb2Marshaller marshaller, ClientInterceptor securityInterceptor, WebServiceMessageSender messageSender) {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.setMessageSender(messageSender);
if(securityInterceptor != null) {
webServiceTemplate.setInterceptors((ClientInterceptor[]) Arrays.asList(securityInterceptor, createLoggingInterceptor()).toArray());
} else {
webServiceTemplate.setInterceptors((ClientInterceptor[]) Arrays.asList(createLoggingInterceptor()).toArray());
}
webServiceTemplate.setCheckConnectionForFault(false);
webServiceTemplate.afterPropertiesSet();
return webServiceTemplate;
}
private ClientInterceptor createLoggingInterceptor() {
return new SoapLoggingInterceptor();
}
public Wss4jSecurityInterceptor createSecurityInterceptor(String username, String password) throws Exception {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementUsername(username);
wss4jSecurityInterceptor.setSecurementPassword(password);
wss4jSecurityInterceptor.setSecurementActions("UsernameToken");
wss4jSecurityInterceptor.setSecurementPasswordType("PasswordText");
wss4jSecurityInterceptor.afterPropertiesSet();
return wss4jSecurityInterceptor;
}
public HttpComponentsMessageSender createMessageSender() {
return new HttpComponentsMessageSender(createHttpClient());
}
private HttpClient createHttpClient() {
RequestConfig.Builder configBuilder = RequestConfig.custom()
.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS)
.setSocketTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS)
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT);
addProxySettings(configBuilder);
HttpClientBuilder clientBuilder = HttpClients.custom().setDefaultRequestConfig(configBuilder.build());
addInterceptor(clientBuilder);
addConnectionManager(clientBuilder);
return clientBuilder.build();
}
private void addProxySettings(RequestConfig.Builder configBuilder) {
if (StringUtils.isNotBlank(proxyHost)) {
configBuilder.setProxy(new HttpHost(proxyHost, Integer.valueOf(proxyPort)));
}
}
private void addInterceptor(HttpClientBuilder clientBuilder) {
clientBuilder.addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor());
}
private void addConnectionManager(HttpClientBuilder clientBuilder) {
if (maxConnections > DEFAULT_MAX_CONNECTIONS_PER_ROUTE) {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(maxConnections);
cm.setDefaultMaxPerRoute(maxConnections);
clientBuilder.setConnectionManager(cm);
}
}
答案 0 :(得分:1)
设置
webServiceTemplate.setCheckConnectionForFault(true);
完成了这个技巧,而不是像上面的配置类那样将其设置为false。
感谢雷迪在正确的方向上提示。我也错过了实现handleFault方法,所以我无法在日志中看到响应。对于所有想要查看LoggingInterceptor示例的人:
public class SoapLoggingInterceptor implements ClientInterceptor {
private static Logger log = LoggerFactory.getLogger(SoapLoggingInterceptor.class);
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
ByteArrayTransportOutputStream os = new ByteArrayTransportOutputStream();
try {
messageContext.getRequest().writeTo(os);
} catch (IOException e) {
throw new WebServiceIOException(e.getMessage(), e);
}
String request = new String(os.toByteArray()).replaceAll("\n", "");
log.info("Soap request\n----------------------------\n" + request + "\n----------------------------\n");
return true;
}
@Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
logMessageContext(messageContext);
return true;
}
@Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
logMessageContext(messageContext);
return true;
}
private void logMessageContext(MessageContext messageContext) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
messageContext.getResponse().writeTo(os);
} catch (IOException e) {
throw new WebServiceIOException(e.getMessage(), e);
}
String response = new String(os.toByteArray());
log.info("Soap response\n----------------------------\n" + response + "\n----------------------------\n");
}
@Override
public void afterCompletion(MessageContext messageContext, Exception e) throws WebServiceClientException {
}
class ByteArrayTransportOutputStream extends TransportOutputStream {
private ByteArrayOutputStream outputStream;
@Override
public void addHeader(String name, String value) throws IOException {
createOutputStream();
String header = name + ": " + value + "\n";
outputStream.write(header.getBytes());
}
public byte[] toByteArray() {
return outputStream.toByteArray();
}
@Override
protected OutputStream createOutputStream() throws IOException {
if (outputStream == null) {
outputStream = new ByteArrayOutputStream();
}
return outputStream;
}
}
}