java 记录 jax-ws http 请求和响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13285342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:07:36  来源:igfitidea点击:

Log jax-ws http request and response

javaloggingjax-ws

提问by drublik

I need to log the full http request and response in a JAX-WS WebService call. For the request I need the request headers and the body and for the response, response headers and body.

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

After some researching, I've found that I can get this information with the property:

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

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

and show the information that I need but it dumps it to the console and I need to store it in the database with an internal request id.

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

I've tried to implement a handler:

我试图实现一个处理程序:

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();
    }

}

but in this case, I can get the http request headers and body but in the response, I only get the body, http response headers are always empty.

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

Any idea on how to archieve this? The objective is to be able to store the full http request and response in a database.

关于如何存档的任何想法?目标是能够在数据库中存储完整的 http 请求和响应。

Thanks!!

谢谢!!

回答by kolossus

You could also try

你也可以试试

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

I'm assuming you're providing your web service from within a Java EE application server of some sort (and not from a standalone client). You cannot have access to Java EE infrastructure like HttpServletRequestand HttpServletResponseoutside of the context of a web/Java EE container.

我假设您从某种 Java EE 应用程序服务器(而不是从独立客户端)中提供 Web 服务。你不能有像访问Java EE基础设施HttpServletRequestHttpServletResponse外部网/ Java EE容器的背景下。

You could try to get your hands on the actual servlet response object (within a web context) with

您可以尝试使用实际的 servlet 响应对象(在 Web 上下文中)

    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.
              }

I seriously doubt that you'll be able to get your hands on the full response headers within a handler though. Your question really intrigued me and I've spent quite some time researching that part. In all the code samples I've seen, Not even the example on the metro siteattempt to implement this functionality and I think the reason is simple. As at the point where a handler is invoked, the container may not have enough definitive information to stamp an http header on the outbound message. You might be able to add stuff but that's doubtful as well.

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