如何在应用程序上下文级别处理404

时间:2015-02-23 08:48:17

标签: tomcat java-ee java-ee-web-profile

我在tomcat 7 web服务器中部署了2个应用程序/项目。上下文路径不同,如" project1"," project2"。当我使用这些上下文路径命中URL时,相应的应用程序加载并正常工作。

有效网址为:

http://localhost:8080/project1

http://localhost:8080/project2

现在当我使用正确的主机名和错误的上下文路径(例如 / project3 )访问任何错误的网址时,它会显示错误消息 404 not found 并向用户显示一个奇怪的屏幕。

我希望向最终用户显示包含正确消息的正确页面。如何在Web服务器级别执行此操作?

2 个答案:

答案 0 :(得分:2)

您可以调整Tomcat的conf/web.xml文件以显示除404错误默认值之外的其他页面 - 请参阅here以获取示例。

提取物:

<error-page>  
       <error-code>404</error-code>  
       <location>/NotFound.jsp</location>  
</error-page>

答案 1 :(得分:1)

理论上,您应该能够修改默认tomcat Web应用程序的 web.xml ,但根据this,这对Tomcat 7不起作用。

您的另一个选择是扩展标准ErrorReportValve。我从现有的ErrorReportValve代码中非常自由地“借用”:

    public class Custom404Valve extends ErrorReportValve{

        public void invoke(Request request, Response response) throws IOException, ServletException {

           if(request.getStatusCode() != 404){
               super.invoke();
               return;
           }
           // Perform the request
           getNext().invoke(request, response);

           if (response.isCommitted()) {
               if (response.setErrorReported()) {
                   try {
                    response.flushBuffer();
                  } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                  }
               response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
                }
          return;
          }

         response.setSuspended(false);
         //this is where your code really matters
         //everything prior are just precautions I lifted
         //from the stock valve. 
         try {
           response.setContentType("text/html");
           response.setCharacterEncoding("utf-8");
           String theErrorPage = loadErrorPage();
           Writer writer = response.getReporter();
           writer.write(theErrorPage);
           response.finishResponse();
         } catch (Throwable tt) {
           ExceptionUtils.handleThrowable(tt);
         }

         if (request.isAsyncStarted()) {
             request.getAsyncContext().complete();
         }
      }

      protected String loadErrorPage() {
          BufferedReader reader = null;
          StringBuilder errorMessage = new StringBuilder();
              try{
                 File file = new File("YourErrorPage.html");
                 reader = new BufferedReader(new FileReader(file));

                    while (reader.ready()) {
                       errorMessage.append(reader.readLine());
                    }
              }catch (IOException e){
                  e.printStackTrace();
              }finally{
                 try{
                    reader.close();
                 }catch (IOException e) {
                    e.printStackTrace();
                 }
              } 
          return errorMessage.toString();     
        }
    }

您现在需要做的就是配置自定义阀门:

    <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">

        <Valve className="com.foo.bar.Custom404Valve"/>
    </Host>