在的StackOverflowError servlet映射与URL模式“/ *”(StackOve

2019-07-29 05:19发布

我有一组JSP页面的,我想隐藏.jsp扩展名(一些研究之后,似乎这是很好的搜索引擎优化)。

我碰到的一个解决方案是以下几点:

<servlet>
    <servlet-name>mypage</servlet-name>
    <jsp-file>/some-page.jsp</jsp-file>
</servlet>
<servlet-mapping>
    <servlet-name>mypage</servlet-name>
    <url-pattern>/some-page</url-pattern>
</servlet-mapping>

虽然这工作,我相信我有建立这个映射在我的网站上的每个JSP页面。

我碰到这里发布另一种解决方案来(轻松友好的URL): JSP / Servlet的的隐藏功能

......它使用一个简单的servlet转发请求。 在我的web.xml我有以下并能正常工作:

<servlet>
    <servlet-name>MyServletName</servlet-name>
    <servlet-class>myservlets.PrettyUrlServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyServletName</servlet-name>
    <url-pattern>/myservlet/*</url-pattern>
</servlet-mapping>

现在的问题是,我不想打的网址:www.mydomain.com/myservlet/some-page

我想使用的网址:www.mydomain.com/some-page

所以我改变了的url-pattern为“/ *”

<servlet>
    <servlet-name>MyServletName</servlet-name>
    <servlet-class>myservlets.PrettyUrlServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyServletName</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

但是,这会导致一个无限循环:

    Exception in thread "http-bio-8080-exec-1" java.lang.StackOverflowError
            at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:219)
            at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228)
            .
            .
            at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228)
            at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:228)
            at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
            at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
            at myservlets.PrettyUrlServlet.doGet(PrettyUrlServlet.java:22)

这我不知道如何解决。 有任何想法吗?

Answer 1:

这是映射到一个servlet /*也将上运行RequestDispatcher#forward()调用。 因此,如果你在这个servlet执行向前,它会调用每次自己在一个无限循环。 这解释了StackOverflowError

毕竟,你不应该使用/*对servlet的。 这不仅使在Servlet过滤器的感觉。 把servlet映射回一个更具体的URL模式,并创建在过滤器/*其在必要时转发到所需的servlet。 你当然不希望有servlet来处理,例如图像/ CSS / JS文件。 假设他们都放在/resources文件夹和您的前端控制器被映射/myservlet/* ,然后执行以下任务中doFilter()

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

if (path.startsWith("/resources/")) {
    // Just let container's default servlet do its job.
    chain.doFilter(request, response);
}
else {
    // Delegate to your front controller.
    request.getRequestDispatcher("/myservlet" + path).forward(request, response);
}

也可以看看:

  • URL映射在Tomcat来FrontController servlet提供


Answer 2:

您应该使用UrlRewriteFilter

你可以使用一些像这样在您的配置文件(urlrewrite.xml):

<rule>
    <from>/products/([a-zA-Z0-9._%]+)</from>
    <to>/products.jsp?id=$1</to>
</rule>

UrlRewriteFilter是在一个评论,但我认为它应该是一个独立的答案。



文章来源: StackOverflowError in servlet mapping with url-pattern “/*”