tomcat - 带有 url 模式 "/*"的 servlet 映射中的 StackOverflowError

标签 tomcat servlets seo servlet-filters

我有一组 JSP 页面,我想隐藏 .jsp 扩展名(经过一些研究后,它似乎对 SEO 有好处)。

我遇到的一个解决方案如下:

<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):Hidden features of 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>

现在的问题是我不想访问 URL:www.mydomain.com/myservlet/some-page

我想使用 URL: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)

我不确定如何修复。有什么想法吗?

最佳答案

映射到 /* 上的 servlet 也将在 RequestDispatcher#forward() 调用上运行。因此,如果您在该 servlet 中执行转发,它会在无限循环中每次调用自己。这解释了 StackOverflowError

毕竟,您根本不应该对 servlet 使用 /*。它只对 servlet 过滤器有意义。将 servlet 映射放回到更具体的 URL 模式上,并在 /* 上创建过滤器,必要时转发到所需的 servlet。您当然不希望 servlet 处理例如图像/CSS/JS 文件。假设它们都放在 /resources 文件夹中,并且您的前端 Controller 映射到 /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);
}

另见:

关于tomcat - 带有 url 模式 "/*"的 servlet 映射中的 StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10402288/

相关文章:

java - doPost 是否加密 URL 及其外部附加参数

seo - 如何在面包屑中插入主页和当前页面?

java - 通过 AJP 的 Tomcat 7 Websockects 不工作。有什么建议么?

tomcat - 无法在 Tomcat 上进行远程访问

html - 从同一 servlet 中的文本字段上传图像和信息

java - 处理 HTTP 状态 500

html - 哪种方式更好?求助于背景图片或使用绝对定位?

ajax - Google 抓取 AJAX 应用程序

java - tomcat的引用问题?

java - web.xml 中的 session 超时不适用于 weblogic 服务器