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

Java 记录jax-ws-http请求和响应,java,logging,jax-ws,Java,Logging,Jax Ws,我需要在JAX-WSWebService调用中记录完整的http请求和响应。对于请求,我需要请求头和主体,对于响应,需要响应头和主体 经过一些研究,我发现我可以通过该属性获得以下信息: -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true 并显示我需要的信息,但它会将其转储到控制台,我需要使用内部请求id将其存储在数据库中 我已尝试实现一个处理程序: public class LoggingHandler impl

我需要在JAX-WSWebService调用中记录完整的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();
    }

}
公共类LoggingHandler实现SOAPHandler{
@凌驾
公共布尔handleMessage(SOAPMessageContext上下文){
Boolean outbound=(Boolean)context.get(MessageContext.MESSAGE\u outbound\u属性);
如果(出站){
System.out.println(“SOAP出站!!!”;
映射响应头=(映射)上下文
.get(SOAPMessageContext.HTTP\u响应\u头);
试一试{
字符串头=getHeaders(响应头);
System.out.println(标题);
字符串body=getBody(context.getMessage());
系统输出打印项次(正文);
}捕获(例外情况除外){
//托多:在这种情况下我该怎么办?
}
}否则{
System.out.println(“SOAP入站!!!”;
映射请求头=(映射)上下文
.get(SOAPMessageContext.HTTP_请求_头);
试一试{
字符串头=getHeaders(requestHeaders);
System.out.println(标题);
字符串body=getBody(context.getMessage());
系统输出打印项次(正文);
}捕获(例外情况除外){
//托多:在这种情况下我该怎么办?
}
}
返回true;
}
私有字符串getBody(SOAPMessage消息)引发SOAPException、IOException{
OutputStream=新的ByteArrayOutputStream();
message.writeTo(流);
返回stream.toString();
}
公共字符串getFullHttpRequest(HttpServletRequest请求)引发IOException{
InputStream in=request.getInputStream();
字符串编码=请求。getCharacterEncoding();
编码=编码==空?“UTF-8”:编码;
String body=IOUtils.toString(in,encoding);
返回体;
}
私有字符串getHeaders(映射头)引发IOException{
StringBuffer结果=新的StringBuffer();
如果(标题!=null){
for(条目标题:headers.entrySet()){
if(header.getValue().isEmpty()){
//我不认为这是合法的,但我们还是放弃吧,
//因为转储的目的是发现问题。
append(header.getValue());
}否则{
for(字符串值:header.getValue()){
result.append(header.getKey()+“:”+值);
}
}
结果。追加(“\n”);
}
}
返回result.toString();
}
}
但是在这种情况下,我可以得到http请求头和主体,但是在响应中,我只得到主体,http响应头总是空的

你知道怎么归档吗?目标是能够在数据库中存储完整的http请求和响应

谢谢

你也可以试试

    -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
我假设您是从某种JavaEE应用服务器(而不是从独立客户端)中提供web服务的。您不能在web/Java EE容器的上下文之外访问Java EE基础结构,如
HttpServletRequest
HttpServletResponse

您可以尝试使用

HttpServletResponse=(HttpServletResponse)messageContext.get(SOAPMessageContext.SERVLET\u response)//messageContext是SOAPMessageContext
List responseHeaderNames=(List)response.getHeaderNames();
for(字符串头名称:响应头名称){
//你想用它做什么就做什么。
}

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

谢谢你的回复。我在Tomcat应用服务器中使用Spring3提供Web服务。你的第一个提议,会把它转储到控制台上,对吗?我需要能够将其存储在数据库中,关于第二个选项,我将尝试一下。谢谢@德鲁布利克:当然,让我们知道结果如何。我很想知道您的答复,但HttpServletResponse没有“getHeaderNames()”方法。事实上,它似乎没有任何获取头的方法,只有设置头的方法。此函数仅在HttpServletRequest中。@drublik,您使用的servlet版本是什么?我可以保证它在3.0ok中可用!我使用的是ServletAPI2.5,因为目标服务器是Tomcat6.0.24(我认为ServletAPI3.0只在Tomcat7或更高版本中可用)
    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.
              }