3

我想将我的 servlet 映射到/*,但它因无限循环而失败。

<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>my.HelloServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

java代码是:

public class HelloServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response){
        request.getRequestDispatcher("/WEB-INF/jsps/hello.jsp").forward(request, response);
    }

}

如果我映射到/hello,一切正常。

HelloServlet映射到 时/*,它也将被调用RequestDispatcher#forward()并导致无限循环。

这是如何引起的,我该如何解决?

4

2 回答 2

5

这是不可能的。JSP 实际上应该调用容器的内置函数JspServlet。但是/*由 webapp 定义的映射具有更高的优先级。

您需要将 servlet 映射到更具体的 URL 模式/pages/*,例如创建一个 servlet 过滤器,将非静态请求转发到该 servlet。是的,非静态请求(图像/CSS/JS 文件)也包含在 中/*,但它们根本不应该由 servlet 处理。

假设您在/resources文件夹中拥有所有静态资源,则应执行以下操作:

<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.example.Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>controller</servlet-name>
    <servlet-class>com.example.Controller</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>controller</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>

在过滤器中使用以下内容doFilter()

HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/resources")) {
    chain.doFilter(request, response); // Goes to container's own default servlet.
} else {
    request.getRequestDispatcher("/pages" + uri).forward(request, response); // Goes to controller servlet.
}

这完全透明地发生,无需对 URL 进行任何更改/pages。转发到 JSP 不会触发过滤器或 servlet。默认情况下,过滤器不会启动转发,并且 JSP 转发路径不再匹配控制器 servlet 的 URL 模式。

或者,如果您有自己的默认 servlet 实现,那么您可以将 servlet 映射到/并让它委托给默认 servlet,如果该请求不适用于前端控制器请求。这就是 Spring MVC 在幕后所做的。然而,创建一个默认 servlet 并不是一项简单的任务,因为它应该能够响应条件请求、缓存请求、流请求、恢复请求、目录列表请求等等。

也可以看看:

于 2012-12-18T14:29:56.127 回答
-1

当在 JSF 中的映射中使用 FORWARD 时,这可能与进入无限循环的 Servlet 过滤器重复

否则应该检查您的 JSP 包含的内容,可能是它请求可能导致此行为的 css 或图像文件。也建议尝试不使用通配符。

于 2012-12-18T14:25:10.167 回答