Как мне указать строку запроса в Tomcat ‹servlet-mapping› ‹url-pattern›?

Я запускаю Tomcat 5.5.4, и сервлет работает без проблем. Однако я хотел бы настроить отображение для запуска сервлета только при отправке URL-адреса, содержащего конкретную строку запроса.

Прямо сейчас в web.xml у меня есть: <servlet-mapping> <servlet-name>MyServer</servlet-name> <url-pattern>/go/*</url-pattern> </servlet-mapping>

Если браузер отправляет http://localhost/MyServer/go?P=123, запускается сервлет. и все хорошо. Однако я хотел бы запускать этот сервлет только в том случае, если URL-адрес точно такой, как только что показано. К сожалению, прямо сейчас, если URL-адрес http://localhost/MyServer/go?P=AnyDarnThing сервлет все еще запускается. Я попытался настроить следующее: <url-pattern>/go?P=123</url-pattern>, но в результате запрошенный ресурс (/ MyServer / go) недоступен.

Я пробовал множество вариантов (цитируя строку, ...) в указанном выше шаблоне URL, но всегда получаю указанную выше ошибку. Я заметил, что если я (в целях отладки) опущу "?" как в <url-pattern>/goP=123</url-pattern>, я больше не получаю сообщение об ошибке и сервер запускается (но, конечно, он не отвечает на «строку запроса», потому что она неправильно сформирована.) Это наводит на мысль, что знак «?» вызывает проблему при отображении. Я попытался заменить его эквивалентом специального символа URL-адреса следующим образом: <url-pattern>/go%3FP=123</url-pattern>, но это дает тот же результат, который был только что описан выше, когда я пытался отбросить "?" все вместе.

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

Спасибо.


person Al Koch    schedule 26.03.2012    source источник
comment
См. Также Недопустимое сопоставление сервлета URL-шаблона в tomcat 6.0   -  person McDowell    schedule 27.03.2012


Ответы (3)


Вы не можете сделать это с помощью шаблонов URL.

Вы можете добиться этого с помощью фильтров. Реализуйте фильтр, который будет перенаправлять сервлету, только если параметры запроса существуют.

Вот как будет выглядеть фильтр:

public class ServletAcessFilter implements Filter
{
  public void init(FilterConfig filterConfig) throws ServletException
  {

  }

  public void doFilter(ServletRequest request, ServletResponse response,
  FilterChain filterChain) throws IOException, ServletException
  {
    //validate the request, check if the request can be forwarded to servlet.
    if(request.getParameter("P").equalsIgnoreCase("123")){
        filterChain.doFilter(request, response);
    } else {
        //write what you want to do if the request has no access
        //below code will write 404 not found, you can do based on your requirement
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(404);
    }
  }

  public void destroy()
  {

  }
}

Определите фильтр в web.xml следующим образом:

<filter>
    <filter-name>ServletAccessFilter</filter-name>
    <filter-class>com.ServletAcessFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ServletAccessFilter</filter-name>
    <url-pattern>/go/*</url-pattern>
</filter-mapping>
person Ramesh PVK    schedule 27.03.2012
comment
Я не знаком с фильтрами. Не могли бы вы предложить ресурс, где я мог бы научиться писать для этого фильтр? (Или, если фильтр действительно простой, вы можете показать мне, как он выглядит?) Спасибо. - person Al Koch; 28.03.2012
comment
добавил фильтр, дайте мне знать, если вам понадобится помощь - person Ramesh PVK; 28.03.2012
comment
Большое спасибо Рамешу! Я ценю, что вы нашли время написать код. Я попробую. Еще раз спасибо. - person Al Koch; 02.04.2012

Вы не можете этого сделать. url-pattern довольно ограничен.

Если вы хотите, чтобы различные действия выполнялись на основе параметра GET, вы можете сделать это вручную. В методе doGet() сервлета есть простое предложение if и вызывают разные методы в зависимости от строки запроса / параметра get.

person Bozho    schedule 26.03.2012
comment
Да, но я пытался избежать написания логики в самом сервлете. Спасибо. - person Al Koch; 28.03.2012

Чтобы добавить в ответ Божо, вы также можете попробовать перейти на чистые URL-адреса

Это значительно расширит ваши возможности с точки зрения сопоставления шаблонов URL и, в частности, может значительно упростить настройку фронтального обратного прокси, если он вам когда-либо понадобится.

person Bruno Grieder    schedule 27.03.2012
comment
Спасибо за это предложение. Независимо от моего вопроса, это похоже на хорошую идею! - person Al Koch; 28.03.2012