1

响应期间使用的输出缓冲行为和块数会根据响应是来自普通 servlet 还是来自 Jersey 容器 servlet 的资源而变化。

我正在使用一个虚拟 servlet 和一个虚拟 Jersey 资源进行测试。两者都打印了 256 个字符的倍数(255 个“a”和 1 个“\n”,这些并不重要,只是随机选择)。

Jetty 有一个 32kB 的默认输出缓冲区,当输出内容超过该大小并且没有明确设置 Content-Length 时,Jetty 将使用分块传输编码。

但是,当从 Jersey 资源进行相同的测试时,无论输出大小如何,Jetty 总是使用分块传输编码,并且块被拆分为 16kB 而不是 32kB。

我浏览了两者的来源,但找不到原因。如果有人能分享他们对此的见解,我真的很高兴。

Servlet 测试代码

public class Test extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private String baseString;

    public Test() {
        super();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 255 ; i++)
            sb.append("a");
        sb.append("\n");
        baseString = sb.toString();
     }

     private void writeOutput(int count, PrintWriter writer) {
        for (int i = 0; i<count; i++) {
            writer.print(baseString);
        }
     }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        writeOutput(Integer.parseInt(request.getParameter("count")),response.getWriter());
     }

}

泽西资源测试代码

@Path("/")
public class JerseyTest {

private String baseString;

public JerseyTest() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 255 ; i++)
        sb.append("a");
    sb.append("\n");
    baseString = sb.toString();
}

@GET
@Produces("text/html;charset=UTF-8")
public String get(@Context HttpServletResponse response,@QueryParam("count")int count) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i<count; i++) {
        sb.append(baseString);
    }
    return sb.toString();
}   
}

设置

  • 嵌入式泽西岛 8.1.7.v20120910
  • Jersey 1.14(使用 Jersey Servlet 容器)

count=1 的响应(即输出大小 256 字节)

  • Servlet:内容长度集
  • Jersey:未设置 Content-Length,使用分块编码,1 个块

count=128 的响应(即输出大小 32kB)

  • Servlet:未设置 Content-Length,使用分块编码,1 个块
  • Jersey:未设置 Content-Length,使用分块编码,2 个块(拆分为 16kB)

count=256 的响应(即输出大小 64kB)

  • Servlet:未设置 Content-Length,使用分块编码,2 个块
  • Jersey:未设置 Content-Length,使用分块编码,4 个块

有人对这种差异的原因有任何想法吗?

更新 1: Jersey 设置了 8kB 的内部缓冲区大小,但这仍然不能解释我看到的 16kB 行为。如果 Jersey 每 8kB 刷新,那么我应该看到 8kB 块而不是 16kB(这种行为存在于普通 servlet 案例中)

4

0 回答 0