Java 如何调试通过网络传输的所有内容(http)

Java 如何调试通过网络传输的所有内容(http),java,debugging,glassfish,glassfish-4,Java,Debugging,Glassfish,Glassfish 4,我正在尝试调试Glassfish 4中的一些Rest服务,我希望确切地看到通过网络(HTTP连接)发送的内容。有没有办法让Glassfish打印出来 我的项目使用并且我知道可以在那里配置它,但是我无法让它与我们的日志框架(java.util.logging)一起工作 编辑:或者,是否有一种方法可以调试Jersey,使其打印出此信息?您不需要指定是否控制客户端/前端,或者是否仅控制后端 我立刻想到了一些想法: 使用数据包嗅探器/分析器(如前所述)。效果很好,唯一的问题是生成的数据可能比您真正想要查

我正在尝试调试Glassfish 4中的一些Rest服务,我希望确切地看到通过网络(HTTP连接)发送的内容。有没有办法让Glassfish打印出来

我的项目使用并且我知道可以在那里配置它,但是我无法让它与我们的日志框架(java.util.logging)一起工作


编辑:或者,是否有一种方法可以调试Jersey,使其打印出此信息?

您不需要指定是否控制客户端/前端,或者是否仅控制后端

我立刻想到了一些想法:

  • 使用数据包嗅探器/分析器(如前所述)。效果很好,唯一的问题是生成的数据可能比您真正想要查看/分析的数据多得多

  • 使用类似于或的代理。可以将其配置为精确显示/记录您想要/需要的数据。缺点是它们是代理(即必须在连接的中间),这可能会导致配置困难,如果你把它放在你的服务器前面。通常,在客户端进行配置要容易得多,只需将客户端流量推送到客户端即可。Fiddler是免费的,但只基于Windows(Mac和Linux的alpha版本)。查尔斯有一个试用版,否则是50美元(如果记忆有用的话)。我也不知道Fiddler和/或Charles是否会以无头模式运行

  • 设置您自己的Http代理服务器,并通过该服务器记录所有内容。这不是一个真正理想的解决方案,但仍然是一个选择

  • 在应用程序中添加一个过滤器,以记录所有进出的HTTP数据,但这会变得棘手/混乱,而且传入的HTTP请求主体是单读的,因此需要缓存它们以进行多次读取/访问(有关此问题的建议解决方案,请参阅和)


  • 您使用的http客户端版本是什么?对于http客户端4,它位于log4j中:

    log4j.category.org.apache.http.wire=DEBUG
    
    或者使用util日志:

    org.apache.http.wire.level=FINEST
    

    如果您有权访问代码,您可以:

  • 更新日志以从HTTP客户端打印信息
  • 添加HTTP拦截器,如下所示:

    public class HttpLogInterceptor extends HandlerInterceptorAdapter {
    
    @Autowired
    private RequestDumper requestDumper;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        requestDumper.doLogRequest(request, response);
        return true;
    };
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
        requestDumper.doLogResponse(request, response);
    }
    
    }


  • 并使用以下内容或类似内容:

    通过使用过滤器,我们可以跟踪响应,将此过滤器配置添加到web.xml文件中

    <filter-mapping>
        <filter-name>Test</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>Test</filter-name>
        <filter-class>net.vsspl.Test</filter-class>
    </filter>
    
    
    试验
    /*
    试验
    net.vsspl.Test
    
    滤池是空的

    import java.io.IOException;
    import java.util.ArrayList;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;
    
    public class Test implements Filter {
    
      public void init(FilterConfig filterConfig) throws ServletException {}
    
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, response);
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        System.out.println("Status Code" + httpServletResponse.getStatus());
        System.out.println("Name of the character encoding" + httpServletResponse.getCharacterEncoding());
        System.out.println("Content type" + httpServletResponse.getContentType());
        ArrayList<String> headers = (ArrayList<String>) httpServletResponse.getHeaderNames();
        for (String header : headers) {
          System.out.println(header + " Header value" + httpServletResponse.getHeader(header));
        }
      }
    
      public void destroy() {}
    
    }
    
    import java.io.IOException;
    导入java.util.ArrayList;
    导入javax.servlet.Filter;
    导入javax.servlet.FilterChain;
    导入javax.servlet.FilterConfig;
    导入javax.servlet.ServletException;
    导入javax.servlet.ServletRequest;
    导入javax.servlet.ServletResponse;
    导入javax.servlet.http.HttpServletResponse;
    公共类测试实现了过滤器{
    public void init(FilterConfig FilterConfig)抛出ServletException{}
    public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException{
    链式过滤器(请求、响应);
    HttpServletResponse HttpServletResponse=(HttpServletResponse)响应;
    System.out.println(“状态代码”+httpServletResponse.getStatus());
    System.out.println(“字符编码的名称”+httpServletResponse.getCharacterEncoding());
    System.out.println(“内容类型”+httpServletResponse.getContentType());
    ArrayList headers=(ArrayList)httpServletResponse.getHeaderNames();
    for(字符串标题:标题){
    System.out.println(header+“header value”+httpServletResponse.getHeader(header));
    }
    }
    public void destroy(){}
    }
    
    其他人建议使用wireshark,这是一个很好的工具,但使用起来有些麻烦。您通常需要捕获流量,将其传输到桌面,然后查看

    我最常用的工具是ngrep,它结合了tcpdump风格的包过滤器和grep风格的包内容过滤器,以及一种足以调试大多数HTTP问题的输出显示风格

    $ sudo ngrep -d tun0 '^(GET|POST|HEAD|HTTP)' port 80
    interface: tun0 (10.104.1.6/255.255.255.255)
    filter: (ip or ip6) and ( port 80 )
    match: ^(GET|POST|HEAD|HTTP)
    ####
    T 10.104.1.6:39700 -> 93.184.216.119:80 [AP]
      GET / HTTP/1.1..User-Agent: Wget/1.14 (linux-gnu)..Accept: */*..Host: examp
      le.com..Connection: Keep-Alive....                                         
    ##
    T 93.184.216.119:80 -> 10.104.1.6:39700 [A]
      HTTP/1.1 200 OK..Accept-Ranges: bytes..Cache-Control: max-age=604800..Conte
      nt-Type: text/html..Date: Fri, 24 Oct 2014 11:21:44 GMT..Etag: "359670651".
      .Expires: Fri, 31 Oct 2014 11:21:44 GMT..Last-Modified: Fri, 09 Aug 2013 23
      :54:35 GMT..Server: ECS (cpm/F9D5)..X-Cache: HIT..x-ec-custom-error: 1..Con
      tent-Length: 1270....<!doctype html>.<html>.<head>.    <title>Example Domai
      n</title>..    <meta charset="utf-8" />.    <meta http-equiv="Content-type"
       content="text/html; charset=utf-8" />.    <meta name="viewport" content="w
      idth=device-width, initial-scale=1" />.    <style type="text/css">.    body
       {.        background-color: #f0f0f2;.        margin: 0;.        padding: 0
      ;.        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, san
      s-serif;.        .    }.    div {.        width: 600px;.        margin: 5em
       auto;.        padding: 50px;.        background-color: #fff;.        borde
      r-radius: 1em;.    }.    a:link, a:visited {.        color: #38488f;.      
        text-decoration: none;.    }.    @media (max-width: 700px) {.        body
       {.            background-color: #fff;.        }.        div {.            
      width: auto;.            margin: 0 auto;.            border-radius: 0;.    
              padding: 1em;.        }.    }.    </style>    .</head>..<body>.<div
      >.    <h1>Example Domain</h1>.    <p>This domain is established to be used 
      for il
    
    $sudo ngrep-d tun0'^(GET | POST | HEAD | HTTP)端口80
    接口:tun0(10.104.1.6/255.255.255.255)
    过滤器:(ip或ip6)和(端口80)
    匹配:^(获取| POST | HEAD | HTTP)
    ####
    T 10.104.1.6:39700->93.184.216.119:80[美联社]
    GET/HTTP/1.1..用户代理:Wget/1.14(linux gnu)…接受:*/*…主机:examp
    连接:保持活动状态。。。。
    ##
    T 93.184.216.119:80->10.104.1.6:39700[A]
    HTTP/1.1 200正常..接受范围:字节..缓存控制:最大年龄=604800..上下文
    nt类型:text/html..日期:2014年10月24日星期五11:21:44 GMT..Etag:“359670651”。
    截止日期:2014年10月31日星期五11:21:44 GMT。最后修改日期:2013年8月9日星期五23
    :54:35 GMT..服务器:ECS(cpm/F9D5)…X缓存:命中..X-ec-custom-error:1..Con
    帐篷长度:1270。。。。。。。多迈示例
    N身体
    {.background color:#f0f2;。边距:0;。填充:0
    字体系列:“开放式Sans”,“Helvetica Neue”,Helvetica,Arial,san
    s-serif;。}。分区宽度:600px;边距:5em
    自动;.padding:50px;。背景色:#fff;.borde
    r半径:1em;}。链接,访问{.color:#38488f;。
    文本装饰:无;}@介质(最大宽度:700px){.body
    {.background color:#fff;}.div{。
    宽度:自动;。边距:0自动;。边框半径:0;。
    填充:1em;}.}。。。。。示例域 已建立此域以供使用
    对于il
    

    我还推荐一个更为晦涩的工具,名为chaosreader,可从中获得。它将把一个tcpdump文件变成一组可浏览的html和其他文件,以一种非常容易访问的形式向您显示所有流量。当你对网络通信的内容比对数据包的分解更感兴趣时,比wireshark容易得多。

    如果你想从其余的C