zoukankan      html  css  js  c++  java
  • Tomcat:Custom a common error page valve for all web application in tomcat

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

      在每个web应用中都可以通过error-page来配置错误页面。但是多个Web应用时,要在每个应用的web.xml中都配置一个错误页面,就显得有些麻烦了。然而希望通过在tomcat/conf/web.xml中来配置错误页面,是不能实现的。因为Tomcat部署应用时会将公共的web.xml与每个web应用的web.xml进行合并,查找页面时,其实还是在每个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.xml中Host的errorReportValveClass属性值为这个类。
     * 另外需要将这个类打成jar包放在tomcat/lib目录下。
     * @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();
                }
            }
        }
        
    }
  • 相关阅读:
    cnpm镜像安装
    wxParse解析html
    C++回调函数
    QT源码分析:QTcpServer
    QT实现支持加密的Sqlite数据库引擎
    VS2013+OpenCV3.4.2编译
    Android Tcp操作
    使用Delphi开发linux应用
    QT5.10+MinGW+OpenCV3.4.2编译
    C++ ActiveX开发的问题讨论
  • 原文地址:https://www.cnblogs.com/f1194361820/p/4553998.html
Copyright © 2011-2022 走看看