前言
再项目中,我们新建项目的时候,都会对接口进行异常全局捕获管理,然后返回给前端!所以,如何快速的实现异常全局捕获就尤其重要!
基于springBoot实现全局异常捕获功能
package com.haoker.servicebase.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.haoker.result.R;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
/**
* 统一异常处理类,采用ControllerAdvice注解,注意拦截的内容默认包要处于扫描中才能生效。
*
*/
@ControllerAdvice
public class GlobalExceptionHandler implements RabbitTemplate.ConfirmCallback {
@Value("${spring.application.name}")
private String serverIdName;
@Value("${server.port}")
private String serverPort;
@Autowired
private RabbitTemplate rabbitTemplate;
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public R errorResult(HttpServletRequest request, Exception ex) throws UnknownHostException {
// 采用全局捕获异常 拦截系统中的错误,返回友好的提示给客户端
Map<String, String[]> parameterMap = request.getParameterMap();
StackTraceElement[] stackTrace = ex.getStackTrace();
StackTraceElement stackTraceElement = stackTrace[0];
// 转换成json
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(stackTraceElement));
// 新增参数内容
jsonObject.put("parameterContent", parameterMap);
// 新增错误日志
jsonObject.put("errorContent", ex.getMessage());
jsonObject.put("serviceId", serverIdName);
jsonObject.put("createTime", new Date());
jsonObject.put("messageId", UUID.randomUUID().toString().replace("-", ""));
// 获取我们的ip
jsonObject.put("serverIp", getServerAddres());
// 投递到MQ中
// try{
// sendMsg(jsonObject.toJSONString());
// }catch (Exception e){
// return R.error().message(ex.getMessage());
// }
return R.error().message(ex.getMessage());
}
/**
* 发送消息的方法
*/
public void sendMsg(String msgJson) {
// 设置生产者消息确认机制
this.rabbitTemplate.setMandatory(true);
this.rabbitTemplate.setConfirmCallback(this);
CorrelationData correlationData = new CorrelationData();
correlationData.setId(msgJson);
String orderExchange = "fanoutExceptionLogExchange";
rabbitTemplate.convertAndSend(orderExchange, null, msgJson, correlationData);
}
/**
* correlationData 投递失败回调的消息
*
* @param correlationData
* @param ack true 投递到MQ成功 如果是为false情况下 消息投递失败
* @param s
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String s) {
String msg = correlationData.getId();
if (!ack) {
System.out.println();
/*log.info("<<<往MQ投递消息失败>>>>:" + msg);*/
// 采用递归算法重试
sendMsg(msg);
return;
}
/*log.info("<<<往MQ投递消息成功>>>>:" + msg);*/
// 生产者投递多次还是is的情况下应该 人工记录
}
private String getServerAddres() throws UnknownHostException {
InetAddress ip4 = Inet4Address.getLocalHost();
return ip4.getHostAddress() + ":" + serverPort;
}
}
自定义异常捕获
1、添加自定义异常类
public class MyException extends RuntimeException {
private static final long serialVersionUID = 1L;
public MyException(String code, String msg) {
this.code = code;
this.msg = msg;
}
private String code;
private String msg;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
2、添加异常捕获处理
@ExceptionHandler(MyException.class)
@ResponseBody
public R errorResult(HttpServletRequest request, Exception ex) throws UnknownHostException {
// 采用全局捕获异常 拦截系统中的错误,返回友好的提示给客户端
Map<String, String[]> parameterMap = request.getParameterMap();
StackTraceElement[] stackTrace = ex.getStackTrace();
StackTraceElement stackTraceElement = stackTrace[0];
// 转换成json
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(stackTraceElement));
// 新增参数内容
jsonObject.put("parameterContent", parameterMap);
// 新增错误日志
jsonObject.put("errorContent", ex.getMessage());
jsonObject.put("serviceId", serverIdName);
jsonObject.put("createTime", new Date());
jsonObject.put("messageId", UUID.randomUUID().toString().replace("-", ""));
// 获取我们的ip
jsonObject.put("serverIp", getServerAddres());
// 投递到MQ中
// try{
// sendMsg(jsonObject.toJSONString());
// }catch (Exception e){
// return R.error().message(ex.getMessage());
// }
return R.error().message(ex.getMessage());
}
3、再controller中抛出异常
@RestController
@RequestMapping("/exce")
public class ExceptionController {
@RequestMapping("/api/v1/myexce")
public Object testMyException() {
throw new MyException("500", "my ext异常");
}
}