Java Jetty在RequestHandler引发异常时重试请求

Java Jetty在RequestHandler引发异常时重试请求,java,servlets,jetty,embedded-jetty,Java,Servlets,Jetty,Embedded Jetty,我注意到每当handle抛出异常时,Jetty都在重试对指定的处理程序的调用 这是不受欢迎的行为,但我似乎找不到阻止它的配置设置 我已经使用Jetty一段时间了,但最近升级了我的环境,使用9.4.9.v20180320。这可能是也可能不是新的行为,但我从未注意到 下面是一个简单的用例来说明我的问题。请注意,输出中有两行指示正文内容,但令人困惑的是,在第二次尝试时,正文是空的 public class JettyTest extends AbstractHandler { @Overrid

我注意到每当
handle
抛出异常时,
Jetty
都在重试对指定的
处理程序的调用

这是不受欢迎的行为,但我似乎找不到阻止它的配置设置

我已经使用Jetty一段时间了,但最近升级了我的环境,使用
9.4.9.v20180320
。这可能是也可能不是新的行为,但我从未注意到

下面是一个简单的用例来说明我的问题。请注意,输出中有两行指示正文内容,但令人困惑的是,在第二次尝试时,正文是空的

public class JettyTest extends AbstractHandler
{
    @Override
    public void handle(String arg0, Request arg1, HttpServletRequest arg2, HttpServletResponse arg3)
    throws IOException
    {
        //read request body into string
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //apache commons copy
        IOUtils.copy(arg1.getInputStream(), bos);
        String body = new String(bos.toByteArray());
        System.out.println("request body: " + body);
        throw new NullPointerException();
    }

    public static void main(String args[])
    throws Exception
    {
        Server server = new Server();
        server.setHandler(new JettyTest());
        LocalConnector localConnector = new LocalConnector(server);
        server.addConnector(localConnector);
        server.start();
        String simpleRequest = "GET / http/1.1\r\nHost: localhost:0\r\nContent-Type: text/plain\r\nContent-Length: 2\r\n\r\nhi";
        String response = localConnector.getResponse(simpleRequest);
        server.join();
    }

}
输出

2018-03-26 19:47:49.590:INFO:oejs.Server:main: Started @327ms

request body: hi

2018-03-26 19:47:49.660:WARN:oejs.HttpChannel:qtp1349277854-12: /
java.lang.NullPointerException
    at test.JettyTest.handle(JettyTest.java:28)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:531)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
    at org.eclipse.jetty.io.ByteArrayEndPoint$1.run(ByteArrayEndPoint.java:78)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)
    at java.lang.Thread.run(Thread.java:748)

request body: 

你有很多事情要做

  • 您没有处理请求的任何内容(代码库中没有任何内容正在使用
    request.setHandled(true)
  • 您没有错误调度处理
  • 您没有ErrorHandler设置
  • 所以发生的是

  • 调用JettyTest.handle()时,会出现异常
  • 请求现在处于错误分派模式
  • 错误分派请求现在再次发送到处理程序中进行错误处理
  • 如果你只是改变一下

    package jetty.errors;
    导入java.io.ByteArrayOutputStream;
    导入java.io.IOException;
    导入javax.servlet.DispatcherType;
    导入javax.servlet.http.HttpServletRequest;
    导入javax.servlet.http.HttpServletResponse;
    导入org.eclipse.jetty.server.LocalConnector;
    导入org.eclipse.jetty.server.Request;
    导入org.eclipse.jetty.server.server;
    导入org.eclipse.jetty.server.handler.AbstractHandler;
    导入org.eclipse.jetty.util.IO;
    公共类handlerRor扩展了AbstractHandler
    {
    @凌驾
    公共无效句柄(字符串s、请求请求、HttpServletRequest、HttpServletRequest、HttpServletResponse、HttpServletResponse)引发IOException
    {
    if(DispatcherType.REQUEST.equals(httpServletRequest.getDispatcherType())
    {
    //将请求正文读入字符串
    ByteArrayOutputStream bos=新建ByteArrayOutputStream();
    //apachecommons副本
    复制(httpServletRequest.getInputStream(),bos);
    字符串体=新字符串(bos.toByteArray());
    System.out.println(“请求主体:+body”);
    抛出新的NullPointerException();
    }
    其他的
    {
    System.out.println(“现在处于DispatchType:+httpServletRequest.getDispatcherType());
    }
    }
    公共静态void main(字符串参数[])
    抛出异常
    {
    服务器=新服务器();
    setHandler(新HandlerWithError());
    LocalConnector LocalConnector=新的LocalConnector(服务器);
    addConnector(localConnector);
    server.start();
    字符串simpleRequest=“GET/http/1.1\r\n”+
    “主机:本地主机:0\r\n”+
    “连接:关闭\r\n”+
    “内容类型:文本/普通\r\n”+
    “内容长度:2\r\n\r\nhi”;
    String response=localConnector.getResponse(simpleRequest);
    join();
    }
    }
    
    你会得到结果的

    2018-03-27 06:47:40.074:INFO::main:Logging在429ms时初始化为org.eclipse.jetty.util.log.StdErrLog
    2018-03-27 06:47:40.148:信息:oejs.服务器:main:jetty-9.4.9.v20180320;建成时间:2018-03-20T07:21:10-05:00;git:1F8159B1E4A42D3F7997021EA1609F2FBAC6DE5;jvm 9.0.4+11
    2018-03-27 06:47:40.182:信息:oejs.AbstractConnector:main:已启动LocalConnector@2f490758{HTTP/1.1[HTTP/1.1]}
    2018-03-27 06:47:40.183:信息:oejs.Server:main:Started@548ms
    2018-03-27 06:47:40.287:警告:oejs.HttpChannel:qtp2104545713-16:/
    java.lang.NullPointerException
    HandlerWithError.handler(HandlerWithError.java:29)
    位于org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    位于org.eclipse.jetty.server.server.handle(server.java:531)
    位于org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
    位于org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    位于org.eclipse.jetty.io.AbstractConnection$ReadCallback.successed(AbstractConnection.java:281)
    位于org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
    位于org.eclipse.jetty.io.ByteArrayEndPoint$1.run(ByteArrayEndPoint.java:78)
    位于org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)
    位于org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)
    位于java.base/java.lang.Thread.run(Thread.java:844)
    请求主体:您好
    现在在DispatchType中:错误
    
    了解所有这些,您可以通过以下方式更改实现以利用此错误分派

    package jetty.errors;
    导入java.io.ByteArrayOutputStream;
    导入java.io.IOException;
    导入javax.servlet.DispatcherType;
    导入javax.servlet.http.HttpServletRequest;
    导入javax.servlet.http.HttpServletResponse;
    导入org.eclipse.jetty.http.HttpTester;
    导入org.eclipse.jetty.server.LocalConnector;
    导入org.eclipse.jetty.server.Request;
    导入org.eclipse.jetty.server.server;
    导入org.eclipse.jetty.server.handler.AbstractHandler;
    导入org.eclipse.jetty.server.handler.DefaultHandler;
    导入org.eclipse.jetty.server.handler.HandlerList;
    导入org.eclipse.jetty.util.IO;
    公共类HandlerRor
    {
    公共静态类MyRequestHandler扩展了AbstractHandler
    {
    @凌驾
    公共无效句柄(字符串目标、请求baseRequest、HttpServletRequest请求、HttpServletResponse响应)引发IOException
    {
    System.out.println(“MyRequestHandler.handle()-DispatcherType:+request.getDispatcherType());
    //仅适用于请求分派
    如果(!DispatcherType.REQUEST.equals(REQUEST.getDispatcherType()))
    {
    //跳过此处理程序
    返回;
    }
    //(用这只手)处理