Написание сервлета, который проверяет, существует ли JSP, и перенаправляет его в другой JSP, если его нет. - PullRequest
6 голосов
/ 24 марта 2010

UPDATE:

Чтобы прояснить общий улавливатель ошибок, который ловит 404, мне не хватает детализации. Мне нужно делать это только в том случае, если jsp находится в определенном каталоге, и только в том случае, если имя файла содержит определенную строку.

/ UPDATE

Мне было поручено написать сервлет, который перехватывает вызов и JSP в определенном каталоге, проверить, существует ли файл, и если он просто переадресовывает этот файл, если нет, я собираюсь переслать JSP по умолчанию. Я настроил web.xml следующим образом:

<servlet>
 <description>This is the description of my J2EE component</description>
 <display-name>This is the display name of my J2EE component</display-name>
 <servlet-name>CustomJSPListener</servlet-name>
 <servlet-class> ... CustomJSPListener</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>
...
<servlet-mapping>
  <servlet-name>CustomJSPListener</servlet-name>
  <url-pattern>/custom/*</url-pattern>
</servlet-mapping>

И метод doGet сервлета выглядит следующим образом:

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  logger.debug(String.format("Intercepted a request for an item in the custom directory [%s]",request.getRequestURL().toString()));
  String requestUri = request.getRequestURI();
            // Check that the file name contains a text string
  if (requestUri.toLowerCase(Locale.UK).contains("someText")){
   logger.debug(String.format("We are interested in this file [%s]",requestUri));
   File file = new File(requestUri);
   boolean fileExists = file.exists();
   logger.debug(String.format("Checking to see if file [%s] exists [%s].",requestUri,fileExists));
                    // if the file exists just forward it to the file
   if (fileExists){
    getServletConfig().getServletContext().getRequestDispatcher(
          requestUri).forward(request,response);
   } else {
                    // Otherwise redirect to default.jsp
    getServletConfig().getServletContext().getRequestDispatcher(
            "/custom/default.jsp").forward(request,response);
   }
  } else {
                    // We aren't responsible for checking this file exists just pass it on to the requeseted jsp
   getServletConfig().getServletContext().getRequestDispatcher(
           requestUri).forward(request,response);   
  }
 }

Кажется, это приводит к ошибке 500 от tomcat, я думаю, это потому, что сервлет перенаправляет в ту же папку, которая затем снова перехватывается сервлетом, что приводит к бесконечному циклу. Есть лучший способ сделать это? Я склонен полагать, что я мог бы использовать фильтры для этого, но я не очень много знаю о них.

Ответы [ 3 ]

8 голосов
/ 24 марта 2010
File file = new File(requestUri);

Это неправильно. java.io.File не знает ничего о контексте веб-приложения, в котором он запущен. Путь к файлу будет относительно текущего рабочего каталога, который зависит от способа запуска сервера приложений. Например, он может относиться к C:/Tomcat/bin, а не к корню веб-приложения, как вы ожидаете. Вы не хотите иметь это.

Используйте ServletContext#getRealPath(), чтобы преобразовать относительный веб-путь в абсолютный путь к файловой системе диска. ServletContext доступен в сервлете унаследованным методом getServletContext(). Таким образом, следующее должно указать правильный файл:

String absoluteFilePath = getServletContext().getRealPath(requestUri);
File file = new File(absoluteFilePath);

if (new File(absoluteFilePath).exists()) { 
    // ...
}

Или, если целевой контейнер не расширяет WAR в файловой системе физического диска, а вместо этого в памяти, вам лучше использовать ServletContext#getResource():

URL url = getServletContext().getResource(requestUri);

if (url != null) { 
    // ...
}
4 голосов
/ 24 марта 2010

Это можно сделать намного проще и встроеннее.

web.xml имеет <error-page> элемент. Вы можете сделать что-то вроде:

<error-page>
    <error-code>404</error-code>
    <location>/pageNotFound.jsp</location>
<error-page>
0 голосов
/ 24 марта 2010

Что я хотел бы сделать, это создать фиктивный каталог для первоначального запроса сервлета, а затем перейти к реальному каталогу или к странице типа 404. Вы выдаете форвард независимо, так почему бы просто не перенаправить в другой каталог? Это позволит избежать любой проблемы зацикливания.

...