首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jetty9.x ProxyServlet -如何在XML中正确设置ServletContext

Jetty9.x ProxyServlet -如何在XML中正确设置ServletContext
EN

Stack Overflow用户
提问于 2018-09-28 14:00:21
回答 2查看 6.6K关注 0票数 1

目标是在本地启动Jetty,同时运行webapp servlet和代理servlet,以及部署和控制台日志之类的其他工具。所有Jetty配置都在XML文件中。

代理servlet将将代理GET请求前缀为/media/*反转到外部站点https://example-server/。所以http://localhost:8080/media/image.jpg会传递给https://media-server/image.jpg

这是我的jetty.xml的摘录

代码语言:javascript
复制
<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代码。

代码语言:javascript
复制
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.xmlhttps://dzone.com/articles/configuring-jetty-servlet-proxy中改编的。

在DZone指南中,我更新了Jetty9.x的类名。因此,org.eclipse.jetty.servlets.ProxyServlet现在是org.eclipse.jetty.proxy.ProxyServletproxyToprefix参数必须从小写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正在启动的日志行。

代码语言:javascript
复制
2018-09-28 15:26:46.045:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1e028a9{"",null,AVAILABLE}

我想这有一个简单的解决方案,比如正确设置ServletContext,但是我不知道如何用XML实现这一点,并且非常希望得到一些帮助。这上面的文档码头很薄。

现在,如果我将jetty.xml更改为下面的内容,那么代理将对GET请求执行激活为“http://localhost:8080/media/image.jpg”。

代码语言:javascript
复制
<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:

代码语言:javascript
复制
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上下文。因此,前缀已被设置(源代码)为null/media,因为ServletContext.getContextPath()为null。这会导致重定向到null,因为这个源代码。随着_prefix设置为null/media,没有什么能与之相媲美。可能是个窃听器,我打开了一个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-01 19:15:57

下面是一个从ProxyServlet目录中使用${jetty.base}的示例。

代码语言:javascript
复制
$ mkdir proxy-example-base
$ cd proxy-example-base/
$ java -jar ../../jetty-home-9.4.12.v20180830/start.jar --add-to-start=http,deploy,proxy
INFO  : webapp          transitively enabled, ini template available with --add-to-start=webapp
INFO  : server          transitively enabled, ini template available with --add-to-start=server
INFO  : proxy           initialized in ${jetty.base}/start.ini
INFO  : security        transitively enabled
INFO  : servlet         transitively enabled
INFO  : http            initialized in ${jetty.base}/start.ini
INFO  : client          transitively enabled
INFO  : threadpool      transitively enabled, ini template available with --add-to-start=threadpool
INFO  : deploy          initialized in ${jetty.base}/start.ini
MKDIR : ${jetty.base}/webapps
INFO  : Base directory was modified
$ ls -la
total 8
drwxr-xr-x   4 joakim  staff   136 Oct  1 14:10 ./
drwxr-xr-x  17 joakim  staff   578 Oct  1 14:10 ../
-rw-r--r--   1 joakim  staff  2146 Oct  1 14:10 start.ini
drwxr-xr-x   3 joakim  staff   102 Oct  1 14:11 webapps/
$ cp ~/Downloads/media-proxy.xml webapps/
$ cat webapps/media-proxy.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
  <Set name="contextPath">/</Set>
  <Call name="addServlet">
    <Arg>org.eclipse.jetty.proxy.ProxyServlet$Transparent.class</Arg>
    <Arg>/media/*</Arg>
    <Set name="InitOrder">1</Set>
    <Call name="setInitParameter">
      <Arg>proxyTo</Arg>
      <Arg>https://media-server/</Arg>
    </Call>
    <Call name="setInitParameter">
      <Arg>prefix</Arg>
      <Arg>/media</Arg>
    </Call>
  </Call>
</Configure>

其工作方式是将${jetty.base}配置为启用proxy jetty模块,该模块将代理类放在服务器类路径上。

然后启用deploy jetty模块,在${jetty.base}/webapps/目录中查找并部署webapps的配置。

最后,XML可部署设置为在/ contextPath上有一个contextPath,还有一个定义的servlet,即带有一些init参数的ProxyServlet$Transparent

票数 2
EN

Stack Overflow用户

发布于 2018-09-29 00:32:32

一个解决方案--这不是我想要做的,但它是有效的--是从与webapp相关的ProxyServlet启动的。

代码语言:javascript
复制
<servlet>
  <servlet-name>JettyProxy</servlet-name>
  <servlet-class>org.eclipse.jetty.proxy.ProxyServlet$Transparent</servlet-class>
  <init-param>
    <param-name>proxyTo</param-name>
    <param-value>https://media-server</param-value>
  </init-param>
  <init-param>
    <param-name>prefix</param-name>
    <param-value>/media</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
  <servlet-name>JettyProxy</servlet-name>
  <url-pattern>/media/*</url-pattern>
</servlet-mapping>

附加问题:

  • web.xml中定义的任何过滤器现在也需要<async-supported>true</async-supported>
  • 您的项目现在需要将jetty-proxy库jar作为依赖项(版本必须与Jetty匹配),如下所示: org.eclipse.jetty jetty-proxy 9.4.12.v20180830

web.xml中这样做和通过Jetty自己的配置(我想在OP中这样做)有一些不同。

  1. 代理URL现在必须采用以下形式( webapp是webapp名称):http://localhost:8080/webapp/media/image.jpg
  2. 当Jetty更改时,webapp必须更新web.xml --这可能是远程托管应用程序的一个问题
  3. 每个webapp应用程序都必须包括这一点,而不是“内置”到Jetty
  4. 与Jetty能够为不同路径设置不同的servlet相比,这感觉很不优雅--这里是否有性能问题,因为代理URL现在也被webapp的过滤器解析了?
  5. 代理请求周期完成时可能阻塞the应用程序的线程(需要测试.)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52557018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档