Jetty 码头上的GzipHandler uber jar

Jetty 码头上的GzipHandler uber jar,jetty,embedded-jetty,Jetty,Embedded Jetty,我用嵌入式jetty服务器创建了uber jar(我更新为9.4.20.v20190813)。fat应用程序包括两部分:静态前端和api后端。从复制的代码框架。我想在两个web应用程序上都添加gziphondler public class Main { public static void main(String[] args) { Server server = new Server(); ServerConnector connectorA

我用嵌入式jetty服务器创建了uber jar(我更新为
9.4.20.v20190813
)。fat应用程序包括两部分:静态前端和api后端。从复制的代码框架。我想在两个web应用程序上都添加
gziphondler

public class Main
{
    public static void main(String[] args)
    {
        Server server = new Server();

        ServerConnector connectorA = new ServerConnector(server);
        connectorA.setPort(8080);
        connectorA.setName("connA"); // connector name A (static web app)
        ServerConnector connectorB = new ServerConnector(server);
        connectorB.setPort(9090);
        connectorB.setName("connB"); // connector name B (api app)

        server.addConnector(connectorA);
        server.addConnector(connectorB);

        // Basic handler collection
        HandlerCollection contexts = new HandlerCollection();
        server.setHandler(contexts);

        // WebApp A
        WebAppContext appA = new WebAppContext();
        appA.setContextPath("/a");
        appA.setWar("./webapps/webapp-a.war");
        appA.setVirtualHosts(new String[]{"@connA"}); // connector name A
        contexts.addHandler(appA);

        // WebApp B
        WebAppContext appB = new WebAppContext();
        appB.setContextPath("/b");
        appB.setWar("./webapps/webapp-b.war");
        appB.setVirtualHosts(new String[]{"@connB"}); // connector name B
        contexts.addHandler(appB);

    GzipHandler gzipHandler = new GzipHandler();
    gzipHandler.setIncludedMethods("POST", "GET");
    gzipHandler.setIncludedMimeTypes("text/html", "text/plain", "text/xml", "text/css", "application/javascript",
                                     "text/javascript", "application/json");
    gzipHandler.setInflateBufferSize(2048);
    gzipHandler.setMinGzipSize(2048);

        contexts.addHandler(gzipHandler);

        try
        {
            server.start(); // start server thread
            server.join(); // wait for server thread to end
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }
}
当我访问
http://localhost:8080
,一些资源返回
状态代码:206部分内容
,服务器引发异常:

17:16:31.447 [qtp60830820-16] WARN  org.eclipse.jetty.server.HttpChannel - /favicon.ico
java.lang.NullPointerException: null
    at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:725)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:502)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
我的问题是:
favicon.ico
的mime类型不包含在GziHandler中,为什么GziHandler会处理它?而
favicon.ico
位于静态资源web应用程序根目录中(与
index.html
的级别相同)

如何正确应用gziphandler?谢谢

顺便说一句:gzip过滤器工作正常

编辑:

  • 我将jetty版本从
    9.4.12.v20180830
    升级到
    9.4.20.v20190813
  • 我在GzipHandler上添加了更多设置
  • 码头9.1为EOL(寿命终止)

    您的代码可以正常工作,只需升级到受支持的Jetty版本即可

    我使用Jetty 9.4.20.v20190813进行了测试,测试结果与设计相符

    当响应包括部分范围数据时,状态代码:206部分内容是预期的状态响应代码,仅当请求包括范围:标头时才会生成该代码

    您的代码有一个如下所示的处理程序树

    Server.setHandler
     \- HandlerCollection
         \- WebAppContext ("/a")
         \- WebAppContext ("/b")
         \- GzipHandler
    
    gziHandler
    放在末尾将允许
    gziHandler
    应用于与上下文
    “/a”
    “/b”
    不匹配的请求,这是一种合法的配置,但可能不是您想要的

    既然您提到了favicon.ico,那通常是一个根请求,它既不匹配
    “/a”
    ,也不匹配
    “/b”
    ,所以我们只能假设这是您想要的

    但是,您实际上并没有说您希望将
    gziphondler
    应用于
    WebAppContext
    ,所以我假设这是您真正想要实现的

    如果是这种情况,那么我们需要
    gziphondler
    在输入
    WebAppContext
    之前执行它所需要的操作

    我们需要一个如下所示的处理程序树

    Server.setHandler
     \- HandlerList
         \- GzipHandler
         |   \- ContextHandlerCollection
         |       \- WebAppContext ("/a")
         |       \- WebAppContext ("/b")
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- ContextHandlerCollection
         |   \- WebAppContext ("/a")
         |       \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/b")
         |       \- GzipHandler (instance / config B)
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/a")
         \- GzipHandler (instance / config B)
         |   \- WebAppContext ("/b")
         \- DefaultHandler
    
    这将是为所有上下文配置的单个
    gziphondler

    粗略的代码如下所示

    Server.setHandler
     \- HandlerList
         \- GzipHandler
         |   \- ContextHandlerCollection
         |       \- WebAppContext ("/a")
         |       \- WebAppContext ("/b")
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- ContextHandlerCollection
         |   \- WebAppContext ("/a")
         |       \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/b")
         |       \- GzipHandler (instance / config B)
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/a")
         \- GzipHandler (instance / config B)
         |   \- WebAppContext ("/b")
         \- DefaultHandler
    
    handlerlisthandlers=newhandlerlist();
    setHandler(处理程序);
    WebAppContext appA=新的WebAppContext();
    appA.setContext(“/a”);
    WebAppContext appB=新的WebAppContext();
    appB.setContextPath(“/b”);
    ContextHandlerCollection contexts=新的ContextHandlerCollection(appA、appB);
    gzip handler gzip handler=新的gzip handler();
    setHandler(上下文);
    addHandler(gziHandler);
    addHandler(新的DefaultHandler());
    
    但是,您也可以为每个Web应用程序提供一个独特的
    gziphondler

    看起来像这样

    Server.setHandler
     \- HandlerList
         \- GzipHandler
         |   \- ContextHandlerCollection
         |       \- WebAppContext ("/a")
         |       \- WebAppContext ("/b")
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- ContextHandlerCollection
         |   \- WebAppContext ("/a")
         |       \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/b")
         |       \- GzipHandler (instance / config B)
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/a")
         \- GzipHandler (instance / config B)
         |   \- WebAppContext ("/b")
         \- DefaultHandler
    
    或者像这样

    Server.setHandler
     \- HandlerList
         \- GzipHandler
         |   \- ContextHandlerCollection
         |       \- WebAppContext ("/a")
         |       \- WebAppContext ("/b")
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- ContextHandlerCollection
         |   \- WebAppContext ("/a")
         |       \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/b")
         |       \- GzipHandler (instance / config B)
         \- DefaultHandler
    
    Server.setHandler
     \- HandlerList
         \- GzipHandler (instance / config A)
         |   \- WebAppContext ("/a")
         \- GzipHandler (instance / config B)
         |   \- WebAppContext ("/b")
         \- DefaultHandler
    

    我升级码头的问题,请帮我看看,感谢您的时间和感谢!谢谢@Joakim Erdfelt。它工作得很好!你让我知道码头有多强大!