我有一组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页面设置此映射。
我在此处发布了另一个解决方案(简易网址):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>
现在问题是我不想点击网址: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)
我不确定如何修复。有什么想法吗?
答案 0 :(得分:6)
映射到/*
的servlet也将在RequestDispatcher#forward()
个调用上运行。因此,如果您在该servlet中执行转发,它将在无限循环中每次调用自身。这解释了StackOverflowError
。
毕竟,您根本不应该将/*
用于servlet。它只适用于servlet过滤器。将servlet映射放回更具体的URL模式,并在/*
上创建一个过滤器,在必要时转发到所需的servlet。您当然不希望servlet处理例如images / 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);
}
答案 1 :(得分:1)
您应该使用UrlRewriteFilter
您可以在配置文件(urlrewrite.xml)上使用类似的内容:
<rule>
<from>/products/([a-zA-Z0-9._%]+)</from>
<to>/products.jsp?id=$1</to>
</rule>
UrlRewriteFilter是评论,但我认为它应该是一个独立的答案。