搭建SpringBoot(二) 自定义返回对象,自定义全局异常

项目源代码GitHub地址

定义返回对象类型

定义枚举类返回信息

需要实现枚举类的get方法

package cn.jijl.mist.common.result;

import lombok.Getter;

/**
 * @Author: liujiebang
 * @Description: 自定义参数枚举
 * @Date: 2018/7/2 16:54
 **/
@Getter
public enum ResultEnum {


    CODE_1(1, "操作成功!"),
    CODE_2(2, "操作失败!"),
    CODE_401(401, "账号或者密码错误!"),
    CODE_403(403, "没有获取授权!"),
    CODE_404(404, "找不到该路径!"),
    CODE_405(405, "请求方式错误!"),
    CODE_406(406, "Not Acceptable"),
    CODE_415(415, "请求参数格式错误!"),
    CODE_500(500, "服务器出错了,请联系后台开发人员!"),
    CODE_9999(9999, "服务器无法处理请求!");

    private Integer code;

    private String msg;

    ResultEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}


定义返回对象的格式

返回对象需要序列化,并且实现get set方法 否则返回时会报错
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver | Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class cn.jijl.mist.common.result.ResultView]

package cn.jijl.mist.common.result;

import lombok.Data;

import java.io.Serializable;
/**
 * @Author jijl
 * @Description: RrestFul自定义响应类
 * @Date 14:29 2019/10/27
 * @Param 
 * @return 
 **/
@Data
public class ResultView implements Serializable {

    private Integer code;

    private String msg;

    private Object data;

    private long time;

    public static ResultView ok() {
        return new ResultView();
    }

    public static ResultView ok(Object data) {
        return new ResultView(data);
    }

    public static ResultView error(ResultEnum resultEnum) {
        return new ResultView(resultEnum.getCode(), resultEnum.getMsg());
    }

    public static ResultView error(ResultEnum resultEnum, String errMsg) {
        return new ResultView(resultEnum.getCode(), errMsg);
    }

    public static ResultView error(Integer code, String errMsg) {
        return new ResultView(code, errMsg);
    }

    public static ResultView error(String errMsg) {
        return new ResultView(errMsg);
    }

    private ResultView() {
        this.code = ResultEnum.CODE_1.getCode();
        this.msg = ResultEnum.CODE_1.getMsg();
    }

    private ResultView(Object data) {
        this.data = data;
        this.code = ResultEnum.CODE_1.getCode();
        this.msg = ResultEnum.CODE_1.getMsg();
        this.time = System.currentTimeMillis();
    }

    private ResultView(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        this.time = System.currentTimeMillis();
    }

    private ResultView(String errMsg) {
        this.code = ResultEnum.CODE_2.getCode();
        this.msg = ResultEnum.CODE_2.getMsg() + errMsg;
        this.time = System.currentTimeMillis();
    }
}

测试

package cn.jijl.mist.modules.controller;


import cn.jijl.mist.common.result.ResultView;
import cn.jijl.mist.modules.entity.SysLog;
import cn.jijl.mist.modules.service.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * 系统日志表 前端控制器
 * </p>
 *  * @author jijl
 * @since 2019-10-25
 */
@Slf4j
@RestController
@RequestMapping("/sys-log")
public class SysLogController {
    @Autowired
    private ISysLogService iSysLogService;

    /**
     * @Author jijl
     * @Description: 测试
     * @Date 14:30 2019/10/27
     * @Param [id]
     * @return cn.jijl.mist.common.result.ResultView
     **/
    @GetMapping("/test")
    public ResultView get(String id) {
        SysLog sysLog = iSysLogService.getById(id);
        log.info("测试{}", sysLog);
        return ResultView.ok(sysLog);
    }
}
  • 控制台打印
 Consume Time:7 ms 2019-10-27 14:32:23
 Execute SQL:SELECT logid,errormessage,controller,method,ip,params,url,logtype,ctime,time,operation,username FROM sys_log WHERE logid='66' 

2019-10-27 14:32:23 | INFO  | http-nio-9001-exec-8 | cn.jijl.mist.modules.controller.SysLogController | 测试SysLog(logid=66, logtype=1, username=null, operation=null, method=null, params=null, controller=null, url=null, ip=null, time=null, errormessage=null, ctime=Sat Oct 26 04:16:00 CST 2019)

  • 返回实例
    在这里插入图片描述

自定义全局异常

定义前后区别

  • 定义之前若报错
    在这里插入图片描述
  • 定义之后若报错
    在这里插入图片描述

可以看出返回的json对象与前面定义的格式是一致的有利于前端提示信息,而且避免我们每个controller都去捕获异常定义格式

全局异常定义类创建

package cn.jijl.mist.common.exception;

import cn.jijl.mist.common.result.ResultEnum;
import cn.jijl.mist.common.result.ResultView;
import cn.jijl.mist.common.utils.IdentityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author jijl
 * @Description: 全局异常定义
 * @Date 14:52 2019/10/27
 * @Param 
 * @return 
 **/
@Slf4j
@RestController
public class ErController implements ErrorController {

    private static final String ERROR_PATH = "/error";

    @RequestMapping(value = ERROR_PATH)
    public ResultView handleError(HttpServletResponse response, HttpServletRequest request) {
        String ip = IdentityUtil.getRemoteHost(request);
        log.info("请求错误:{}", response.getStatus());
        log.info("请求IP是:{}", ip);
        log.info(response.getStatus() + "异常");
        if (response.getStatus() == ResultEnum.CODE_401.getCode()) {
            return ResultView.error(ResultEnum.CODE_401);
        } else if (response.getStatus() == ResultEnum.CODE_403.getCode()) {
            return ResultView.error(ResultEnum.CODE_403);
        } else if (response.getStatus() == ResultEnum.CODE_404.getCode()) {
            return ResultView.error(ResultEnum.CODE_404);
        } else if (response.getStatus() == ResultEnum.CODE_405.getCode()) {
            return ResultView.error(ResultEnum.CODE_405);
        } else if (response.getStatus() == ResultEnum.CODE_406.getCode()) {
            return ResultView.error(ResultEnum.CODE_406);
        } else if (response.getStatus() == ResultEnum.CODE_415.getCode()) {
            return ResultView.error(ResultEnum.CODE_415);
        } else if (response.getStatus() == ResultEnum.CODE_500.getCode()) {
            return ResultView.error(ResultEnum.CODE_500);
        }
        return ResultView.error(ResultEnum.CODE_9999);
    }


    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}

 

Controller异常捕获类

package cn.jijl.mist.common.exception;


import cn.jijl.mist.common.result.ResultEnum;
import cn.jijl.mist.common.result.ResultView;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Iterator;
import java.util.Set;


/**
 * @Author: liujiebang
 * @Description: Controller异常捕获类
 * @Date: 2018/7/2 16:51
 **/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 自定义全局异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public ResultView myExceptionHandler(MyException e) {
        ResultView resultView = ResultView.error(e.getResultEnum(), e.getMessage());
        return errorResponse(resultView);
    }

    /**
     * 授权异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthException.class)
    @ResponseBody
    public ResultView authExceptionHandler(AuthException e) {
        ResultView resultView = ResultView.error(e.getResultEnum(), e.getMessage());
        return resultView;
    }


    /**
     * 获取bindingResult中的错误信息
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResultView bindExceptionHandler(BindException e) {
        FieldError fieldError = e.getFieldError();
        StringBuilder sb = new StringBuilder();
        String errorMsg = fieldError.getDefaultMessage();
        sb.append(ResultEnum.CODE_2.getMsg()).append(errorMsg);
        ResultView resultView = ResultView.error(ResultEnum.CODE_2.getCode(), sb.toString());
        return resultView;
    }


    /**
     * 请求参数类型不匹配
     *
     * @param e
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseBody
    public ResultView typeMismatchExceptionHandler(TypeMismatchException e) {
        ResultView resultView = ResultView.error(ResultEnum.CODE_400.getCode(), "参数类型不匹配,参数" + e.getPropertyName() + "类型应该为" + e.getRequiredType());
        return resultView;
    }

    /**
     * 请求参数个数不匹配
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseBody
    public ResultView missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
        ResultView resultView = ResultView.error(ResultEnum.CODE_400.getCode(), "缺少必要参数,参数名称为" + e.getParameterName());
        return resultView;
    }

    /**
     * 请求方式错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public ResultView httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException e) {
        ResultView resultView = ResultView.error(ResultEnum.CODE_405);
        return resultView;
    }

    /**
     * 返回解析错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    @ResponseBody
    public ResultView httpMediaTypeNotAcceptabledExceptionHandler(HttpMediaTypeNotAcceptableException e) {
        ResultView resultView = ResultView.error(ResultEnum.CODE_406);
        return resultView;
    }

    /**
     * Violation 参数校验异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResultView constraintViolationExceptionHandler(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
        StringBuffer sb = new StringBuffer(ResultEnum.CODE_2.getMsg());
        while (iterator.hasNext()) {
            ConstraintViolation<?> cvl = iterator.next();
            sb.append(",");
            sb.append(cvl.getMessageTemplate());
            break;
        }
        ResultView resultView = ResultView.error(ResultEnum.CODE_2.getCode(), sb.toString());
        return resultView;
    }


    /**
     * 默认异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultView defaultErrorHandler(Exception e) {
        ResultView resultView = ResultView.error(ResultEnum.CODE_500);
        return resultView;
    }



    /**
     * 集成结果打印
     *
     * @param resultView
     * @return
     */
    private ResultView errorResponse(ResultView resultView) {
        String json = JSONObject.toJSONString(resultView);
        log.error("返回结果 = {}", json);
        return resultView;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值