Отображение URL в Tomcat на сервлет FrontController - PullRequest
10 голосов
/ 18 января 2012

Я пытаюсь следовать шаблону на веб-приложениях Design Patterns . Все это прекрасно работает, когда дело доходит до сопоставления «корневых» URL.

Я бы хотел поставить все запросы через "Front Controller", поэтому я поставил

<servlet-mapping>
    <servlet-name>ControllerServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

в web.xml. При выполнении шага через Netbeans отображается входящий запрос, и действие работает нормально, но затем строка

request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);

ТАКЖЕ ловится контроллером, он снова переходит к действию и все терпит неудачу.

Я могу заставить его работать, не выходя из корня URL, например

  <servlet-mapping>
        <servlet-name>ControllerServlet</servlet-name>
        <url-pattern>/pages/*</url-pattern>
    </servlet-mapping>

Но это не то, что я хочу. Есть ли способ заставить его работать с «корневыми» URL?

Ответы [ 4 ]

8 голосов
/ 18 января 2012

Шаблон URL /* охватывает все , а также перенаправленные файлы JSP и статические ресурсы, такие как CSS / JS / images.Вы не хотите, чтобы это было на сервлете фронт-контроллера.

Держите ваш сервлет-контроллер на более конкретном шаблоне URL, таком как /pages/*.Вы можете выполнить функциональное требование избавления от "/ pages" в URL, сгруппировав статические ресурсы в общую папку, такую ​​как /resources и создав Filter, который сопоставлен с /* и выполняет следующую работу вdoFilter() method:

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("/pages" + path).forward(request, response);
}

Пересылаемый ресурс JSP по умолчанию не будет соответствовать этому фильтру, поэтому он будет правильно подобран собственным контейнером JspServlet.

3 голосов
/ 18 января 2012

Почему нам нужно сопоставить каждый URL. Если вам нужно сопоставить все URL, вам может понадобиться пропустить URL в фильтре.

   <filter>
    <display-name>SessionFilter</display-name>
    <filter-name>SessionFilter</filter-name>
    <filter-class>com.colabcom.goshare.app.base.filter.SessionFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

В вашем фильтре,

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String url = request.getServletPath();
        boolean allowedRequest = Utility.filterURL(url, avoidUrls);
        if(allowedRequest){
            chain.doFilter(request, response);
        }else{
            //Main Filter Code           
        }

Класс утилит для фильтрации вашего URL:

 public static boolean filterURL(String str, List<String> avoidURLList) {
    boolean exist = false;

    if(avoidURLList == null){
        return exist;
    }
    for (int i = 0; i < avoidURLList.size(); i++) {
        if (str.contains(avoidURLList.get(i))) {
            exist = true;
            break;
        }
    }
    return exist;
}

В противном случае вы можете сопоставить определенный URL в вашем файле web.xml, например

<filter-mapping>
    <filter-name>sessionFilter</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
0 голосов
/ 20 января 2013

Вы можете расширить DefaultServlet вашего веб-сервера. Расширенный сервлет будет вашим фронт-контроллером. В методе doGET или doPOST перенаправьте ваши статические страницы в суперкласс. DefaultServlet - это сервлет, который по умолчанию отображается на URL "/". Я использовал его с сервером Jetty, но он может быть реализован и в Tomcat.

public class FrontController extends DefaultServlet {

@Override
public void init() throws UnavailableException {
    super.init();
}

@Override
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    String uri = request.getRequestURI();

    /*
     * if request is trying to access inside /static then use the default
     * servlet. YOU CAN USE YOUR OWN BUSINESS LOGIC TO FORWARD REQUESTS 
     * TO DEFAULTSERVLET
     */
    if (uri.startsWith("/static/")) {

        super.doGet(request, response);
        return;
    } else {

        // else use your custom action handlers
    }
}

}

В приведенных выше примерах кода я перенаправил все запросы, начиная с / static /, на сервлет по умолчанию для обработки. Таким образом, вы можете отобразить FrontController на уровень "/".

<servlet>
<description></description>
<display-name>FrontController</display-name>
<servlet-name>FrontController</servlet-name>
<servlet-class>FrontController</servlet-class>

<servlet-mapping>
<servlet-name>FrontController</servlet-name>
<url-pattern>/</url-pattern>

0 голосов
/ 18 января 2012

шаблон / * url соответствует всем сервлетам, jsp и статическому содержимому в вашем приложении.

Что вам нужно, это определить шаблон * .jsp, чтобы позволить Tomcat использовать сервлет jsp по умолчанию:

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...