我目前正在使用Spring WS开发SOAP客户端。我按照指南/教程进行操作,一切正常。除了一件事,错误处理。
我无法控制发送消息的SOAP端点。所以我想在出现问题时做一些好的异常处理。我在测试场景中遇到了一些我没有依赖的HTTP错误。我不知道如何处理它们。
例如:
我将SOAP消息发送到错误的URL。哪个返回了不允许的HTTP 405方法。 (我将POST发送到仅限GET的URL,这是一个配置错误但仍然是错误)。 在body中,字面上是来自SOAP端点的HTML错误页面。 Ofcourse Spring无法处理此消息并抛出异常。在堆栈跟踪中很明显它是405.但是我想提取返回的错误代码并以其他方式记录它(或者将它发送回用户发送SOAP消息的请求)。
这些是我在发送SOAP消息后收到的一些日志消息(其他日志记录被省略):
org.apache.http.wire : << "HTTP/1.1 405 Method Not Allowed[\r][\n]"
o.a.h.impl.conn.DefaultClientConnection : Receiving response: HTTP/1.1 405 Method Not Allowed
org.apache.http.headers : << HTTP/1.1 405 Method Not Allowed
有没有办法捕获并提取这些HTTP错误代码? 如果需要更多信息,请询问。我愿意提供尽可能多的信息,但我不知道此时还有什么要发布。
编辑:或者有没有办法用集成测试来模拟/测试它?我无法继续向真正的SOAP端点发送消息。我没有从集成测试中获得与真实测试相同的输出(启动应用程序并将消息发送到真正的SOAP端点)。我已将集成测试的日志记录级别设置为与实际测试环境相同。谢谢!
答案 0 :(得分:0)
您可以通过扩展spring WebServiceTemplate并覆盖handleError方法并添加自定义实现来创建自己的wsTemplate。
不确定您使用的是哪个版本,但常见的默认实现如下所示:
protected Object handleError(WebServiceConnection connection, WebServiceMessage request) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("Received error for request [" + request + "]");
}
throw new WebServiceTransportException(connection.getErrorMessage());
}
更强大和理想的方法是编写自己的org.springframework.ws.client.support.interceptor.ClientInterceptor并通过setInterceptors方法在wsTemplate中设置。不确定您从MessageContext对象中获取的内容是否足以满足您的要求,但所有soap故障都将以这种方式截获。
public class MyClientInterceptor implements ClientInterceptor {
public boolean handleFault(MessageContext messageContext){
// custom implementation
}
public boolean handleRequest(MessageContext messageContext){
return true;
}
public boolean handleResponse(MessageContext messageContext){
return true;
}
}
答案 1 :(得分:0)
以@artemisian的答案为基础-您可以将WebServiceConnection
强制转换为其基础实现(我在使用HttpComponentsConnection
),然后使用它来访问响应标头/正文。
protected Object handleError(WebServiceConnection connection, WebServiceMessage request) throws IOException {
if(connection instanceof HttpComponentsConnection) {
HttpComponentsConnection conn = (HttpComponentsConnection) connection;
for(Iterator<String> it = conn.getResponseHeaderNames(); it.hasNext(); )
for(Iterator<String> vt = conn.getResponseHeaders(it.next()); vt.hasNext(); )
... do something ...
conn.getHttpResponse().getEntity().writeTo( ... some stream ... );
}
if (logger.isDebugEnabled()) {
logger.debug("Received error for request [" + request + "]");
}
throw new WebServiceTransportException(connection.getErrorMessage());
}