如何将servlet映射到/*,它会因无限循环而失败,并最终导致StackOverflowError [英] How to map servlet to /*, it fails with infinite loop and eventually StackOverflowError

查看:88
本文介绍了如何将servlet映射到/*,它会因无限循环而失败,并最终导致StackOverflowError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的servlet映射到/*,但是由于无限循环而失败.

I would like to map my servlet to /*, but it failed with an infinite loop.

<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,则一切正常.

If I map to /hello, everything works fine.

由于HelloServlet映射到/*,因此也会在RequestDispatcher#forward()上调用它,并导致无限循环.

As the HelloServlet is mapped to /*, it will also be invoked on RequestDispatcher#forward() and cause the infinite loop.

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

How is this caused and how can I solve it?

推荐答案

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

This is not possible. The JSP should actually invoke container's builtin JspServlet. But the /* mapping definied by the webapp has a higher precedence.

您需要将servlet映射到更具体的URL模式(例如/pages/*),并创建一个servlet过滤器,该过滤器将非静态请求转发到该servlet.是的,/*也涵盖了非静态请求(图像/CSS/JS文件),但是servlet完全不应该处理它们.

You need to map the servlet on a more specific URL pattern like /pages/* and create a servlet filter which forwards non-static requests to that servlet. Yes, non-static requests (image/CSS/JS files) are also covered by /*, but they should not be processed by the servlet at all.

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

Assuming that you've all static resources in /resources folder, the following should do:

<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()中具有以下内容:

With the following in filter's 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模式匹配.

This takes place fully transparently without any change to /pages in the URL. The forward to the JSP will not trigger the filter or the servlet. Filters do by default not kick in on forwards and the JSP forward path does not match the controller servlet's URL pattern any more.

或者,如果您有自己的默认servlet实现,则可以将该servlet映射到/,如果该请求不适用于前端控制器请求,则可以将该servlet委托给默认servlet.这就是Spring MVC在幕后所做的.但是,创建默认servlet并不是一件容易的事,因为它应该能够响应条件请求,缓存请求,流请求,恢复请求,目录列表请求等.

Alternatively, if you have your own default servlet implementation, then you could map the servlet to / and let it delegate to the default servlet if the request isn't applicable as a front controller request. This is what Spring MVC is doing under the covers. Creating a default servlet is however not a trivial task as it should be capable of responding to conditional requests, caching requests, streaming requests, resume requests, directory listing requests, etecetera.

  • Difference between / and /* in servlet mapping url pattern
  • How to access static resources when mapping a global front controller servlet on /*
  • Design Patterns web based applications

这篇关于如何将servlet映射到/*,它会因无限循环而失败,并最终导致StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆