(Почти) все 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, который отображает все ваши статические файлы.