Jetty uber jar 上的 GzipHandler
GzipHandler on Jetty uber jar
我用嵌入式码头服务器创建了 uber jar(我更新到 9.4.20.v20190813
)。胖应用包括两部分:静态前端和api后端。从 jetty server 9.1 multiple embeded ports and application in same server instance 复制的代码框架。我想在两个网络应用程序上添加 GzipHandler
。
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
, 一些资源 return Status Code: 206 Partial Content
. 时,服务器抛出异常:
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.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
我的问题:favicon.ico
的mime-type没有包含在GzipHandler中,为什么GzipHandler会处理它? favicon.ico
位于静态资源 Web 应用程序根目录中(与 index.html
相同级别)。
如何正确应用 gziphandler?谢谢!
顺便说一句:gzip 过滤器工作正常
编辑:
- 我将 Jetty 版本从
9.4.12.v20180830
升级到 9.4.20.v20190813
- 我在 GzipHandler 上添加了更多设置
Jetty 9.1 已停产。
https://www.eclipse.org/jetty/documentation/current/what-jetty-version.html
您的代码有效,as-is,只需升级到受支持的 Jetty 版本即可。
我使用 Jetty 9.4.20.v20190813 进行了测试,它按设计运行。
状态代码:206 Partial Content
是一个预期的状态响应代码,当响应包含部分范围数据时,它仅在请求包含Range:
header时产生。
您的代码有一个处理程序树,如下所示 ..
Server.setHandler
\- HandlerCollection
\- WebAppContext ("/a")
\- WebAppContext ("/b")
\- GzipHandler
在末尾添加 GzipHandler
将允许 GzipHandler
应用于不匹配上下文 "/a"
或 "/b"
的请求,这是一个合法的配置,但可能不是您想要的。
既然您提到了 favicon.ico
,那通常是根请求,既不匹配 "/a"
也不匹配 "/b"
,因此我们只能假设这是您想要的。
但是,您实际上并没有说要将 GzipHandler
应用到 WebAppContext
,所以我假设那是您真正想要完成的。
如果是这样,那么我们需要 GzipHandler
在输入 WebAppContext
之前完成所需的操作。
我们想要一个看起来像这样的处理程序树...
Server.setHandler
\- HandlerList
\- GzipHandler
| \- ContextHandlerCollection
| \- WebAppContext ("/a")
| \- WebAppContext ("/b")
\- DefaultHandler
这将是为所有上下文配置的单个 GzipHandler
。
粗略的代码如下所示...
HandlerList handlers = new HandlerList();
server.setHandler(handlers);
WebAppContext appA = new WebAppContext();
appA.setContext("/a");
WebAppContext appB = new WebAppContext();
appB.setContextPath("/b");
ContextHandlerCollection contexts = new ContextHandlerCollection(appA, appB);
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(contexts);
handlers.addHandler(gzipHandler);
handlers.addHandler(new DefaultHandler());
但您也可以为每个 WebApp 设置唯一的 GzipHandler
。
看起来像这样...
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
我用嵌入式码头服务器创建了 uber jar(我更新到 9.4.20.v20190813
)。胖应用包括两部分:静态前端和api后端。从 jetty server 9.1 multiple embeded ports and application in same server instance 复制的代码框架。我想在两个网络应用程序上添加 GzipHandler
。
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
, 一些资源 return 时,服务器抛出异常:Status Code: 206 Partial Content
.
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.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
我的问题:favicon.ico
的mime-type没有包含在GzipHandler中,为什么GzipHandler会处理它? favicon.ico
位于静态资源 Web 应用程序根目录中(与 index.html
相同级别)。
如何正确应用 gziphandler?谢谢!
顺便说一句:gzip 过滤器工作正常
编辑:
- 我将 Jetty 版本从
9.4.12.v20180830
升级到9.4.20.v20190813
- 我在 GzipHandler 上添加了更多设置
Jetty 9.1 已停产。
https://www.eclipse.org/jetty/documentation/current/what-jetty-version.html
您的代码有效,as-is,只需升级到受支持的 Jetty 版本即可。
我使用 Jetty 9.4.20.v20190813 进行了测试,它按设计运行。
状态代码:206 Partial Content
是一个预期的状态响应代码,当响应包含部分范围数据时,它仅在请求包含Range:
header时产生。
您的代码有一个处理程序树,如下所示 ..
Server.setHandler
\- HandlerCollection
\- WebAppContext ("/a")
\- WebAppContext ("/b")
\- GzipHandler
在末尾添加 GzipHandler
将允许 GzipHandler
应用于不匹配上下文 "/a"
或 "/b"
的请求,这是一个合法的配置,但可能不是您想要的。
既然您提到了 favicon.ico
,那通常是根请求,既不匹配 "/a"
也不匹配 "/b"
,因此我们只能假设这是您想要的。
但是,您实际上并没有说要将 GzipHandler
应用到 WebAppContext
,所以我假设那是您真正想要完成的。
如果是这样,那么我们需要 GzipHandler
在输入 WebAppContext
之前完成所需的操作。
我们想要一个看起来像这样的处理程序树...
Server.setHandler
\- HandlerList
\- GzipHandler
| \- ContextHandlerCollection
| \- WebAppContext ("/a")
| \- WebAppContext ("/b")
\- DefaultHandler
这将是为所有上下文配置的单个 GzipHandler
。
粗略的代码如下所示...
HandlerList handlers = new HandlerList();
server.setHandler(handlers);
WebAppContext appA = new WebAppContext();
appA.setContext("/a");
WebAppContext appB = new WebAppContext();
appB.setContextPath("/b");
ContextHandlerCollection contexts = new ContextHandlerCollection(appA, appB);
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(contexts);
handlers.addHandler(gzipHandler);
handlers.addHandler(new DefaultHandler());
但您也可以为每个 WebApp 设置唯一的 GzipHandler
。
看起来像这样...
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