说明
处理业务的 Servlet 抛出异常后,我们可以配置 一个 全局异常处理器(Servlet)来处理异常
好处
如 LoginServlet 处理登录操作,当用户名不存在或密码错误时,直接抛出异常即可,不需要 跳转页面 或 返回JSON
由 全局异常处理器 处理上面的异常,根据请情况,跳转页面 或 返回JSON
好处:业务Servlet,只需要抛出异常即可,不需要做后续处理
全局异常处理
其实就是普通 Servlet,如下:
public class ErrorHandler extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取异常相关信息
通过 request.getAttribute(Key) 方法获取 业务Servlet 抛出的异常信息
key有:
javax.servlet.error.status_code:HTTP协议的状态码,
Integer类型javax.servlet.error.message:错误信息,
String类型javax.servlet.error.request_uri:访问哪个 URL 调用 Servlet,
String类型javax.servlet.error.exception:异常对象,
java.lang.Throwable类型javax.servlet.error.exception_type:异常类型的信息,
java.lang.Class类型javax.servlet.error.servlet_name: Servlet 的名称,
String类型
注意:根据情况,上面的值可能获取不到,如:如果 业务Servlet 抛出异常,那么只有 javax.servlet.error.exception 会获取到异常对象,其他 key 获取的是空
例子
此例子是菜鸟教程中的案例,详见:
https://www.runoob.com/servlet/servlet-exception-handling.html
//导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
//扩展 HttpServlet 类
public class ErrorHandler extends HttpServlet {
// 处理 GET 方法请求的方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
Throwable throwable = (Throwable)request.getAttribute("javax.servlet.error.exception");
String requestUri = (String)request.getAttribute("javax.servlet.error.request_uri");
String message = (String)request.getAttribute("javax.servlet.error.message");
if (requestUri == null){
requestUri = "Unknown";
}
// 设置响应内容类型
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String title = "菜鸟教程 Error/Exception 信息";
String docType = "<!DOCTYPE html>\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n");
out.println("<h1>错误</h1>");
if (throwable == null && statusCode == null){
out.println("<h2>错误信息丢失</h2>");
out.println("请返回 <a href=\"" +
response.encodeURL("http://localhost:8080/") +
"\">主页</a>。");
}else if (statusCode != null) {
out.println("错误代码 : " + statusCode);
}else{
out.println("<h2>错误信息</h2>");
out.println("异常类型 : " + throwable.getClass( ).getName( ) + "</br></br>");
out.println("请求 URI: " + requestUri + "<br><br>");
out.println("异常信息: " + throwable.getMessage( ));
}
out.println("</body>");
out.println("</html>");
}
// 处理 POST 方法请求的方法
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
配置到 web.xml 中
类似配置错误页,使用 <error-page> 进行配置
根据 错误码 进行处理
在 web.xml 中,通过 error-code 元素进行配置
当 状态码,与 error-code 配置的状态码相匹配时,全局异常处理器 ErrorHandler 进行处理
如下:找不到资源时,就由 ErrorHandler 进行处理
<error-page>
<error-code>404</error-code>
<location>/ErrorHandler</location>
</error-page>
根据 异常类型 进行处理
在 web.xml 中,通过 exception-type 元素进行配置
当 业务Servlet 抛出异常类型,与 exception-type 配置的异常相匹配时,全局异常处理器 ErrorHandler 进行处理
如下:当抛出 IOException 异常时,就由 ErrorHandler 进行处理
<error-page>
<exception-type>java.io.IOException</exception-type >
<location>/ErrorHandler</location>
</error-page>
完整例子
<servlet>
<servlet-name>ErrorHandler</servlet-name>
<servlet-class>com.runoob.test.ErrorHandler</servlet-class>
</servlet>
<!-- servlet mappings -->
<servlet-mapping>
<servlet-name>ErrorHandler</servlet-name>
<url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/ErrorHandler</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type >
<location>/ErrorHandler</location>
</error-page>
参考:
https://blog.csdn.net/pzzzzzp/article/details/118880585
https://www.runoob.com/servlet/servlet-exception-handling.html