参考文章:
https://blog.csdn.net/chinrui/article/details/71036544
https://blog.csdn.net/chenhaotao/article/details/78784493
http://www.cnblogs.com/java-zhao/archive/2016/08/13/5769018.html
大值思路:
通过使用@ControllerAdvice定义统一的异常处理类,可以不用在每个Controller中逐个定义异常处理方式
代码实现:
- 创建一个BizLogicException类,继承自Exception
package com.springcloud.blog.exception;
import java.io.Serializable;
import java.util.ArrayList;
import com.springcloud.blog.bean.SystemMessage;
/**
* 描述: 异常处理
* @author hyp
* @date 2018年7月22日21:36:34
* @version v0.1
*/
public class BizLogicException extends Exception implements Serializable {
private static final long serialVersionUID = -5458946175270060619L;
private ArrayList<SystemMessage> messageList = new ArrayList<SystemMessage>();
public ArrayList<SystemMessage> getMessageList() {
return messageList;
}
public void setMessageList(ArrayList<SystemMessage> messageList) {
this.messageList = messageList;
}
public BizLogicException(ArrayList<SystemMessage> messageList) {
super(messageList.get(0).getMessage());
this.messageList = messageList;
}
public BizLogicException(SystemMessage systemMessage) {
super(systemMessage.getMessage());
if(systemMessage != null) {
this.messageList.add(systemMessage);
}
}
}
然后就可以可以在代码中,可能会出现异常的地方进行异常抛出,不必捕获
throw new BizLogicException(new SystemMessage("error","系统出现异常"));
测试运行,然后在控制台打印出来错误信息,但是定义的错误信息却不能返回出去,因此需要定义一个类,进行全局的错误捕获
- 创建一个GlobalExceptionHandler类,增加@ControllerAdvice注解
package com.springcloud.blog.config;
import java.text.MessageFormat;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.springcloud.blog.bean.ServiceResponseBase;
import com.springcloud.blog.bean.SystemMessage;
import com.springcloud.blog.consts.CommonConsts;
import com.springcloud.blog.exception.BizLogicException;
import com.springcloud.blog.utils.Pub;
/**
* 描述:全局异常处理
* 参考地址:http://www.cnblogs.com/java-zhao/archive/2016/08/13/5769018.html
*
* @ControllerAdvice是controller的一个辅助类,最常用的就是作为全局异常处理的切面类
* @ControllerAdvice可以指定扫描范围
* @ControllerAdvice约定了几种可行的返回值,如果是直接返回model类的话,
* 需要使用@ResponseBody进行json转换 返回String,表示跳到某个view 返回modelAndView 返回model + @ResponseBody
* @author: 和彦鹏
* @date: 和2018年7月22日22:24:53
* @version:v0.1
*/
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 日志
*/
private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler//处理所有异常
@ResponseBody // 在返回自定义相应类的情况下必须有,这是@ControllerAdvice注解的规定
public ServiceResponseBase exceptionHandler(Exception e, HttpServletResponse response) {
ServiceResponseBase resp = new ServiceResponseBase();
if(e instanceof BizLogicException) {
BizLogicException bizLogicException = (BizLogicException)e;
resp.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
resp.setMessageList(bizLogicException.getMessageList());
}
// 验证出错
else if(e instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException)e;
BindingResult result = (BindingResult) methodArgumentNotValidException.getBindingResult();
if (result.hasErrors()) {
ServiceResponseBase serviceResponseBase = new ServiceResponseBase();
for (ObjectError error : result.getAllErrors()) {
Pub.addSystemMessage(error.getCodes()[0], error.getDefaultMessage(), serviceResponseBase);
}
resp.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
resp.setMessageList(serviceResponseBase.getMessageList());
}
}
//jacksonMapper转换出错
else if(e.getCause() instanceof InvalidFormatException) {
InvalidFormatException invalidFormatException = (InvalidFormatException)e.getCause();
ServiceResponseBase serviceResponseBase = new ServiceResponseBase();
// 字段[{0}]的值[{1}]不能转换成[{2}]类型
Pub.addSystemMessage(new SystemMessage("ClassCaseException",
MessageFormat.format("字段[{0}]的值[{1}]不能转换成[{2}]类型", new Object[]{
invalidFormatException.getPathReference()//字段
, invalidFormatException.getValue()//值
//类型
, invalidFormatException.getTargetType().getName()})), serviceResponseBase);
resp.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
resp.setMessageList(serviceResponseBase.getMessageList());
}
else if(e instanceof HttpRequestMethodNotSupportedException) {
resp.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
Pub.addSystemMessage("SERVER_ERROR", "访问资源有误,请确认资源路径。", resp);
}
else {
resp.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
Pub.addSystemMessage("SERVER_ERROR", "系统异常,请联系管理员!", resp);
}
log.error(e.getMessage(), e);
return resp;
}
}
贴上Pub类代码
package com.springcloud.blog.utils;
import java.util.ArrayList;
import java.util.List;
import com.github.pagehelper.Page;
import com.springcloud.blog.bean.PageControllerInfo;
import com.springcloud.blog.bean.ServiceResponseBase;
import com.springcloud.blog.bean.SystemMessage;
import com.springcloud.blog.consts.CommonConsts;
public class Pub {
public static void addSystemMessage(String key, String message, ServiceResponseBase responseDto) {
ArrayList<SystemMessage> systemMessages = responseDto.getMessageList();
if (systemMessages == null) {
systemMessages = new ArrayList<SystemMessage>();
}
SystemMessage systemMessage = new SystemMessage(key, message);
systemMessages.add(systemMessage);
responseDto.setMessageList(systemMessages);
responseDto.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
}
public static void addSystemMessage(SystemMessage message, ServiceResponseBase responseDto) {
ArrayList<SystemMessage> systemMessages = responseDto.getMessageList();
if (systemMessages == null) {
systemMessages = new ArrayList<SystemMessage>();
}
systemMessages.add(message);
responseDto.setMessageList(systemMessages);
responseDto.setResponseCode(CommonConsts.RESPONSE_CODE_WARNING);
}
public static <E> PageControllerInfo getPageControllerInfo(List<E> list) throws Exception {
if (list == null) {
throw new Exception("getPageControllerInfo方法的参数不能为空!");
}
if (!(list instanceof Page<?>)) {
return null;
}
Page<E> page = (Page<E>) list;
PageControllerInfo pageControllerInfo = new PageControllerInfo();
pageControllerInfo.setPageNum(page.getPageNum());
pageControllerInfo.setPageSize(page.getPageSize());
pageControllerInfo.setTotalRecordCount(page.getTotal());
pageControllerInfo.setTotalPages(page.getPages());
return pageControllerInfo;
}
}
这样,如果代码中如果有异常,则会把错误消息直接抛出来
{
"responseCode": "300",
"messageList": [
{
"key": "error",
"message": "系统出现异常"
}
],
"version": null
}