【发布时间】:2018-09-28 14:00:21
【问题描述】:
旨在通过运行 webapp servlet 和代理 servlet 以及其他工具(如部署和控制台日志记录)在本地启动 Jetty。所有 Jetty 配置都在 XML 文件中。
代理 servlet 会将前缀为 /media/* 的 GET 请求反向代理到外部站点 https://example-server/。所以http://localhost:8080/media/image.jpg 将传递给https://media-server/image.jpg。
这是我jetty.xml的摘录:
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="context" class="org.eclipse.jetty.servlet.ServletContextHandler">
<Arg><Get class="org.eclipse.jetty.servlet.ServletContextHandler" name="SESSIONS"/></Arg>
<Call name="setContextPath" arg="/"/>
<Set name="servletHandler">
<New id="handler" class="org.eclipse.jetty.servlet.ServletHandler">
<Call id="holder" name="addServletWithMapping" arg="org.eclipse.jetty.proxy.ProxyServlet$Transparent,/media/*">
<Call name="setInitParameter" arg="proxyTo,https://media-server"/>
<Call name="setInitParameter" arg="prefix,/media"/>
</Call>
</New>
</Set>
</New>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
上面的 XML 应该等同于这个 Java 代码。
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
ServletHandler handler = new ServletHandler();
ServletHolder holder = handler.addServletWithMapping(ProxyServlet$Transparent.class, "/media/*");
holder.setInitParameter("proxyTo", "https://media-server");
holder.setInitParameter("prefix", "/media");
context.setServletHandler(handler);
这是改编自默认的jetty.xml和https://dzone.com/articles/configuring-jetty-servlet-proxy
根据 DZone 指南,我更新了 Jetty 9.x 的类名。所以org.eclipse.jetty.servlets.ProxyServlet 现在是org.eclipse.jetty.proxy.ProxyServlet 并且proxyTo 和prefix 参数必须以小写p 开头。
检查 jetty-proxy-9.4.12.v20180830.jar 是否作为库包含在 Jetty 的启动配置中。
对于日志记录,Jetty 命令行包括 -Dorg.eclipse.jetty.proxy.LEVEL=DEBUG(我建议其他任何人使用此方法来解决 ProxyServlet。)
问题:什么都没有发生。 ProxyServlet 未在 GET 对 `http://localhost:8080/media/image.jpg' 的请求上激活。
这是显示ServletContextHandler 正在启动的日志行。
2018-09-28 15:26:46.045:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1e028a9{"",null,AVAILABLE}
我想有一个简单的解决方案,比如正确设置 ServletContext,但我不知道如何在 XML 中做到这一点,非常感谢一些帮助。 Jetty documentation 在这个很薄。
现在,如果我将jetty.xml 更改为下面的这个,那么代理确实会在GET 向`http://localhost:8080/media/image.jpg'发出请求时激活。
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="handler" class="org.eclipse.jetty.servlet.ServletHandler">
<Call id="holder" name="addServletWithMapping" arg="org.eclipse.jetty.proxy.ProxyServlet$Transparent,/media/*">
<Call name="setInitParameter" arg="proxyTo,https://media-server"/>
<Call name="setInitParameter" arg="prefix,/media"/>
</Call>
</New>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
日志显示 ProxyServlet 像这样激活:
2018-09-28 14:22:14.904:DBUG:oejpP.194a1b5:qtp22374712-13: org.eclipse.jetty.proxy.ProxyServlet$Transparent-194a1b5 @ null/media to https://media-server
2018-09-28 14:22:14.904:DBUG:oejpP.194a1b5:qtp22374712-13: 21964987 rewriting: http://localhost:8080/media/image.jpg -> null
但是这里的代理失败了,因为它有一个null 上下文。所以前缀(source code)设置为null/media是因为ServletContext.getContextPath()为空。由于this source code,这会导致重定向到null。将_prefix 设置为null/media,没有什么能与之匹配。可能这是一个错误,我已经打开了一个问题。
【问题讨论】:
标签: xml configuration reverse-proxy jetty-9