你的位置:首页 > Java教程

[Java教程]Tomcat:Custom a common error page valve for all web application in tomcat


  如果在一个Tomcat Server上会部署多个Web应用,又希望这多个Web应用共用一套错误页面,而不是使用默认的错误页面。就需要自定义错误页面了。

  在每个web应用中都可以通过error-page来配置错误页面。但是多个Web应用时,要在每个应用的web.

  为了达到共用的目录,只能自己来重写Tomcat的默认实现了。所幸,Tomcat也是支持我们这样去做的。

package com.fjn.frame.catalina.valves;import java.io.IOException;import java.io.InputStream;import java.io.Writer;import java.util.Scanner;import org.apache.catalina.connector.Request;import org.apache.catalina.connector.Response;import org.apache.catalina.util.RequestUtil;import org.apache.catalina.util.ServerInfo;import org.apache.catalina.valves.ErrorReportValve;/** * * 要使用这个类来自定义错误页面,需要调整 server.@since tomcat 6.0 * @author fs1194361820@163.com 2015年6月4日 * */public class ErrorPageValve extends ErrorReportValve {  private static final String ERROR_PAGE_NAME = "errorPage.html";  @Override  protected void report(Request request, Response response,      Throwable throwable) {    // Do nothing on non-HTTP responses    int statusCode = response.getStatus();    // Do nothing on a 1xx, 2xx and 3xx status    // Do nothing if anything has been written already    if (statusCode < 400 || response.getContentCount() > 0        || !response.isError()) {      return;    }    String message = RequestUtil.filter(response.getMessage());    if (message == null) {      if (throwable != null) {        String exceptionMessage = throwable.getMessage();        if (exceptionMessage != null && exceptionMessage.length() > 0) {          message = RequestUtil              .filter((new Scanner(exceptionMessage)).nextLine());        }      }      if (message == null) {        message = "";      }    }    // Do nothing if there is no report for the specified status code    String report = null;    try {      report = sm.getString("http." + statusCode);    } catch (Throwable t) {      ;    }    if (report == null)      return;    StringBuffer sb = new StringBuffer();    try {      buildHTMLFromErrorPage(sb);    } catch (Exception ex) {    }    if (sb.length() < 1) {      defaultBuildHTML(sb, statusCode, message, report, throwable);    }    try {      try {        response.setContentType("text/html");        response.setCharacterEncoding("utf-8");      } catch (Throwable t) {        if (container.getLogger().isDebugEnabled())          container.getLogger().debug("status.setContentType", t);      }      Writer writer = response.getReporter();      if (writer != null) {        // If writer is null, it's an indication that the response has        // been hard committed already, which should never happen        writer.write(sb.toString());      }    } catch (IOException e) {      ;    } catch (IllegalStateException e) {      ;    }  }  private void defaultBuildHTML(StringBuffer sb, int statusCode,      String message, String report, Throwable throwable) {    sb.append("<html><head><title>");    sb.append(ServerInfo.getServerInfo()).append(" - ");    sb.append(sm.getString("errorReportValve.errorReport"));    sb.append("</title>");    sb.append("<style><!--");    sb.append(org.apache.catalina.util.TomcatCSS.TOMCAT_CSS);    sb.append("--></style> ");    sb.append("</head><body>");    sb.append("<h1>");    sb.append(        sm.getString("errorReportValve.statusHeader", "" + statusCode,            message)).append("</h1>");    sb.append("<HR size=\"1\" noshade=\"noshade\">");    sb.append("<p><b>type</b> ");    if (throwable != null) {      sb.append(sm.getString("errorReportValve.exceptionReport"));    } else {      sb.append(sm.getString("errorReportValve.statusReport"));    }    sb.append("</p>");    sb.append("<p><b>");    sb.append(sm.getString("errorReportValve.message"));    sb.append("</b> <u>");    sb.append(message).append("</u></p>");    sb.append("<p><b>");    sb.append(sm.getString("errorReportValve.description"));    sb.append("</b> <u>");    sb.append(report);    sb.append("</u></p>");    if (throwable != null) {      String stackTrace = getPartialServletStackTrace(throwable);      sb.append("<p><b>");      sb.append(sm.getString("errorReportValve.exception"));      sb.append("</b> <pre>");      sb.append(RequestUtil.filter(stackTrace));      sb.append("</pre></p>");      int loops = 0;      Throwable rootCause = throwable.getCause();      while (rootCause != null && (loops < 10)) {        stackTrace = getPartialServletStackTrace(rootCause);        sb.append("<p><b>");        sb.append(sm.getString("errorReportValve.rootCause"));        sb.append("</b> <pre>");        sb.append(RequestUtil.filter(stackTrace));        sb.append("</pre></p>");        // In case root cause is somehow heavily nested        rootCause = rootCause.getCause();        loops++;      }      sb.append("<p><b>");      sb.append(sm.getString("errorReportValve.note"));      sb.append("</b> <u>");      sb.append(sm.getString("errorReportValve.rootCauseInLogs",          ServerInfo.getServerInfo()));      sb.append("</u></p>");    }    sb.append("<HR size=\"1\" noshade=\"noshade\">");    sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");    sb.append("</body></html>");  }  private void buildHTMLFromErrorPage(StringBuffer buffer) throws IOException {    InputStream in=null;    Scanner scanner = null;    try {      // 优先从当前路径下查找文件      in=this.getClass().getResourceAsStream(ERROR_PAGE_NAME);      if(in==null){        // 从当前jar包内的根目录 或者tomcat/lib目录下        in=Thread.currentThread().getContextClassLoader().getResourceAsStream(ERROR_PAGE_NAME);      }      if(in==null){        in=ClassLoader.getSystemResourceAsStream(ERROR_PAGE_NAME);      }      scanner = new Scanner(in);      while (scanner.hasNextLine()) {        String line = scanner.nextLine();        // line=RequestUtil.filter(line);        buffer.append(line);      }    } catch (Exception ex) {    } finally {      if (scanner != null) {        scanner.close();      }      if(in!=null){        in.close();      }    }  }  }