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 [email protected] 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();
            }
        }
    }

}
时间: 2024-11-29 09:25:05

Tomcat:Custom a common error page valve for all web application in tomcat的相关文章

【Tomcat】【3】报错 Illegal access: this web application instance has been stopped already. Could not load [org.apache.commons.pool.impl.CursorableLinkedList$Cursor]

用Tomcat运行项目报错: Illegal access: this web application instance has been stopped already. Could not load [org.apache.commons.pool.impl.CursorableLinkedList$Cursor]. The following stack trace is thrown for debugging purposes as well as to attempt to term

在ASP.NET Core使用Middleware模拟Custom Error Page功能

一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAttribute特性,那么默认的,当这个Action抛出了异常时MVC将会显示Error视图,该视图位于~/Views/Shared目录下. 自定义错误页面的目的,就是为了能让程序在出现错误/异常的时候,能够有较好的显示体验.有时候在Error视图中也会发生错误,这时ASP.NET/MVC将会显示其默认

Tomcat Error Page配置

如果JSP页面出现异常,就会转到tomcat自动的那个异常页面,页面不怎么友好.jsp标准中提供了error page的配置,可以自己定义当出现错误时跳转到哪个页面.这个配置在web.xml里面进行配置,下面一步步来实现自定义错误页面. 1.首先,在web.xml加入下面的标签: <error-page>       <error-code>400</error-code>       <location>/400.html</location>

使用Tomcat时出现问题:严重: Error deploying web application directory G:\MyEclipseWorkspaces\.metadata\.me_tcat7\webapps\hiber_test

今天我写了第一个jsp和Servlet,然后再myeclipse上使用tomcat来搭建服务器,登录时出现的问题. 出现问题: 严重: Error deploying web application directory G:\MyEclipseWorkspaces\.metadata\.me_tcat7\webapps\hiber_test 按照老师教的步骤一步一步来,结果打开jsp网页时还是报错了 一开始我还以为是Tomcat版本问题,然后换了6和7,又用了myeclipse自带的那两个,结果

问题:Custom tool error: Failed to generate code for the service reference &#39;AppVot;结果:添加Service Reference, 无法为服务生成代码错误的解决办法

添加Service Reference, 无法为服务生成代码错误的解决办法 我的解决方案是Silverlight+WCF的应用,Done Cretiria定义了需要在做完Service端的代码后首先运行事先定义好的Unit Test,确保在客户端使用Service之前Service是可以正确的运行的.在我创建Unit Test之前,需要在测试项目中添加对WCF Service的引用,而这时却出现了错误. Custom tool error: Failed to generate code for

tomcat:java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind

error message:Error initializing endpointjava.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bindat java.net.PlainSocketImpl.socketBind(Native Method)at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)at java.net.ServerSocket.

SpringBoot接口服务处理Whitelabel Error Page

转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50915979 <SpringBoot接口服务处理Whitelabel Error Page> <Maven依赖载入错误的情况分析> <Java Webproject转换为基于Maven的Webproject> <Maven Webproject执行异常:Maven.multiModuleProjectDirectory system propery

Error page: /dede/login.php Error infos: No database

登陆dede后台这样提示Error page: /dede/login.php Error infos: No database selected Error sql: Select admin.*,atype.purviews From `dede_admin` admin left join `dede_admintype` atype on atype.rank=admin.usertype where admin.userid like 'admin' limit 0,1登陆dede后台

Tomcat:Java Web服务器配置详解

一.Tomcat概述 1.tomcat简介 tomcat是基于JDK的web服务器,其能运行Servlet和JSP规范总.Tomcat 5支持最新的Servlet 2.4 和JSP 2.0规范.实际上Tomcat 部分是Apache服务器的扩展,但它是独立运行的.运行tomcat时,它实际上作为一个与Apache 独立的进程单独运行的.Apache 为HTML页面服务,而Tomcat实际上运行JSP页面和Servlet.tomcat具有处理HTML页面的功能,另外它还是一个Servlet和JSP