我想将我的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()
上调用并导致无限循环。
这是如何引起的?如何解决?
答案 0 :(得分:4)
这是不可能的。 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并不是一项简单的任务,因为它应该能够响应条件请求,缓存请求,流请求,恢复请求,目录列表请求,等等。
答案 1 :(得分:-1)
这可能与Servlet Filter going in infinite loop when FORWARD used in mapping in JSF
重复否则应检查JSP包含的内容,可能是它对css或图像文件的请求可能导致此行为。也建议在没有通配符的情况下尝试。