将特定的 servlet 映射为 Tomcat 中的默认 servlet

2022-09-03 09:31:59

我正在尝试实现一个获取原始请求的servlet,并决定要么处理它们,要么将它们转发到另一个后端服务器。它类似于负载均衡器,其中收到的请求被转发到其中一个(在我的情况下是2)目标。其中一个目标是远程的(在另一台主机上)。此外,请求可以到达根目录(http://mycompany.com/)。

由于我想获取原始请求,因此我实现了自己的servlet(子类化),这效果很好。我的服务包看起来像这样:HttpServlet

public class MyProxyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        processOrForward(req, resp);
    }
    // also doGet(), doHead(), ...
}

由于我要处理的服务可能会将请求发送到根目录,因此我想将我的 servlet 映射为默认的 servlet,从而接收任何没有显式 servlet 映射的请求。假设我的 servlet 的名称是 “myservlet”,并且与另一个 servlet 的 “foo” 一起运行,我希望所有请求都以 http://mycompany.com/foo/ 的形式出现...交付给 foo,以及其他所有内容(例如,/, /bar/..., /myservlet/...) 到 “myservlet”。看看早期的帖子(例如,这里这里的根映射,或这里的url重写),我以为我想通了,但它不起作用。

这是我的网络.xml

<web-app>
  <servlet>
    <servlet-name>ProxyServlet</servlet-name>
    <servlet-class>com.mycompany.MyProxyServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>ProxyServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

在上面的web.xml,对于我尝试过的url模式

"/" and "/*" and empty (i.e., <url-pattern></url-pattern>), all behave the same -->
    Requests to root (/)goes to tomcat's default servlet
    Requests to /myservlet/... are handled by "myservlet"
    Requests to /fubar/... are always 404

有没有办法将我的servlet转换为默认值。也就是说,任何没有专门映射到 servlet 的请求都会来到我的(接收所有请求甚至是可以接受的,因为我可以在自己的容器中部署这个 servlet)。如果这很重要,我在Ubuntu 12.10上使用Tomcat 7.0.30。


答案 1

这应该对你有用。

来自 Java™ Servlet Specification Version 3.1 (JSR 340)

第 12 章。将请求映射到 Servlet

12.2 映射规范

在 Web 应用程序部署描述符中,以下语法用于定义映射:

  • 以字符开头并以后缀结尾的字符串用于路径映射//*

  • 以前缀开头的字符串用作扩展映射*.

  • 空字符串是一种特殊的 URL 模式,它完全映射到应用程序的上下文根,即格式为 的请求。在本例中,路径信息为,servlet 路径和上下文路径为空字符串。("")http://host:port/<contextroot>//("")

  • 仅包含该字符的字符串指示应用程序的“默认”servlet。在这种情况下,servlet 路径是请求 URI 减去上下文路径,路径信息为 null。/

  • 所有其他字符串仅用于完全匹配


另外,请阅读这篇很好的解释,其中包含Head First Servlets & JSP:通过Sun认证Web组件开发人员考试(第2版)一书中的简短示例(引用):

三种类型的元素<url-pattern>

1) 完全匹配

例:
<url-pattern>/Beer/SelectBeer.do</url-pattern>

  • 必须以斜杠 () 开头。/
  • 可以有一个扩展名(如 .do),但不是必需的。

2) 目录匹配

例:
<url-pattern>/Beer/*</url-pattern>

  • 必须以斜杠 () 开头。/
  • 始终以斜杠/星号 () 结尾。/*

3) 扩展匹配

例:
<url-pattern>*.do</url-pattern>

  • 必须以星号 () 开头(切勿以斜杠开头)。*
  • 在星号之后,它必须有一个点扩展名(.do,.jsp等)。


重要说明:
URL模式表示逻辑/虚拟结构,即指定的模式(路径)不需要物理存在


更新

如果你愿意,正如你在评论中所说的那样,

我希望 host:port 命中我的 servlet,而不是默认的 tomcat servlet

然后在这里看到解决方案:
如何使我的Web应用程序成为Tomcat默认应用程序

换句话说,您需要的是一个没有应用程序上下文的路径,这意味着 Tomcat 默认应用程序的应用程序上下文。

引用上面的链接:

在标准的Tomcat安装中,您会注意到在同一目录(CATALINA_BASE)/webapps/下,有一个名为ROOT的目录(大写字母很重要,即使在Windows下也是如此)。这是当前Tomcat默认应用程序的驻留地,当用户调用 http://myhost.company.com[:p ort]时,现在调用该应用程序。诀窍是将您的应用程序放在它的位置上。


答案 2

我不确定我是否理解你想要什么,但可能拦截404是你想做的,然后重定向到你想要的地方。

我来到论坛,因为我对tomcat 7有奇怪的问题,我的正在做你想做的事情;)

这只是我如何拥有root的一种方式,EMPTY

<servlet-mapping>
    <servlet-name>Default</servlet-name>
    <url-pattern></url-pattern>
</servlet-mapping>

这样:任何内容都被重定向到这个servlet,包括图像等,例如,我打开另一个页面,这显示这个页面,根,然后我可以在日志中看到对同一页面的更多请求,3用于css和一个用于图像。

<servlet-mapping>
    <servlet-name>Default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

推荐