StackOverflowError в сопоставлении сервлетов с url-шаблоном "/*"
У меня есть набор страниц 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
... который использует простой сервлет для пересылки запроса. В моей паутине.в 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-шаблон на "/* "
<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)
Который я не знаю, как исправить. Есть идеи?
2 ответа:
Сервлет, отображенный на
/*
, также будет работать на вызовахRequestDispatcher#forward()
. Поэтому, если вы выполняете форвард в этом сервлете, он будет вызывать себя каждый раз в бесконечном цикле. Это объясняетStackOverflowError
.В конце концов, вы вообще не должны использовать
/*
для сервлетов. Это имеет смысл только на фильтрах сервлетов. Поместите отображение сервлета обратно на более конкретный шаблон URL и создайте фильтр на/*
, который при необходимости перенаправляет к нужному сервлету. Вы, конечно, не хотите иметь сервлет для обработки, например, файлов 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); }
См. также:
Вы должны использовать UrlRewriteFilter
Вы можете использовать некоторые из них в вашем файле конфигурации (urlrewrite.xml):
<rule> <from>/products/([a-zA-Z0-9._%]+)</from> <to>/products.jsp?id=$1</to> </rule>
UrlRewriteFilter находится в комментарии a, но я считаю, что это должен быть независимый ответ.