如果在一个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();
}
}
} }

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

  1. Tomcat翻译--Tomcat Web Application Deployment(Tomcat中部署web应用)

    原文:http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html Introduction(介绍) Deployment is the te ...

  2. ASP.NET Core:CMD命令行+记事本 创建Console程序和Web Application

    今天看了Scott关于ASP.NET Core的介绍视频,发现用命令行一步一步新建项目.添加Package.Restore.Build.Run 执行的实现方式,更让容易让我们了解.NET Core的运 ...

  3. Cannot forward to error page for request ......

    今天现场报了以下问题: Cannot forward to error page for request [/order/search] as the response has already bee ...

  4. 前端错误提示whitelabel error page

    1:错误提示whitelabel error page:需要定义一个error.html  ,否则提示如图

  5. JDK和Tomcat环境变量,以及用MyEclipse新建Web Project测试Tomcat Server

    [请尊重原创版权,如需引用,请注明来源及地址] 在此之前一直用的Eclipse挺顺手的,今天突然想换MyEclipse试试,不知安装MyEclipse的时候我选错了什么选项,反正JDK和Tomcat的 ...

  6. JavaWeb--基本概念、Web服务器与Tomcat

    前言 Java Web 其实就是一个技术的总和,把Web看成一个容器而已主要使用JavaEE技术来实现.在加上各种中间件. 整个javaWeb阶段的内容通过实际的案例贯穿学习, 所涉及到的技术知识点会 ...

  7. How to create your own custom 404 error page and handle redirect in SharePoint 分类: Sharepoint 2015-07-08 00:22 4人阅读 评论(0) 收藏

    1. In your MOSS server, make a copy of %systemdrive%\Program Files\Common Files\Microsoft Shared\Web ...

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

    一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAtt ...

  9. [转]在ASP.NET Core使用Middleware模拟Custom Error Page功能

    本文转自:http://www.cnblogs.com/maxzhang1985/p/5974429.html 阅读目录 一.使用场景 二..NET Core实现 三.源代码 回到目录 一.使用场景 ...

随机推荐

  1. 介绍开源的.net通信框架NetworkComms框架 源码分析(十四)StreamTools

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  2. 孙鑫MFC学习笔记12:文件读写

    1.指向常量的指针 2.指针常量 3.C语言对文件操作是在缓冲区,在缓冲区满或文件关闭时写入文件 读取相同 4.fflush刷新缓冲区,使缓冲区数据写入文件 5.fseek改变文件指针偏移量 6.st ...

  3. Struts 2.0全面分析

    Struts 2.0 struts 1---前端控制+应用控制+命令模式 webwork ---控制器+拦截器+代理 Struts 2.0 继承了WebWork的设计理念,并没有继承struts 1, ...

  4. 泛函编程(35)-泛函Stream IO:IO处理过程-IO Process

    IO处理可以说是计算机技术的核心.不是吗?使用计算机的目的就是希望它对输入数据进行运算后向我们输出计算结果.所谓Stream IO简单来说就是对一串按序相同类型的输入数据进行处理后输出计算结果.输入数 ...

  5. Linux命令详解之—more命令

    Linux more命令同cat命令一样,多用来查看文件内容,本文就为大家介绍下Linux more命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux的more命令类似 ca ...

  6. 操作系统与c语言

      以下是根据看书后的理解做的总结:   最早,unix是使用汇编编写,但是非常简单.后来觉得汇编,换种机器又得重新用另外一种机器汇编重写,太麻烦.于是想设计一种通用的语言,到各种机器上都能运行 当时 ...

  7. [asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文

    我们在asp.net 开发中已经封装了最强大的HttpContext,我们可以在HttpContext中可以获取到几乎任何想获取的东西,也可以在HttpContext写入需要返回客户端的信息.但是这些 ...

  8. Nodejs与ES6系列1:变量声明

    1.声明变量 在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域.变量分为两类,全局(global)的和局部的.其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都 ...

  9. ENVI【遥感图像预处理之图像的几何校正】

    ---恢复内容开始--- 一.图像几何校正的概述 1.几何校正方法: 1)利用卫星自带的地理定位文件进行几何校正.主菜单>>>Map>>Georeference传感器的名 ...

  10. MySQL之MySQL5.7安装包(msi文件)在Windows8下安装

    最近自己在使用MySQL5.7.16.msi安装MySQL.自己下载的是.msi文件,在安装的过程中遇到了许多文件,网上大部分的Blog都是关于免安装包的安装方法,希望我的方法对大家有帮助. 1,下载 ...