为什么Jetty 9.x中的ServletTester如此之慢?

时间:2013-12-06 16:04:17

标签: java jetty embedded-jetty jetty-9

Jetty的ServletTester对于测试Servlet应用程序非常有用。我之前使用过Jetty 6的ServletTester,它运行得很好。

例如:

Jetty 6.x

的pom.xml

<dependency>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-servlet-tester</artifactId>
  <version>6.1.26</version>
  <scope>test</scope>
</dependency>

SampleServletTest.java

package example;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.mortbay.jetty.testing.HttpTester;
import org.mortbay.jetty.testing.ServletTester;

public class SampleServletTest {

    @Test
    public void testDoGet() throws Exception {
        ServletTester tester = new ServletTester();
        tester.addServlet(SampleServlet.class, "/index");
        tester.start();

        HttpTester request = new HttpTester();
        request.setMethod("GET");
        request.setHeader("Host", "tester"); // should be "tester"
        request.setURI("/index");
        request.setVersion("HTTP/1.1");
        request.setContent("");

        String responses = tester.getResponses(request.generate());
        HttpTester response = new HttpTester();
        response.parse(responses);

        assertThat(response.getStatus(), is(equalTo(200)));
    }
}

Jetty 9.x

ServtyTester的API在Jetty 9.x中得到了很大改进。

的pom.xml

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlet</artifactId>
    <version>9.0.7.v20131107</version>
    <scope>test</scope>
</dependency>

SampleServletTest.java

package example;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.servlet.ServletTester;

public class SampleServletTest {

    @Test
    public void testDoGet() throws Exception {
        ServletTester tester = new ServletTester();
        tester.addServlet(SampleServlet.class, "/index");
        tester.start();

        HttpTester.Request request = HttpTester.newRequest();
        request.setMethod("GET");
        request.setHeader("Host", "tester"); // should be "tester"
        request.setURI("/index");
        request.setVersion("HTTP/1.1");
        request.setContent("");

        HttpTester.Response response = HttpTester.parseResponse(tester.getResponses(request.generate()));

        assertThat(response.getStatus(), is(equalTo(200)));
    }
}

新API看起来非常酷,但遗憾的是上面的代码运行得很慢......这段代码每次运行需要10秒钟。你能相信吗?

有没有人知道这个问题?如果这只是我的错误,这是一个非常好的消息。

1 个答案:

答案 0 :(得分:6)

这是您拥有的请求配置的正常行为。

它与HTTP持久连接有关。

Jetty 6的servlet测试程序默认为HTTP / 1.0行为。

HTTP / 1.0没有针对持久连接的官方规范,但是多年来客户端已经发展为采用非持久行为,可以使用协商的Connection标头覆盖。

使用HTTP / 1.0,其1个请求,然后1个响应,然后关闭连接。除非客户端发送Connection: Keep-Alive标头(并且服务器响应相同的标头)

Jetty 9的HttpTester also defaults to HTTP/1.0

您在示例中指定了request.setVersion("HTTP/1.1");,其中所有连接都被视为持久连接,除非另有声明。因此,添加Connection: close将强制服务器在发送响应后关闭连接,而不是等待另一个请求。

所以你有两个选择:

  1. 坚持使用HTTP / 1.1并添加request.setHeader("Connection", "close");
  2. 或将您的HTTP版本降级为1.0。使用:
    • request.setVersion("HTTP/1.0");
    • 或注释掉request.setVersion();的来电并依赖默认行为。