一,springMVC自定义异常的处理方式
异常抛到Controller集中统一处理:
controller中出现异常0/1
1 @Controller 2 @RequestMapping("/test") 3 public class TestController { 4 5 6 /** 7 * 返回值的前缀: 加上前缀 视图解析器不会再拼接前缀和后缀 8 * redirect: 重定向 9 * forward: 请求转发 10 * @return 11 */ 12 @RequestMapping("/testString") 13 public String testString(){ 14 System.out.println(1/0); 15 return "redirect:testModelAndView"; 16 } 17 18 19 20 21 22 23 }
异常处理类(解析异常resolve)
指定一个返回给用户的友好提示信息
指定一个跳转的error.jsp
程序员还能自己在控制台看什么异常
ex.printStackTrace();
@Component public class MyHandlerException implements HandlerExceptionResolver { /** * 解析异常 * @param request 请求对象 * @param response 响应 * @param handler 处理器 * @param ex 捕获到的异常对象 * @return 模型和视图对象 */ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ex.printStackTrace(); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message","系统错误,请联系管理员!!"); modelAndView.setViewName("error"); return modelAndView; } }
spring-mvc.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context.xsd 10 http://www.springframework.org/schema/mvc 11 http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 12 <!--开启注解扫描--> 13 <context:component-scan base-package="com.example"></context:component-scan> 14 15 <!--视图解析器--> 16 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 17 <property name="prefix" value="/WEB-INF/"></property> 18 <property name="suffix" value=".jsp"></property> 19 </bean> 20 <!--mvc注解驱动: 自动加载了处理映射器处理适配器--> 21 <mvc:annotation-driven></mvc:annotation-driven> 22 </beans>
error.jsp在WEB-INF中
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${message}
</body>
</html>
二,springcloud自定义异常的处理方式
问题背景
代码冗余,try-catch太多不合适。
用户体验不好例如用户操作返回‘’操作失败‘’,不清楚具体是什么异常
解决
所有异常由全局异常处理器捕获(@ControllerAdvice),捕获后分两种情况:
1.自定义异常(CustomerException)不应继承Exception,因为对代码有侵入性,还要继续抛,所以继承RunTimeException,
2.不可预知异常系统级别(空指针,连接超时。。。),异常类当做key,value是友好信息。
若查询的异常类没在map返回特定的信息,若异常类在map中的key存在,则返回value提示。
(一)自定义异常例子
执行顺序1-》2中抛出了一个4CustomerException类-》被3抓住,3中的特定handler处理此异常,获取异常信息,返回给用户特定信息。
1异常处
ExceptionCast.cast(Code.EXIT)。
2ExceptionCast类(异常抛出类)和
3ExceptionCatch(抓取类)
1 public class ExceptionCast { 2 public static void cast(ResultCode resultCode){ 3 throw new CustomerException(resultCode); 4 5 } 6 7 8 }
1 @ControllerAdvice 2 @Slf4j 3 public class ExceptionCatch { 4 @ExceptionHandler(CustomerException.class) 5 public ResponseResult customerException(CustomerException customerException){ 6 7 ResultCode resultCode = customerException.getResultCode(); 8 ResponseResult responseResult = new ResponseResult(resultCode); 9 return responseResult; 10 }
4CustomerException类(抛出的异常类)
public class CustomerException extends RuntimeException { private ResultCode resultCode; public ResultCode getResultCode(){ return resultCode; } public CustomerException(ResultCode resultCode){ super("错误代码"+resultCode.code()+"错误信息:"+resultCode.message()); this.resultCode =resultCode; } }
(二)系统级别的例子
抓取不可预知的异常,信息用log输出,
@Slf4j
后期方便定位问题,info。warning,error日志的常见级别
1 @ControllerAdvice 2 @Slf4j 3 public class ExceptionCatch { 4 5 @ExceptionHandler(Exception.class) 6 public ResponseResult exception(Exception exception){ 7 log.error(exception.getMessage()); 8 return null; 9 10 } 11 12 }
特定异常添加到特定map中(谷歌提供的)
ImmutableMap
//全局异常抓取类 @ControllerAdvice //增强controller @Slf4j public class ExceptionCatch { //ImmutableMap 线程安全,声明之后内容不可变 private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS; protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder(); //抓取自定义异常(可预知异常) @ExceptionHandler(CustomerException.class) @ResponseBody public ResponseResult customerException(CustomerException customerException){ //给用户返回友好信息 ResultCode resultCode = customerException.getResultCode(); ResponseResult responseResult = new ResponseResult(resultCode); return responseResult; } //抓取不可预知异常 @ExceptionHandler(Exception.class) @ResponseBody public ResponseResult exception(Exception exception){ log.error(exception.getMessage()); if (EXCEPTIONS == null){ EXCEPTIONS = builder.build(); } ResultCode resultCode = EXCEPTIONS.get(exception.getClass()); if (resultCode == null){ return new ResponseResult(CommonCode.SERVER_ERROR); }else{ return new ResponseResult(resultCode); } } static { builder.put(HttpMessageNotReadableException.class, CommonCode.INVALIDATE_PARAMS); } }
从map中找,有,返回key对应的value,没有的话返回固定的友好提示:服务器繁忙。