(Почти) все URL-адреса одного сервлета
Я хотел бы сопоставить все URL-адреса с одним основным сервлетом, за исключением моих статических файлов (например, таблиц стилей, графики и т.д.) и по-прежнему иметь возможность вызывать JSP из моих сервлетов.
Я намерен предоставить пользователям "URL тщеславия", чтобы любой URL-адрес, который не указывает на статический файл или ресурс, отображается на мой основной сервлет.
Как мне это сделать??
Если это помогает, у меня могут быть все мои статические файлы и JSP в отдельных папках. Есть ли способ сопоставить эти папки перед отображением/*..?
Ответы
Ответ 1
Вдохновленный Как получить доступ к статическим ресурсам при сопоставлении глобального сервлет-контроллера в /*
Я придумал это решение:
в /war/WEB-INF/web.xml
:
<filter>
<filter-name>MainFilter</filter-name>
<filter-class>com.example.mywebsite.MainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MainFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>com.example.mywebsite.MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/MainServlet/*</url-pattern>
</servlet-mapping>
в MainFilter.java
:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI();
String topfolder = path.substring(1);
if (topfolder.contains("/")) {
topfolder = topfolder.substring(0, topfolder.indexOf("/"));
}
if (topfolder.startsWith("_")) {
chain.doFilter(request, response);
} else if (topfolder.endsWith(":")) {
request.getRequestDispatcher(path.replaceFirst(":", "")).forward(request, response);
} else {
request.getRequestDispatcher("/MainServlet" + path).forward(request, response);
}
}
Теперь вы можете поместить весь свой статический контент в подпапки в своей WAR. Затем, если вы хотите ссылаться на /war/css/style.css
на свой HTML, вы просто называете его "/css:/style.css"
.. Или вы можете называть свои папки/файлы с помощью _
в начале и ссылаться на них, как обычно..
(Также правило _
гарантирует, что разработчики Google App Engine могут получить доступ к /_ah/admin
)
Ответ 2
Как правильно сказано в комментарии, используйте отдельный сервлет для отдельных JSP, если для этого не существует обоснованной причины. Если вы хотите это сделать, вы можете просто иметь блок if--else
в своем сервлете, который отображается на разных URL-адресах, и на основе входящего и отправляемого запроса в соответствующий JSP.
Как
...
else if(request.getServletPath().equals("/user/account")){
//relevant processing and setting request attribute goes here
request.getRequestDispatcher("account_jsp_page.jsp").forward(request, response);
}
else if (....){
....
Я предлагаю против этого плана. лучше иметь web.xml
для выполнения маршрутизации. Или лучше использовать фреймворк, который обрабатывает это для вас.
Ответ 3
Я бы рекомендовал использовать фреймворк для обработки маршрутизации, например, Spring, а Struts лучше справляется с обработкой маршрутизации. Вы можете сделать сервлет или web.xml сделать это, но тогда не повторное использование кода из фреймворка просто кажется бессмысленным в этом случае. Поэтому я бы рекомендовал пойти с Spring или Struts 2
Ответ 4
Два способа сделать это не идеальны:
- Определите расширение для своих "действий" и сопоставьте его с вашим сервлетом (например,.do в Struts 1).
- Попросите все запросы сервлета перейти к определенному подпути (например,/actions/*)
Правила сопоставления в web.xml
довольно ограничены, поскольку контейнер соответствует расширениям после правил пути, невозможно сопоставить сервлет с /*, except *.jsp
.
Как обычно, я не думаю, что "использовать фреймворк" обязательно является ответом - если проект относительно невелик, добавленная сложность может не стоить того.
Ответ 5
Помимо всех структур, которые могут сделать это для вас, как уже указывали другие, попробуйте сопоставить это наоборот.
Поэтому вместо того, чтобы пытаться отобразить все, кроме исключений, сопоставьте исключения и позвольте всем пройти через ваш сервлет. Вы можете легко достичь этого, поставив фильтр upfront, который отображает все ваши статические файлы.