1.自定义统一异常处理器
自定义Exception实现 HandlerExceptionResolver接口或继承AbstractHandlerExceptionResolver类
1.实现接口HandlerExceptionResolver
package com.jay.platform.exception.handler; import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import com.jay.platform.exception.AjaxException; import com.jay.platform.exception.BusinessException; /** * * @ClassName: ExceptionHandler * @Description: 统一异常处理 , 注意这里可以处理Controller层抛出的异常,但不处理Controller捕获的异常(Controller捕获的异常,这里不再处理) * @author Jay He * @date 2014年11月4日 上午10:22:11 * */ public class ExceptionHandler implements HandlerExceptionResolver { private static final Logger LOGGER = Logger .getLogger(ExceptionHandler.class); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { LOGGER.error(new Date().toLocaleString() + "异常信息", ex); if (ex instanceof NumberFormatException) { return new ModelAndView("exception/number"); } else if (ex instanceof NullPointerException) { return new ModelAndView("exception/null"); } else if (ex instanceof BusinessException) { return new ModelAndView("exception/business"); } else if (ex instanceof SocketTimeoutException || ex instanceof ConnectException) { try { response.getWriter().write("网络异常"); } catch (IOException e) { e.printStackTrace(); } return new ModelAndView("exception/net_error"); }else if(ex instanceof AjaxException){ System.out.println("-=-="); } return new ModelAndView("exception/exception"); } }
2.继承AbstractHandlerExceptionResolver类
package com.jay.platform.exception.handler; import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; import com.jay.platform.exception.AjaxException; import com.jay.platform.exception.BusinessException; /** * * @ClassName: ExceptionHandler * @Description: 统一异常处理 , 注意这里可以处理Controller层抛出的异常,但不处理Controller捕获的异常(Controller捕获的异常,这里不再处理) * @author Jay He * @date 2014年11月4日 上午10:22:11 * */ public class ExceptionHandler extends AbstractHandlerExceptionResolver{ private static final Logger LOGGER = Logger .getLogger(ExceptionHandler.class); @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { <pre name="code" class="java">LOGGER.error(new Date().toLocaleString() + "异常信息", ex); if (ex instanceof NumberFormatException) { return new ModelAndView("exception/number"); } else if (ex instanceof NullPointerException) { return new ModelAndView("exception/null"); } else if (ex instanceof BusinessException) { return new ModelAndView("exception/business"); } else if (ex instanceof SocketTimeoutException || ex instanceof ConnectException) { try { response.getWriter().write("网络异常"); } catch (IOException e) { e.printStackTrace(); } return new ModelAndView("exception/net_error"); }else if(ex instanceof AjaxException){ System.out.println("-=-="); } return new ModelAndView("exception/exception");
}}
在配置文件中添加自定义异常处理模块
<!-- Spring MVC的统一异常处理 --> <bean id="exceptionResolver" class="com.jay.platform.exception.handler.ExceptionHandler"/>
错误页面展示:
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error页面</title> </head> <body> <center> <h1>Error页面</h1><br> <h2>出错信息</h2> <br><br> 错误描述 <br> ${errorTips } <br><br> <br><br> 错误异常信息栈 <br><br> ${ex } </center> </body> </html>
eception.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Exception页面</title> </head> <body> <center> <h1>Exception页面</h1><br> <h2>模块开发中,请稍后。。。。。。</h2> </center> </body> </html>
2.基于@ControllerAdvice注解实现统一异常处理,可方便返回普通异常和Ajax异常信息
自定义Web层异常处理
WebExceptionHandler.java
package com.jay.platform.exception.handler; import java.io.IOException; import java.net.ConnectException; import java.net.SocketTimeoutException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.ServletRequestUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.servlet.ModelAndView; import com.jay.platform.exception.AjaxException; import com.jay.platform.utils.DateUtil; /** * @ClassName: WebExceptionHandler * @Description: Web层异常处理器, -- 这里可以根据不同的异常,写多个方法去处理, 可以处理跳转页面请求,跳到异常指定的错误页, * 也可以处理Ajax请求,根据不通过异常,在页面输出不同的提示信息 * operateExp : 处理普通请求 * operateExpAjax : 处理Ajax请求 * @author Jay He * @date 2015年5月27日 下午5:16:37 * */ @ControllerAdvice public class WebExceptionHandler { Logger logger = Logger.getLogger(WebExceptionHandler.class); /* * 如果抛出UnauthorizedException,将被该异常处理器截获来显示没有权限信息 */ @ExceptionHandler({ UnauthorizedException.class }) @ResponseStatus(HttpStatus.UNAUTHORIZED) public ModelAndView unauthenticatedException(NativeWebRequest request, UnauthorizedException e) { ModelAndView mv = new ModelAndView(); mv.addObject("exception", e); mv.setViewName("base/exception/unauthorized"); return mv; } /** * @Title: operateExp * @Description: 全局异常控制,记录日志 * 任何一个方法发生异常,一定会被这个方法拦截到。然后,输出日志。封装Map并返回给页面显示错误信息: * 特别注意:返回给页面错误信息只在开发时才使用,上线后,要把错误页面去掉,只打印log日志即可,防止信息外漏 * @param: @param ex * @param: @param request * @return: String * @throws: */ @ExceptionHandler(RuntimeException.class) public String operateExp(RuntimeException ex, HttpServletRequest request) { logger.error(ex.getMessage(), ex); logger.info("************* ------ 异常信息已记录(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********"); request.setAttribute("errorTips", ex.getMessage()); request.setAttribute("ex", ex); return "exception/error"; } /* * 记录Ajax异常日志,并将错误Ajax错误信息传递(回写)给前台展示, * 前台的jQuery的Ajax请求error中,可以打印错误提示信息 -- data.responseText : 这里即是后台传递的错误提示 * eg: * $.ajax({ type : 'get', dataType : "json", url : ctx + '/test/test', accept:"application/json", success : function(data) { console.log(data); }, error : function(data, errorThrown) { console.log(data); alert("error" + data.responseText); } }); */ @ExceptionHandler(AjaxException.class) public void operateExpAjax(AjaxException ex, HttpServletResponse response) throws IOException { logger.error(ex.getMessage(), ex); logger.info("************* ------ 异常信息已记录(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********"); //将Ajax异常信息回写到前台,用于页面的提示 response.getWriter().write("sorry,Ajax请求出错!!!"); } @ExceptionHandler(ConnectException.class) public void operateExpNetException(ConnectException ex, HttpServletResponse response) throws IOException { logger.error(ex.getMessage(), ex); logger.info("************* ------ 异常信息已记录(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********"); //将Ajax异常信息回写到前台,用于页面的提示 response.getWriter().write("sorry,网络连接出错!!!"); } }
异常测试
package com.jay.platform.controller.test; import java.net.ConnectException; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.jay.platform.annotation.AjaxExceptionHandler; import com.jay.platform.exception.AjaxException; @Component @Controller() @RequestMapping("exception") public class ExceptionHandlerTestController { @RequestMapping("test") public String getIt(){ return "exception/test/test"; } @RequestMapping(value="/common",method=RequestMethod.GET) public Map<String, Object> commonExcetion() throws RuntimeException{ Map<String, Object> map = new HashMap<String, Object>(); int i=10; if(i==10){ throw new RuntimeException("运行时异常"); } return map; } @AjaxExceptionHandler(tips="试一把", description="哈啊") @RequestMapping(value="/ajax/net",method=RequestMethod.GET) @ResponseBody public Map<String, Object> AjaxConnectionExcetion() throws ConnectException{ Map<String, Object> map = new HashMap<String, Object>(); int i=10; if(i==10){ throw new ConnectException("测试 网络连接 异常"); } return map; } @RequestMapping(value="/ajax/common",method=RequestMethod.GET) @ResponseBody public Map<String, Object> AjaxExcetion() throws AjaxException{ Map<String, Object> map = new HashMap<String, Object>(); int i=10; if(i==10){ throw new AjaxException("测试Ajax异常"); } return map; } }
前台页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <%@ include file="../../common/meta.jsp"%> <script src="${jqueryCtxPath }/jquery-ui-1.11.2.custom/jquery-ui.min.js"></script> <link href="${jqueryCtxPath }/jquery-ui-1.11.2.custom/jquery-ui.min.css" rel="stylesheet" type="text/css" /> <link href="${jqueryCtxPath }/jquery-ui-1.11.2.custom/jquery-ui.theme.min.css" rel="stylesheet" type="text/css" /> </head> <body class="index-main"> <button id="test"><a href="http://localhost:8080/JayPlatform/exception/common">普通的异常处理测试</a></button> <button id="test1">网络连接异常的Ajax测试</button> <button id="test2">普通异常的Ajax测试</button> <script type="text/javascript"> $(document).ready(function() { $("#test1").click(function(){ $.ajax({ type : 'get', dataType : "json", url : ctx + '/exception/ajax/net', accept:"application/json", success : function(data) { console.log(data); }, error : function(data, errorThrown) { console.log(data); alert("error" + data.responseText); } }); }); $("#test2").click(function(){ $.ajax({ type : 'get', dataType : "json", url : ctx + '/exception/ajax/common', accept:"application/json", success : function(data) { console.log(data); }, error : function(data, errorThrown) { console.log(data); alert("error" + data.responseText); } }); }); }); </script> </body> </html>
页面结果演示
时间: 2024-10-08 19:22:10