一直使用tomcat,今天想到一个问题,自定义404错误页面, 为了获得很好的用户感受,是不应当向用户暴露404这样的页面的, 问题的出发点是我在Struts2中定义错误页面, 在Struts2中是这样定义的:
1
2
3
4
|
< default-action-ref name = "pagenotfound" ></ default-action-ref > < action name = "pagenotfound" > < result >/pagenotfound.html</ result > </ action > |
这就是说在访问action是.如果没有找到action就访问这个页面,但是我如果我不用.do或者.action的样式,而直接使用.jsp或者.html的方式来访问页面的请,struts就不会处理了.结果是404错误依然出现.
现在已经不是struts的处理范围了,那么这应当是应用的处理范围,经查证,在工程的web.xml中可以设置自定义错误页面,设置如下:
1
2
3
4
|
< error-page > < error-code >404</ error-code > < location >/pagenotfound.html</ location > </ error-page > |
现在再访问该该工程下面一个不存在的页面,将跳转到自定义的pagenotfound页面,这样,struts中的那个default-action-ref 配置是可以去掉的了.因为404交给tomcat处理了.
然后,然后我输入http://localhost/asdfasdfafd一个不存在的地址,结果404依然出现,
回头想一下,刚才我们的web.xml是在某一个应用下面的,他处理的应当是本应用的404,而http://localhost/访问的是tomcat自已的应用,那么这个web.xml配置就应当在webapp/Root/下面的应用来配了,
Root目录下面放着Tomcat的应用,把里面换成自已的就行了.
于是现在再进行输入不存在的地址,成功跳向自定义的错误页面.
Tomcat中404/500 错误,自定义错误页面
当服务器出现404、500错误时候希望能够给用户友好的现实界面
只需要在项目的web.xml中添加一些配置
1
2
3
4
5
6
7
8
9
10
|
< error-page > < error-code >404</ error-code > < location >/NotFound404.jsp</ location > </ error-page > < error-page > < error-code >500</ error-code > < location >/NotFound500.jsp</ location > </ error-page > |
这样当你在访问不存在的页面出错的页面时就自动显示刚才指定的页面了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<!-- 400错误 --> < error-page > < error-code >400</ error-code > < location >/error.jsp</ location > </ error-page > <!-- 404 页面不存在错误 --> < error-page > < error-code >404</ error-code > < location >/error.jsp</ location > </ error-page > <!-- 500 服务器内部错误 --> < error-page > < error-code >500</ error-code > < location >/error.jsp</ location > </ error-page > <!-- java.lang.Exception异常错误,依据这个标记可定义多个类似错误提示 --> < error-page > < exception-type >java.lang.Exception</ exception-type > < location >/error.jsp</ location > </ error-page > <!-- java.lang.NullPointerException异常错误,依据这个标记可定义多个类似错误提示 --> < error-page > < exception-type >java.lang.NullPointerException </ exception-type > < location >/error.jsp</ location > </ error-page > < error-page > < exception-type >javax.servlet.ServletException</ exception-type > < location >/error.jsp</ location > </ error-page > |
具体的如下:
Tomcat 的错误页面是由 org.apache.catalina.valves.ErrorReportValve 类输出来的。如果想自定义错误页面,不需要修改该类。Servlet 规范声明了相关的API,只需要在每个 web 应用的 web.xml 里定义。可按照错误类型、错误代码配置。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
< web-app xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version = "2.5" > < display-name >Welcome to Tomcat</ display-name > < description > Welcome to Tomcat </ description > < error-page > < error-code >404</ error-code > < location >/errorpages/404.jsp</ location > </ error-page > < error-page > < exception-type >java.lang.Exception</ exception-type > < location >/errorpages/exception.jsp</ location > </ error-page > </ web-app > |
注意错误页面必须以“/”开头,这样任何path的404错误页面及exception错误都会映射到这两个文件。然后在本web引用的errorpages下面放置404.jsp, exception.jsp两个文件。
错误页面 404.jsp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<%@ page contentType= "text/html; charset=UTF-8" %> <%@ page import = "java.io.*" %> <%@ page import = "java.util.*" %> <html> <header> <title> 404 page</title> <body> <pre> <% Enumeration<String> attributeNames = request.getAttributeNames(); while (attributeNames.hasMoreElements()) { String attributeName = attributeNames.nextElement(); Object attribute = request.getAttribute(attributeName); out.println( "request.attribute['" + attributeName + "'] = " + attribute); } %> </pre> |
代码中输出了所有的 request 中的变量。从中也可以看到访问哪个文件出错,跳到哪个错误页面了,从而进行更详细、更人性化的错误处理。例如,提示可能的正确网址等等。
例如:访问一个不存在的页面 page_not_exist.html,显示的信息为:
request.attribute['javax.servlet.forward.request_uri'] = /page_not_exists.html
request.attribute['javax.servlet.forward.context_path'] =
request.attribute['javax.servlet.forward.servlet_path'] = /page_not_exists.html
request.attribute['javax.servlet.forward.path_info'] = /errorpages/404.jsp
request.attribute['javax.servlet.error.message'] = /page_not_exists.html
request.attribute['javax.servlet.error.status_code'] = 404
request.attribute['javax.servlet.error.servlet_name'] = default
request.attribute['javax.servlet.error.request_uri'] = /page_not_exists.html
注意,该错误页面必须大于512字节,否则IE将不予显示。因为IE默认只显示大于512字节的错误页面。Firefox中正常显示。可以添加一些其他信息,将页面大小扩充到512字节以上。如果仍不能显示,请检查IE设置,将该选项选中。
异常处理页面 exception.jsp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<%@ page contentType= "text/html; charset=UTF-8" isErrorPage= "true" %> <%@ page import = "java.io.*" %> <html> <header> <title>exception page</title> <body> <hr/> <pre> <% response.getWriter().println( "Exception: " + exception); if (exception != null ) { response.getWriter().println( "<pre>" ); exception.printStackTrace(response.getWriter()); response.getWriter().println( "</pre>" ); } response.getWriter().println( "<hr/>" ); %> |
注意isErrorPage熟悉必须为true,才能使用exception对象。exception即捕捉到的异常。此处可以对exception进行处理,比如记录日志、重定向等等。这里把exception trace打印出来了。
500、505 等错误页面的处理类似于404。