3

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

例如:

码头 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)));
    }
}

码头 9.x

ServletTester 的 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 秒。你相信吗?

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

4

1 回答 1

6

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

它与 HTTP 持久连接有关。

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

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

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

Jetty 9 的HttpTester 也默认为 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();并依赖默认行为。
于 2013-12-06T17:23:07.200 回答