一,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,没有的话返回固定的友好提示:服务器繁忙。