在编写程序的过程中,异常处理是绕不开的一步,这篇笔记主要记录我在Spring Boot程序中遇到的异常处理的情况。
主要用到@ControllerAdvice的尝试
首先,我们自定义一个异常类CommonException,代码如下
import lombok.Data;
@Data
public class CommonException extends RuntimeException {
private int code;
private String msg;
public CommonException(int code, String msg) {
this.code = code;
this.msg = msg;
}
}复制代码
这里用到了lombok注解省去set/get环节,类CommonException继承的是RuntimeException(要注意的是在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常。),可以在不声明的情况下抛出RuntimeException,即RuntimeException不需要自己写catch块处理掉。
而参数code和msg则是异常的重要组成部分,下面会提到
接下来,我们定义一个全局异常处理类
@Slf4j
@RestControllerAdvice
public class CommonExceptionHandler {
/**
* 全局异常捕捉处理
* @param ex
* @return
*/
@ExceptionHandler(value = Exception.class)
public Map errorHandler(HttpServletRequest req,Exception ex) {
Map map = new HashMap();
map.put("code", 100);
map.put("message", ex.getMessage());
map.put("url", req.getRequestURL());
map.put("params", req.getParameterMap());
log.error("发生未处理的异常={}",ex.getMessage(),ex);
return map;
}
/**
* 拦截捕捉自定义异常 MyException.class
* @param ex
* @return
*/
@ExceptionHandler(value = CommonException.class)
public Map myErrorHandler(HttpServletRequest req, CommonException ex) {
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("message", ex.getMsg());
map.put("url", req.getRequestURL());
map.put("params", req.getParameterMap());
return map;
}
}复制代码
在这里要注意我们要捕捉哪里的异常,并写在value中
@ExceptionHandler(value = CommonException.class)复制代码
此处捕捉我们自定义的异常
@ExceptionHandler(value = Exception.class)复制代码
此处捕捉全局异常
同时可以发现,我这里使用的是@RestControllerAdvice注解而不是@ControllerAdvice注解,原因很简单。这二者的区别类似于@RestController和@Controller的区别。用前者是为了在返回json数据时少写一个@ResponseBody注解
最后,我们在controller中使用异常处理
@RequestMapping("/login")
public Object login(String username,String pwd) throws Exception {
try {
userService.login(username,pwd);
}catch (Exception e){
log.error("用户登录异常={}",e.getMessage(),e);
throw new CommonException(500,"内部错误");
}
return userService.login(username,pwd);
}复制代码
我们要注意的是
log.error("用户登录异常={}",e.getMessage(),e);
throw new CommonException(500,"内部错误");复制代码
此处我加入了@Slf4j来作为log.error日志报错处理,第二行中500即为自定义的异常code,“内部错误”即为自定义的异常信息。二者可根据具体情况进行修改