6

我有一组 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):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

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

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

4

2 回答 2

6

映射到的 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);
}

也可以看看:

于 2012-05-01T18:29:31.077 回答
1

你应该使用 UrlRewriteFilter

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

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

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

于 2013-01-03T17:33:36.907 回答