平时开发过程中,无可避免咱们须要解决各类异样,所以这里咱们在公共模块中自定义对立异样,Spring Boot 提供 @RestControllerAdvice 注解对立异样解决,咱们在GitEgg_Platform中新建gitegg-platform-boot子工程,此工程次要用于Spring Boot相干性能的自定义及扩大。
1、批改gitegg-platform-boot的pom.xml,增加spring-boot-starter-web和swagger依赖,设置optional为true,让这个包在我的项目之间依赖不传递。

        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>            <optional>true</optional>        </dependency>        <dependency>            <groupId>com.gitegg.platform</groupId>            <artifactId>gitegg-platform-swagger</artifactId>            <optional>true</optional>        </dependency>

2、自定义通用响应音讯类,Result和PageResult,一个是一般响应音讯,一个是分页响应音讯。
Result类:

package com.gitegg.platform.boot.common.base;import com.gitegg.platform.boot.common.enums.ResultCodeEnum;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.*;/** * @ClassName: Result * @Description: 自定义通用响应类 * @author GitEgg * @date 2020年09月19日 下午9:24:50 */@ApiModel(description = "通用响应类")@Getter@ToStringpublic class Result<T> {    @ApiModelProperty(value = "是否胜利", required = true)    private boolean success;        @ApiModelProperty(value ="响应代码", required = true)    private int code;    @ApiModelProperty(value ="提示信息", required = true)    private String msg;    @ApiModelProperty(value ="响应数据")    private T data;        /**     *      * @param code     * @param data     * @param msg     */    private Result(int code, T data, String msg) {        this.success = ResultCodeEnum.SUCCESS.code == code;        this.code = code;        this.msg = msg;        this.data = data;    }    /**     *      * @param resultCodeEnum     */    private Result(ResultCodeEnum resultCodeEnum ) {        this(resultCodeEnum.code, null, resultCodeEnum.msg);    }    /**     *      * @param resultCodeEnum     * @param msg     */    private Result(ResultCodeEnum resultCodeEnum , String msg) {        this(resultCodeEnum, null, msg);    }    /**     *      * @param resultCodeEnum     * @param data     */    private Result(ResultCodeEnum resultCodeEnum , T data) {        this(resultCodeEnum, data, resultCodeEnum.msg);    }    /**     *      * @param resultCodeEnum     * @param data     * @param msg     */    private Result(ResultCodeEnum resultCodeEnum , T data, String msg) {        this(resultCodeEnum.code, data, msg);    }    /**     *      *     * @param data 数据     * @param <T>  T 响应数据     * @     */    public static <T> Result<T> data(T data) {        return data(data, ResultCodeEnum.SUCCESS.msg);    }    /**     *      *     * @param data 数据     * @param msg  音讯     * @param <T>  T 响应数据     * @     */    public static <T> Result<T> data(T data, String msg) {        return data(ResultCodeEnum.SUCCESS.code, data, msg);    }    /**     *      *     * @param code 状态码     * @param data 数据     * @param msg  音讯     * @param <T>  T 响应数据     * @     */    public static <T> Result<T> data(int code, T data, String msg) {        return new Result<>(code, data, msg);    }    /**     * 返回Result     *     * @param      * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> success() {        return new Result<>(ResultCodeEnum.SUCCESS);    }        /**     * 返回Result     *     * @param msg 音讯     * @param <T> T 响应数据     * @返回Result     */    public static <T> Result<T> success(String msg) {        return new Result<>(ResultCodeEnum.SUCCESS, msg);    }    /**     * 返回Result     *     * @param      * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> success(ResultCodeEnum resultCodeEnum ) {        return new Result<>(resultCodeEnum);    }    /**     * 返回Result     *     * @param      * @param msg   提示信息     * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> success(ResultCodeEnum resultCodeEnum , String msg) {        return new Result<>(resultCodeEnum, msg);    }        /**     * 返回Result     *     * @param <T> T 响应数据     * @返回Result     */    public static <T> Result<T> error() {        return new Result<>(ResultCodeEnum.ERROR, ResultCodeEnum.ERROR.msg);    }    /**     * 返回Result     *     * @param msg 音讯     * @param <T> T 响应数据     * @返回Result     */    public static <T> Result<T> error(String msg) {        return new Result<>(ResultCodeEnum.ERROR, msg);    }    /**     * 返回Result     *     * @param code 状态码     * @param msg  音讯     * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> error(int code, String msg) {        return new Result<>(code, null, msg);    }    /**     * 返回Result     *     * @param      * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> error(ResultCodeEnum resultCodeEnum ) {        return new Result<>(resultCodeEnum);    }    /**     * 返回Result     *     * @param      * @param msg   提示信息     * @param <T>  T 响应数据     * @返回Result     */    public static <T> Result<T> error(ResultCodeEnum resultCodeEnum , String msg) {        return new Result<>(resultCodeEnum, msg);    }        /**     *      * @param <T>     * @param flag     * @return     */    public static <T> Result<T> result(boolean flag) {        return flag ? Result.success("操作胜利") : Result.error("操作失败");    }}

PageResult类:

package com.gitegg.platform.boot.common.base;import java.util.List;import com.gitegg.platform.boot.common.enums.ResultCodeEnum;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;/** * @ClassName: PageResult * @Description: 通用分页返回 * @author GitEgg * @date * @param <T> */@Data@ApiModel("通用分页响应类")public class PageResult<T> {    @ApiModelProperty(value = "是否胜利", required = true)    private boolean success;    @ApiModelProperty(value ="响应代码", required = true)    private int code;    @ApiModelProperty(value ="提示信息", required = true)    private String msg;    @ApiModelProperty(value ="总数量", required = true)    private long count;    @ApiModelProperty(value ="分页数据")    private List<T> data;    public PageResult(long total, List<T> rows) {        this.count = total;        this.data = rows;        this.code = ResultCodeEnum.SUCCESS.code;        this.msg = ResultCodeEnum.SUCCESS.msg;    }}

3、自定义通用响应音讯枚举类ResultCodeEnum。

package com.gitegg.platform.boot.common.enums;/** * @ClassName: ResultCodeEnum * @Description: 自定义返回码枚举 * @author GitEgg * @date 2020年09月19日 下午11:49:45 */public enum ResultCodeEnum {    /**     * 胜利     */    SUCCESS(200, "操作胜利"),    /**     * 零碎谬误     */    ERROR(500, "零碎谬误"),    /**     * 操作失败     */    FAILED(101, "操作失败"),    /**     * 未登录/登录超时     */    UNAUTHORIZED(102, "登录超时"),    /**     * 参数谬误     */    PARAM_ERROR(103, "参数谬误"),    /**     * 参数谬误-已存在     */    INVALID_PARAM_EXIST(104, "申请参数已存在"),    /**     * 参数谬误     */    INVALID_PARAM_EMPTY(105, "申请参数为空"),    /**     * 参数谬误     */    PARAM_TYPE_MISMATCH(106, "参数类型不匹配"),    /**     * 参数谬误     */    PARAM_VALID_ERROR(107, "参数校验失败"),    /**     * 参数谬误     */    ILLEGAL_REQUEST(108, "非法申请"),    /**     * 验证码谬误     */    INVALID_VCODE(204, "验证码谬误"),    /**     * 用户名或明码谬误     */    INVALID_USERNAME_PASSWORD(205, "账号或明码谬误"),    /**     *     */    INVALID_RE_PASSWORD(206, "两次输出明码不统一"),    /**     * 用户名或明码谬误     */    INVALID_OLD_PASSWORD(207, "旧明码谬误"),    /**     * 用户名反复     */    USERNAME_ALREADY_IN(208, "用户名已存在"),    /**     * 用户不存在     */    INVALID_USERNAME(209, "用户名不存在"),    /**     * 角色不存在     */    INVALID_ROLE(210, "角色不存在"),    /**     * 角色不存在     */    ROLE_USED(211, "角色应用中,不可删除"),    /**     * 没有权限     */    NO_PERMISSION(403, "以后用户无该接口权限");    public int code;    public String msg;    ResultCodeEnum(int code, String msg) {        this.code = code;        this.msg = msg;    }    public int getCode() {        return code;    }    public void setCode(int code) {        this.code = code;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }}

4、自定义异样类BusinessException和SystemException

package com.gitegg.platform.boot.common.exception;import com.gitegg.platform.boot.common.enums.ResultCodeEnum;import lombok.AllArgsConstructor;import lombok.Data;import lombok.Getter;import lombok.Setter;/** * @ClassName: BusinessException * @Description: 业务解决异样 * @author GitEgg * @date */@Getter@Setterpublic class BusinessException extends RuntimeException {    private int code;    private String msg;    public BusinessException() {        this.code = ResultCodeEnum.FAILED.code;        this.msg = ResultCodeEnum.FAILED.msg;    }    public BusinessException(String message) {        this.code = ResultCodeEnum.FAILED.code;        this.msg = message;    }    public BusinessException(int code, String msg) {        this.code = code;        this.msg = msg;    }    public BusinessException(Throwable cause) {        super(cause);    }    public BusinessException(String message, Throwable cause) {        super(message, cause);    }}
package com.gitegg.platform.boot.common.exception;import com.gitegg.platform.boot.common.enums.ResultCodeEnum;import lombok.Getter;/** * @ClassName: SystemException * @Description: 零碎解决异样 * @author GitEgg * @date */@Getterpublic class SystemException extends RuntimeException {    private int code;    private String msg;    public SystemException() {        this.code = ResultCodeEnum.ERROR.code;        this.msg = ResultCodeEnum.ERROR.msg;    }    public SystemException(String message) {        this.code = ResultCodeEnum.ERROR.code;        this.msg = message;    }    public SystemException(int code, String msg) {        this.code = code;        this.msg = msg;    }    public SystemException(Throwable cause) {        super(cause);    }    public SystemException(String message, Throwable cause) {        super(message, cause);    }}

5、自定义对立异样解决类GitEggControllerAdvice.java

package com.gitegg.platform.boot.common.advice;import com.gitegg.platform.boot.common.base.Result;import com.gitegg.platform.boot.common.enums.ResultCodeEnum;import com.gitegg.platform.boot.common.exception.BusinessException;import com.gitegg.platform.boot.common.exception.SystemException;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.ui.Model;import org.springframework.web.HttpMediaTypeNotAcceptableException;import org.springframework.web.HttpMediaTypeNotSupportedException;import org.springframework.web.HttpRequestMethodNotSupportedException;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.MissingPathVariableException;import org.springframework.web.bind.MissingServletRequestParameterException;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;import org.springframework.web.servlet.NoHandlerFoundException;import javax.annotation.PostConstruct;import javax.servlet.http.HttpServletRequest;import javax.validation.ConstraintViolationException;@Slf4j@RestControllerAdvicepublic class GitEggControllerAdvice {    /**     * 服务名     */    @Value("${spring.application.name}")    private String serverName;    /**     * 微服务零碎标识     */    private String errorSystem;    @PostConstruct    public void init() {        this.errorSystem = new StringBuffer()                .append(this.serverName)                .append(": ").toString();    }    /**     * 利用到所有@RequestMapping注解办法,在其执行之前初始化数据绑定器     */    @InitBinder    public void initBinder(WebDataBinder binder) {    }    /**     * 把值绑定到Model中,使全局@RequestMapping能够获取到该值     */    @ModelAttribute    public void addAttributes(Model model) {    }    /**     * 全局异样捕获解决     */    @ExceptionHandler(value = {Exception.class})    public Result handlerException(Exception exception, HttpServletRequest request) {        log.error("申请门路uri={},零碎外部出现异常:{}", request.getRequestURI(), exception);        Result result = Result.error(ResultCodeEnum.ERROR, errorSystem + exception.toString());        return result;    }    /**     * 非法申请异样     */    @ExceptionHandler(value = {            HttpMediaTypeNotAcceptableException.class,            HttpMediaTypeNotSupportedException.class,            HttpRequestMethodNotSupportedException.class,            MissingServletRequestParameterException.class,            NoHandlerFoundException.class,            MissingPathVariableException.class,            HttpMessageNotReadableException.class    })    public Result handlerSpringAOPException(Exception exception) {        Result result = Result.error(ResultCodeEnum.ILLEGAL_REQUEST, errorSystem + exception.getMessage());        return result;    }    /**     * 非法申请异样-参数类型不匹配     */    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)    public Result handlerSpringAOPException(MethodArgumentTypeMismatchException exception) {        Result result = Result.error(ResultCodeEnum.PARAM_TYPE_MISMATCH, errorSystem + exception.getMessage());        return result;    }    /**     * 非法申请-参数校验     */    @ExceptionHandler(value = {MethodArgumentNotValidException.class})    public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {        //获取异样字段及对应的异样信息        StringBuffer stringBuffer = new StringBuffer();        methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()                .map(t -> t.getField()+"=>"+t.getDefaultMessage()+" ")                .forEach(e -> stringBuffer.append(e));        String errorMessage = stringBuffer.toString();        Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);        return result;    }    /**     * 非法申请异样-参数校验     */    @ExceptionHandler(value = {ConstraintViolationException.class})    public Result handlerConstraintViolationException(ConstraintViolationException constraintViolationException) {        String errorMessage = constraintViolationException.getLocalizedMessage();        Result result = Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);        return result;    }    /**     * 自定义业务异样-BusinessException     */    @ExceptionHandler(value = {BusinessException.class})    public Result handlerCustomException(BusinessException exception) {        String errorMessage = exception.getMsg();        Result result = Result.error(exception.getCode(), errorSystem + errorMessage);        return result;    }    /**     * 自定义零碎异样-SystemException     */    @ExceptionHandler(value = {SystemException.class})    public Result handlerCustomException(SystemException exception) {        String errorMessage = exception.getMsg();        Result result = Result.error(exception.getCode(), errorSystem + errorMessage);        return result;    }}

6、从新将GitEgg-Platform进行install,在GitEgg-Cloud中的gitegg-service引入gitegg-platform-boot

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <parent>        <artifactId>GitEgg-Cloud</artifactId>        <groupId>com.gitegg.cloud</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>    <artifactId>gitegg-service</artifactId>    <packaging>pom</packaging>    <modules>        <module>gitegg-service-base</module>        <module>gitegg-service-bigdata</module>        <module>gitegg-service-system</module>    </modules>    <dependencies>        <!-- gitegg Spring Boot自定义及扩大 -->        <dependency>            <groupId>com.gitegg.platform</groupId>            <artifactId>gitegg-platform-boot</artifactId>        </dependency>        <!-- gitegg数据库驱动及连接池 -->        <dependency>            <groupId>com.gitegg.platform</groupId>            <artifactId>gitegg-platform-db</artifactId>        </dependency>        <!-- gitegg mybatis-plus -->        <dependency>            <groupId>com.gitegg.platform</groupId>            <artifactId>gitegg-platform-mybatis</artifactId>        </dependency>        <!-- gitegg swagger2-knife4j -->        <dependency>            <groupId>com.gitegg.platform</groupId>            <artifactId>gitegg-platform-swagger</artifactId>        </dependency>        <!-- spring boot web外围包 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <!-- spring boot 衰弱监控 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>    </dependencies></project>

7、批改SystemController.java、ISystemService.java和SystemServiceImpl.java减少异样解决的测试代码

SystemController.java:

package com.gitegg.service.system.controller;import com.gitegg.platform.boot.common.base.Result;import com.gitegg.platform.boot.common.exception.BusinessException;import com.gitegg.service.system.service.ISystemService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.AllArgsConstructor;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping(value = "system")@AllArgsConstructor@Api(tags = "gitegg-system")public class SystemController {    private final ISystemService systemService;    @GetMapping(value = "list")    @ApiOperation(value = "system list接口")    public Object list() {        return systemService.list();    }    @GetMapping(value = "page")    @ApiOperation(value = "system page接口")    public Object page() {        return systemService.page();    }    @GetMapping(value = "exception")    @ApiOperation(value = "自定义异样及返回测试接口")    public Result<String> exception() {        return Result.data(systemService.exception());    }}

ISystemService.java:

package com.gitegg.service.system.service;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.gitegg.service.system.entity.SystemTable;import java.util.List;public interface ISystemService {    List<SystemTable> list();    Page<SystemTable> page();    String exception();}

SystemServiceImpl.java:

package com.gitegg.service.system.service.impl;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.gitegg.platform.boot.common.exception.BusinessException;import com.gitegg.service.system.entity.SystemTable;import com.gitegg.service.system.mapper.SystemTableMapper;import com.gitegg.service.system.service.ISystemService;import lombok.AllArgsConstructor;import org.springframework.stereotype.Service;import java.util.List;/** * */@Service@AllArgsConstructorpublic class SystemServiceImpl implements ISystemService {    private final SystemTableMapper systemTableMapper;    @Override    public List<SystemTable> list() {        return systemTableMapper.list();    }    @Override    public Page<SystemTable> page() {        Page<SystemTable> page = new Page<>(1, 10);        List<SystemTable> records = systemTableMapper.page(page);        page.setRecords(records);        return page;    }    @Override    public String exception() {        throw new BusinessException("自定义异样");//        return "胜利取得数据";    }}

8、运行GitEggSystemApplication,关上浏览器拜访:http://127.0.0.1:8001/doc.html,而后点击左侧的异样解决接口,应用Swagger2进行测试,即可看到后果

本文源码在https://gitee.com/wmz1930/GitEgg 的chapter-07分支。