编写一个Servlet来检查JSP是否存在,如果不存在则转发给另一个JSP

更新:

澄清捕获404的一般错误捕获器对我来说没有足够的粒度。 我只有在jsp位于特定目录中时才需要这样做,并且只有当文件名包含某个字符串时才需要这样做。

/ UPDATE

我的任务是编写一个servlet来拦截对特定目录中的JSP和JSP的调用,检查文件是否存在以及它是否仅转发到该文件,如果没有,那么我将转发到默认的JSP。 我按如下方式设置了web.xml:

 This is the description of my J2EE component This is the display name of my J2EE component CustomJSPListener  ... CustomJSPListener 1  ...  CustomJSPListener /custom/*  

并且servlet的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); } } 

这似乎导致tomcat出现错误500,我认为这是因为servlet重定向到同一个文件夹,然后由servlet再次拦截,导致无限循环。 有一个更好的方法吗? 我相信我可以使用filter来做到这一点,但我不太了解它们。

 File file = new File(requestUri); 

这是错的。 java.io.File对运行它的webapp上下文一无所知 。文件路径将相对于当前工作目录,这取决于启动应用程序服务器的方式。 例如,它可能是相对于C:/Tomcat/bin而不是您期望的webapp根。 你不想拥有这个。

使用ServletContext#getRealPath()将相对Web路径转换为绝对磁盘文件系统路径。 servlet中的ServletContext由inheritance的getServletContext()方法提供。 因此,以下应指出正确的文件:

 String absoluteFilePath = getServletContext().getRealPath(requestUri); File file = new File(absoluteFilePath); if (new File(absoluteFilePath).exists()) { // ... } 

或者,如果目标容器没有在物理磁盘文件系统上扩展WAR,而是在内存中扩展WAR,那么最好使用ServletContext#getResource()

 URL url = getServletContext().getResource(requestUri); if (url != null) { // ... } 

这可以通过更简单和内置的方式完成。

web.xml有元素。 你可以这样做:

  404 /pageNotFound.jsp  

我要做的是为初始servlet请求创建一个虚拟目录,然后转发到真实目录或404类型页面。 无论你是在发布前锋,为什么不重定向到另一个目录? 这样可以避免任何循环问题。