spring boot 2.1.2.RELEASE,我的全局处理模板

注:使用lombok
ResponseResult.java ----- 通用返回体

import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/*************************************************************
 * 类:json串响应体
 * @author Jabwin
 *************************************************************
 */
@Data
@Accessors(chain = true)
public class ResponseResult<T> implements Serializable
{
    private String resultCode;
    private String msg;
    private transient T data;

    public ResponseResult(String resultCode, String msg)
    {
        this.resultCode = resultCode;
        this.msg = msg;
    }

    public ResponseResult(String resultCode, String msg, T data)
    {
        this.resultCode = resultCode;
        this.msg = msg;
        this.data = data;
    }

    public static <T> ResponseResult<T> build(String code, String msg, T data)
    {
        return new ResponseResult<>(code, msg,data);
    }
    public static ResponseResult build(String code, String msg)
    {
        return new ResponseResult<>(code, msg);
    }
    public static ResponseResult build()
    {
        return new ResponseResult<>(null, null);
    }
}

BaseController.java ----- Controller基类

/*************************************************************
 * 控制器基类:
 * @author Jabwin
 *************************************************************
 */
public abstract class BaseController
{

    /** 此次请求响应成功 */
    protected <T> ResponseResult<T> success(T data)
    {
        return new ResponseResult("200", "操作成功", data);
    }

    /** 此次请求响应成功 */
    protected ResponseResult success()
    {
        return ResponseResult.build("200", "操作成功");
    }
}

GlobalExceptionHandler.java ----- 全局异常处理

import com.xwj.ssp.templet.exception.ServiceException;
import com.xwj.ssp.templet.ResponseResult;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.validation.ConstraintViolationException;
import java.util.List;

/*************************************************************
 * 全局异常处理类
 * @author Jabwin
 *************************************************************
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler
{
    /** 返回码:参数错误 */
    public static final String RETURN_CODE_ARGUMENT_NOT_VALID = "40500";
    /** 返回码:请求方式错误 */
    public static final String RETURN_CODE_REQUEST_METHOD_FAIL = "40100";
    /** 返回码:远程调用失败 */
    public static final String RETURN_CODE_FEIGN_FAIL = "50100";

    /** 总异常处理 */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult handleException(Exception e)
    {
        log.error(e.getMessage());
        ResponseResult result = new ResponseResult<>("90000", "未知错误");
        log.info("\r\n==== 未处理异常 ==== 响应参数:{}", result);
        return result;
    }
    /** 请求方式异常处理 */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public ResponseResult handleException(HttpRequestMethodNotSupportedException e)
    {
        log.error(e.getMessage());
        ResponseResult result = new ResponseResult<>(RETURN_CODE_REQUEST_METHOD_FAIL, "请求方式错误");
        log.info("\r\n==== 请求方式异常 ==== 响应参数:{}", result);
        return result;
    }
    /** mybatis异常处理 */
    @ExceptionHandler(DataAccessException.class)
    @ResponseBody
    public ResponseResult handleDataAccessException(DataAccessException e)
    {
        log.error(e.getMessage());
        ResponseResult result = new ResponseResult<>("50000", "数据库访问错误");
        log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
        return result;
    }
    /** mybatis异常处理,数据重复插入 */
    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseBody
    public ResponseResult handleDataAccessException(DuplicateKeyException e)
    {
        log.error(e.getMessage());
        ResponseResult result = new ResponseResult<>("50000", "数据重复");
        log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
        return result;
    }
    /** mybatis异常处理,数据库连接超时 */
    @ExceptionHandler(QueryTimeoutException.class)
    @ResponseBody
    public ResponseResult handleDataAccessException(QueryTimeoutException e)
    {
        log.error(e.getMessage());
        ResponseResult result = new ResponseResult<>("50000", "数据连接超时");
        log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
        return result;
    }
    //*****************************************************************************************************
    /** Validated异常处理,对象 */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseResult handleException(MethodArgumentNotValidException e)
    {
        log.error(e.getMessage());
        BindingResult result = e.getBindingResult();
        final List<FieldError> fieldErrors = result.getFieldErrors();
        StringBuilder builder = new StringBuilder();
        for(FieldError error : fieldErrors)
        {
            builder.append(error.getDefaultMessage() + "; ");
        }
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, builder.toString());
        log.info("\r\n==== violation异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    /** validated异常处理,单个参数 */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResponseResult handleException(ConstraintViolationException e)
    {
        log.error(e.getMessage());
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, e.getMessage().replaceAll("^.*:\\s",""));
        log.info("\r\n==== violation异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    //*****************************************************************************************************
    /** requestParam异常处理,单个参数 */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public ResponseResult handleException(MissingServletRequestParameterException e)
    {
        log.error(e.getMessage());
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "缺少必须的请求参数");
        log.info("\r\n==== requestParam异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    /** requestParam异常处理,单个参数类型错误 */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public ResponseResult handleException(MethodArgumentTypeMismatchException e)
    {
        log.error(e.getMessage());
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "请求失败,请检查请求参数");
        log.info("\r\n==== requestParam异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    /** Bind异常处理,参数绑定错误 */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResponseResult handleException(BindException e)
    {
        log.error(e.getMessage());
        BindingResult result = e.getBindingResult();
        final List<FieldError> fieldErrors = result.getFieldErrors();
        StringBuilder builder = new StringBuilder();
        for(FieldError error : fieldErrors)
        {
            builder.append(error.getDefaultMessage() + "; ");
        }
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, builder.toString());
        log.info("\r\n==== 请求参数数据绑定异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    /** Bind异常处理,单个参数类型错误 */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public ResponseResult handleException(HttpMessageNotReadableException e)
    {
        log.error(e.getMessage());
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "请求失败,传入格式无法解析");
        log.info("\r\n==== 请求参数数据绑定异常 ==== 响应参数:{}", reResult);
        return reResult;
    }

    //****************************************************************************************************
    /** Feign异常处理,调用失败 */
    @ExceptionHandler(FeignException.class)
    @ResponseBody
    public ResponseResult handleException(FeignException e)
    {
        log.error(e.getMessage());
        ResponseResult reResult = new ResponseResult<>(RETURN_CODE_FEIGN_FAIL, "服务访问失败。");
        log.info("\r\n==== feign异常 ==== 响应参数:{}", reResult);
        return reResult;
    }
    //****************************************************************************************************
    /** service异常处理 */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public ResponseResult handleServiceException(ServiceException e)
    {
        ResponseResult result = new ResponseResult<>(e.getResultCode(), e.getMsg());
        log.info("\r\n==== " + e.getMethod() + " ==== 响应参数:{}", result);
        return result;
    }
}

ServiceException.java -----通用异常类

import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;

/*************************************************************
 * 异常类:服务
 * @author Jabwin
 *************************************************************
 */
@Data
@Accessors(chain = true)
public class ServiceException extends RuntimeException implements Serializable
{

    private String resultCode;
    private String msg;
    private String method;

    public ServiceException(String resultCode, String msg)
    {
        this.resultCode = resultCode;
        this.msg = msg;
    }
    /** 简单服务异常 */
    public static ServiceException simpleThrow(String message)
    {
        return new ServiceException("500", message);
    }
}

LogAspect.java ----- 切面打印日志

import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
/*************************************************************
 * 切面:为controller层整体出参入参打印日志
 * @author Jabwin
 *************************************************************
 */
@Aspect
@Component
public class LogAspect
{

    @Autowired
    private ObjectMapper objectMapper;
    private static final String ENTER = "\r\n";
    
    @Around("execution(public * *..controller.*Controller.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable
    {
        Long startTime = System.currentTimeMillis();
        Class targetClass = joinPoint.getTarget().getClass();//获取目标类
        Signature method = joinPoint.getSignature();//目标方法
        String methodName = method.getName();//获取目标类方法名称
        Object[] args = joinPoint.getArgs();//参数列表



        Field field = targetClass.getDeclaredField("log");
        if (field == null || !field.getType().equals(Logger.class)) return joinPoint.proceed();
        field.setAccessible(true);
        Logger logger = (Logger)field.get(Logger.class);
        try
        {
            StringBuilder argStr = new StringBuilder();
            for(Object o : args)
            {
                if (!argStr.toString().isEmpty()) argStr.append("; ");
                argStr.append(objectMapper.writeValueAsString(o));
            }
            logger.info(ENTER + "==== {} ==== 接入参数:{}", methodName, argStr);
            Object returnObj = joinPoint.proceed();
            Long exeTime = System.currentTimeMillis() - startTime;//执行时间
            logger.info(ENTER + "==== {} ==== 响应时间:{}ms,响应参数:{}" ,methodName, exeTime, objectMapper.writeValueAsString(returnObj));
            return returnObj;
        }
        catch (Exception e)
        {
            if (logger != null) logger.info(ENTER + "XXXX {} XXXX 抛出异常:【{}】",methodName , e.getClass().getName());
            throw e;
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容