【问题标题】:Log jax-ws http request and response记录 jax-ws http 请求和响应
【发布时间】:2012-11-08 08:39:11
【问题描述】:

我需要在 JAX-WS WebService 调用中记录完整的 http 请求和响应。对于请求,我需要请求标头和正文,对于响应,我需要响应标头和正文。

经过一番研究,我发现我可以通过该属性获取此信息:

-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true

并显示我需要的信息,但它会将其转储到控制台,我需要使用内部请求 ID 将其存储在数据库中。

我已经尝试实现一个处理程序:

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound) {
            System.out.println("SOAP outbound!!!!!");
            Map<String, List<String>> responseHeaders = (Map<String, List<String>>) context
                    .get(SOAPMessageContext.HTTP_RESPONSE_HEADERS);
            try {
                String headers = getHeaders(responseHeaders);
                System.out.println(headers);
                String body = getBody(context.getMessage());
                System.out.println(body);
            } catch (Exception ex) {
                // TODO: What do I have to do in this case?
            }
        } else {
            System.out.println("SOAP inbound!!!!!");
            Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context
                    .get(SOAPMessageContext.HTTP_REQUEST_HEADERS);
            try {
                String headers = getHeaders(requestHeaders);
                System.out.println(headers);
                String body = getBody(context.getMessage());
                System.out.println(body);
            } catch (Exception ex) {
                // TODO: What do I have to do in this case?
            }
        }
        return true;
    }

    private String getBody(SOAPMessage message) throws SOAPException, IOException {
        OutputStream stream = new ByteArrayOutputStream();
        message.writeTo(stream);
        return stream.toString();
    }

    public String getFullHttpRequest(HttpServletRequest request) throws IOException {
        InputStream in = request.getInputStream();
        String encoding = request.getCharacterEncoding();
        encoding = encoding == null ? "UTF-8" : encoding;
        String body = IOUtils.toString(in, encoding);
        return body;
    }

    private String getHeaders(Map<String, List<String>> headers) throws IOException {
        StringBuffer result = new StringBuffer();
        if (headers != null) {
            for (Entry<String, List<String>> header : headers.entrySet()) {
                if (header.getValue().isEmpty()) {
                    // I don't think this is legal, but let's just dump it,
                    // as the point of the dump is to uncover problems.
                    result.append(header.getValue());
                } else {
                    for (String value : header.getValue()) {
                        result.append(header.getKey() + ": " + value);
                    }
                }
                result.append("\n");
            }
        }
        return result.toString();
    }

}

但在这种情况下,我可以获取 http 请求标头和正文,但在响应中,我只获取正文,http 响应标头始终为空。

知道如何归档这个吗?目标是能够将完整的 http 请求和响应存储在数据库中。

谢谢!!

【问题讨论】:

    标签: java logging jax-ws


    【解决方案1】:

    你也可以试试

        -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
    

    我假设您从某种 Java EE 应用服务器(而不是独立客户端)中提供 Web 服务。您无法在 Web/Java EE 容器的上下文之外访问 Java EE 基础架构,例如 HttpServletRequestHttpServletResponse

    您可以尝试使用

        HttpServletResponse response = (HttpServletResponse) messageContext.get(SOAPMessageContext.SERVLET_RESPONSE); //messageContext is the SOAPMessageContext
        List<String> responseHeaderNames = (List<String>)response.getHeaderNames();
            for(String headerName : responseHeaderNames){
                 //Do whatever you want with it.
                  }
    

    我严重怀疑您是否能够在处理程序中获得完整的响应标头。你的问题真的让我很感兴趣,我花了很多时间研究这部分。在我见过的所有代码示例中,甚至metro site 上的示例都没有尝试实现此功能,我认为原因很简单。在调用处理程序时,容器可能没有足够的确定信息来在出站消息上标记 http 标头。你也许可以添加东西,但这也是值得怀疑的。

    【讨论】:

    • 感谢您的回复。我在 Tomcat 应用程序服务器中使用 Spring 3 提供 web 服务。你的第一个提案,只是将它转储到控制台,对吗?我需要能够将它存储在数据库中,关于第二个选项,我会试一试。谢谢!
    • @drublik 当然,让我们知道它是如何工作的。我很好奇一个
    • 感谢您的回复,但 HttpServletResponse 没有“getHeaderNames()”方法。事实上,它似乎没有任何方法来获取标题,只有设置。此函数仅在 HttpServletRequest 中。
    • @drublik,您使用的是哪个 servlet 版本?我可以保证它在 3.0 中可用
    • 好的!我使用的是 servlet-api 2.5,因为目标服务器是 Tomcat 6.0.24(我认为 servlet-api 3.0 仅在 Tomcat 7 或更高版本中可用)
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2010-12-29
    • 2016-02-13
    • 2016-11-21
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多