Java JSP / Servlet: сервлет контроллера, выбрасывающий знаменитое переполнение стека - PullRequest
4 голосов
/ 01 июня 2010

Я прочитал несколько документов и не понимаю: я знаю, что делаю что-то не так, но не понимаю, что именно. У меня есть веб-сайт, который генерируется полностью динамически: почти нет статического контента.

Итак, пытаясь понять JSP / Servlet, я написал свой собственный «фронт-контроллер», перехватывающий каждый запрос, он выглядит так:

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

В основном я хочу любой запрос пользователя, например:

  • example.org
  • example.org / бар
  • example.org / foo.html

чтобы все прошли через сервлет по умолчанию, который я написал.

Затем сервлет проверяет URI и находит, к чему .jsp должен быть отправлен запрос, и затем, после правильной установки всех атрибутов, a:

RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/index.jsp");
dispatcher.forward(req, resp);

Когда я использую шаблон URL (в web.xml ), например, *.html, все работает нормально. Но когда я изменяю его на /* (чтобы действительно перехватывать все), я вхожу в бесконечный цикл, и он заканчивается ... StackOverflow:)

Когда отправляется запрос, сам URI "... / WEB-INF / jsp / index.jsp" соответствует самому фильтру web.xml /, который Я установил?

EDIT очевидно, нет, потому что это точное отображение index.jsp и, следовательно, оно обходит шаблон web.xml url. Так что я до сих пор не понимаю, как мне войти в этот бесконечный цикл.

Как мне поступить, если я хочу перехватить все, используя / * url-pattern, и при этом иметь возможность отправлять / пересылать /?

Я не спрашиваю здесь о спецификациях / Javadocs: я действительно смущен общей картиной, и мне нужно какое-то объяснение того, что может происходить.

Разве я не должен перехватывать все?

Если я могу все перехватить, что я должен знать о пересылке / отправке?

Ответы [ 2 ]

4 голосов
/ 01 июня 2010

К сожалению, спецификация Serlvet не позволяет создавать отображение сервлета для соответствия только входящему запросу, а не форварду. Однако это можно сделать для сопоставлений фильтров (и по умолчанию сопоставления фильтров соответствуют только входящим запросам).

Итак, типичное решение для перехвата всего с помощью одного сервлета - это использование UrlRewriteFilter :

<filter>
    <filter-name>urlRewrite</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>urlRewrite</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>application</servlet-name>
    <servlet-class>...</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>application</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

/WEB-INF/urlrewrite.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
    PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
    "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">

<urlrewrite default-match-type="wildcard">
    <rule>
        <from>/**</from>
        <to>/app/$1</to>
    </rule>
    <outbound-rule>
        <from>/app/**</from>
        <to>/$1</to>
    </outbound-rule>    
</urlrewrite>

Этот способ также позволяет указать исключения из сопоставления /* для статических файлов.

0 голосов
/ 01 июня 2010

Попробуйте использовать распорки, в которых встроен шаблон переднего контроллера. Там у вас будет класс действия, и вы можете определить форварды в файле struts-config, используя которые вы можете легко управлять форвардами.

Пройдите учебник http://www.roseindia.net/struts/struts2/index.shtml. Надеюсь, это вам поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...