旨在使用运行中的webapp servlet和代理servlet以及其他工具(如部署和控制台日志记录)在本地启动Jetty。所有Jetty配置都在XML文件中。
代理Servlet将GET
前缀为/media/*
的请求反向代理到外部站点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
的{{1}}对“ http://localhost:8080/media/image.jpg”的请求未激活。
这是显示GET
开始的日志行。
ServletContextHandler
我猜想有一个简单的解决方案,例如正确设置ServletContext,但是我不知道如何在XML中做到这一点,并且非常感谢您的帮助。码头documentation稀薄。
2018-09-28 15:26:46.045:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1e028a9{"",null,AVAILABLE}
现在,如果我将
更改为以下内容,则代理会对<http://localhost:8080/media/image.jpg的
jetty.xml
请求进行 激活。
GET
日志显示ProxyServlet的激活方式如下:
<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>
但是这里代理失败,因为它具有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
上下文。因此将前缀(source code)设置为null
是因为null/media
为空。由于this source code,这将导致重定向到ServletContext.getContextPath()
。将null
设置为_prefix
时,没有任何匹配的结果。可能是个错误,我已经开了一个问题。
答案 0 :(得分:2)
这是在#include <stdio.h>
#include <stdlib.h>
/* append a character to a string, assuming s points to an array with enough space */
void append(char *s, char c) {
size_t len = strlen(s);
s[len] = c;
s[len + 1] = '\0';
}
int main(void) {
int c;
char *s;
size_t i = 1;
s = malloc(i * sizeof(char));
if (s == NULL) {
printf("memory allocation failure\n");
return 1;
}
*s = '\0';
while ((c = getchar()) != EOF && c != '\n') {
i++;
s = realloc(s, i * sizeof(char));
if (s == NULL) {
printf("memory allocation failure\n");
return 1;
}
append(s, c);
}
printf("%s\n", s);
free(s);
return 0;
}
目录中使用ProxyServlet
的示例。
${jetty.base}
工作方式是将$ 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
码头模块以在deploy
目录中查找webapp的配置并进行部署。
最后,将XML可部署程序设置为在${jetty.base}/webapps/
contextPath处有一个javax.servlet.ServletContext
和一个已定义的servlet /
,并带有一些初始参数。
答案 1 :(得分:1)
一种解决方法-并非完全是我想做的,但它确实有效-是从与Web应用程序关联的web.xml
启动ProxyServlet。
<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版本匹配),如下所示:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-proxy</artifactId>
<version>9.4.12.v20180830</version>
</dependency>
从web.xml
进行此操作与我在OP中希望通过Jetty自己的配置进行操作之间有一些区别。
web.xml
-对于远程托管的应用程序可能是个问题