前言
再项目中,我们新建项目的时候,都会对接口进行异常全局捕获管理,然后返回给前端!所以,如何快速的实现异常全局捕获就尤其重要!
基于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注解,注意拦截的内容默认包要处于扫描中才能生效。**/@ControllerAdvicepublic class GlobalExceptionHandler implements RabbitTemplate.ConfirmCallback {@Value("${spring.application.name}")private String serverIdName;@Value("${server.port}")private String serverPort;@Autowiredprivate RabbitTemplate rabbitTemplate;@ExceptionHandler(RuntimeException.class)@ResponseBodypublic R errorResult(HttpServletRequest request, Exception ex) throws UnknownHostException {// 采用全局捕获异常 拦截系统中的错误,返回友好的提示给客户端Map<String, String[]> parameterMap = request.getParameterMap();StackTraceElement[] stackTrace = ex.getStackTrace();StackTraceElement stackTraceElement = stackTrace[0];// 转换成jsonJSONObject 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("-", ""));// 获取我们的ipjsonObject.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*/@Overridepublic 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)@ResponseBodypublic R errorResult(HttpServletRequest request, Exception ex) throws UnknownHostException {// 采用全局捕获异常 拦截系统中的错误,返回友好的提示给客户端Map<String, String[]> parameterMap = request.getParameterMap();StackTraceElement[] stackTrace = ex.getStackTrace();StackTraceElement stackTraceElement = stackTrace[0];// 转换成jsonJSONObject 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("-", ""));// 获取我们的ipjsonObject.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异常");}}
