Spring WS客户端处理HTTP错误

时间:2017-02-28 09:39:41

标签: spring web-services soap http-headers

我目前正在使用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端点)。我已将集成测试的日志记录级别设置为与实际测试环境相同。

谢谢!

2 个答案:

答案 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());

}