5 Star 32 Fork 13

编程界的小学生 / exception-handler

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

[TOC]

作者:编程界的小学生

时间:2018-02-03

项目名称:exception-handler

是什么?

统一异常处理。支持返回统一的Json格式和跳转到错误页面。

有什么用?

我们项目中难免会遇到一些异常,比如自定义异常、参数传递异常等等其他异常。遇到异常我们一般是捕获并解决,或者直接将错误信息抛给客户端,问题来了,一堆乱七八糟的错误日志直接抛给用户,用户看得懂吗?会有人说,那可以直接判断状态码不是200的话就弹出系统异常等字样提示。是可以的,但是我们想更精确的知道是什么异常,比如参数异常,我们的业务异常等,所以这个exception-handler就是一个统一异常处理的工具类。他能帮我们处理你任何自定义的异常以及其他异常,处理方式为统一返回如下格式的JSON给客户端

{
    "code": 1,
    "msg": "系统异常",
    "result": "xxxxx"
}

注意:不同类型的异常code是不同的,内置分为参数异常和系统异常,前端可以根据不同的code来进行不同的处理,比如跳转不同的页面等。

怎么用?

我上面说了有什么用,现在来说说具体怎么用。分为两种使用,一种是maven项目的使用,一种是非maven项目的使用。

maven项目的使用

首先下载此项目,在项目根目录(包含pom.xml的目录)运行如下命令

mvn clean install

然后将如下配置放到你项目的pom.xml中

<dependency>
    <groupId>com.chentongwei</groupId>
	<artifactId>exception-handler</artifactId>
	<version>1.0.0</version>
</dependency>

非maven项目的使用

首先下载项目,然后导出成jar包放到项目的lib目录。

接下来说下spring项目和springboot项目如何使用

spring使用

直接复制下面配置到你的配置文件即可。

<bean id="exceptionResolver" class="com.chentongwei.interceptor.ExceptionResolver" />

springboot使用

将如下配置类复制到你项目中受spring所管理的包中即可生效。

import com.chentongwei.interceptor.ExceptionResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author TongWei.Chen 2018-03-01 16:13
 */
@Configuration
public class WebConfig {

    @Bean
    public ExceptionResolver getBean() {
        return new ExceptionResolver();
    }
}

配置完成后即可使用,如果你项目中报任何错误,都会被系统拦截到并将错误级别(这里所谓的错误级别是指msg)和错误具体信息抛给客户端。如果我们想要抛出我们自定义的异常的怎么办?

可以直接自己建立自定义异常类并继承com.chentongwei.exception.ExceptionStrategy(内置了一个BussinessException

自定义异常Demo

import com.chentongwei.enums.IBaseEnum;
import com.chentongwei.strategy.ExceptionStrategy;

/**
 * @author TongWei.Chen 2018-03-01 15:55
 */
public class UserNotExistException extends ExceptionStrategy {

    private IBaseEnum baseEnum;

    public IBaseEnum getBaseEnum() {
        return baseEnum;
    }

    public void setBaseEnum(IBaseEnum baseEnum) {
        this.baseEnum = baseEnum;
    }

    public UserNotExistException(IBaseEnum baseEnum) {
        this.baseEnum = baseEnum;
    }

    @Override
    public IBaseEnum resolverException() {
        return this.baseEnum;
    }
}

注意:com.chentongwei.enums.IBaseEnum是我自定义的一个错误信息枚举接口,所以必须包含比此属性并且带有此属性的构造器。

如果我们想自定义异常错误码和错误信息怎么办?可以自定义枚举类然后实现com.chentongwei.enums.IBaseEnum

自定义枚举Demo

import com.chentongwei.enums.IBaseEnum;

/**
 * @author TongWei.Chen 2018-03-02 14:20:38
 */
public enum  ResponseEnum implements IBaseEnum{

    NULL(2, "未查到此数据")
    ;

    private int code;
    private String msg;

    ResponseEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public int getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }
}

完整Demo

import com.chentongwei.enums.IBaseEnum;
import com.chentongwei.strategy.ExceptionStrategy;

/**
 * @author TongWei.Chen 2018-03-01 15:55
 */
public class UserNotExistException extends ExceptionStrategy {

    private IBaseEnum baseEnum;

    public IBaseEnum getBaseEnum() {
        return baseEnum;
    }

    public void setBaseEnum(IBaseEnum baseEnum) {
        this.baseEnum = baseEnum;
    }

    public UserNotExistException(IBaseEnum baseEnum) {
        this.baseEnum = baseEnum;
    }

    @Override
    public IBaseEnum resolverException() {
        return this.baseEnum;
    }
}

import com.chentongwei.enums.IBaseEnum;

/**
 * @author TongWei.Chen 2018-03-02 14:20:38
 */
public enum  ResponseEnum implements IBaseEnum{

    NULL(2, "未查到此数据")
    ;

    private int code;
    private String msg;

    ResponseEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public int getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }
}

@RestController
public class UserController {

    @GetMapping("/user/{id}")
    public void detail(@PathVariable Integer id) {
        throw new UserNotExistException(ResponseEnum.NULL);
    }
}

调用URL

http://ip:port/projectname/user/1

返回结果

{
  "code": 2,
  "msg": "未查到此数据",
  "result": "未查到此数据"
}

结果简单说明

上面的JSON数据很明显是我们自定义枚举类里的内容,所以这样就达到了可扩展,根据不同的业务可以抛出不同的异常。而我们的exception-handler全都会为我们捕获并抛给客户端。

跳转页面配置

上面说的是返回统一的JSON,接下来简单说下如果不是静态分离的项目,应该如何配置才能跳转到自定义的异常页面上。

resources目录下新建system.properties,里面支持两个参数,如下

com.chentongwei.exception.handler.type=HTML
com.chentongwei.exception.view=/error.html

第一个参数若不配置则默认是返回JSON,这里配置为HTML,则就会触发跳转到页面的逻辑,而不是统一返回JSON的逻辑;第二个参数是需要跳转到哪个页面上。

项目其他描述

如果你有用到Hibernate Valid(比如@NotNull,@NotEmpty等等注解验证),则我们的exception-handler也为我们捕获了此异常,称之为参数传递异常。如下做个Demo进行演示查看效果

import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotNull;

/**
 * @author TongWei.Chen 2018-02-28 15:49
 */
public class UserIO {

    @NotNull(message = "用户名不能为空")
    private String username;

    @Range(min = 0, max = 100, message = "年龄必须在0~100之间")
    private int age;

    private int ageTo;

    private String xxx;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAgeTo() {
        return ageTo;
    }

    public void setAgeTo(int ageTo) {
        this.ageTo = ageTo;
    }

    public String getXxx() {
        return xxx;
    }

    public void setXxx(String xxx) {
        this.xxx = xxx;
    }
}

@GetMapping("/user")
public List<User> query(@Valid UserIO userIO) {
	return null;
}

调用URL

http://ip:port/projectname/user?username=&age=101

返回结果

{
  "code": 3,
  "msg": "参数传递异常",
  "result": "年龄必须在0~100之间并且用户名不能为空"
}

结果简单说明

code为3,msg称为参数传递异常,result是具体因为什么而发生异常的一个详细说明。很完美的JSON。完全无需我们在额外管理其他东西。

PS:对Valid验证不了解的,希望自行学习下,学习成本很低,很了不起的一个校验框架,能省下很多时间,也支持自定义的注解校验,不是此处重点,所以不进行过多讲解。

日志问题

我们都想在抛出异常时记录下日志到文件,默认采取的是log4j,若你是logback或其他,请自行将com.chentongwei.interceptor.ExceptionResolver里面这句话换掉。

private static final Logger LOG = LogManager.getLogger("exceptionLog");

若您采取的是log4j,则只需要声明个name为exceptionLog的logger即可。

值得注意的地方

若此项目与您的项目jar重复导致问题的话,请用maven依赖的时候将我这里的jar排除掉即可。

写在最后的话

我是一个对编程充满无限兴趣的小学生。写的东西不是很完美,希望大家多多提ISSUE,共同交流一起进步!

个人名言:

什么都要会一点,这样装起逼来不会尴尬。

彪悍的人生不需要解释。

The MIT License (MIT) Copyright (c) 2018 编程界的小学生 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

统一异常处理,配置简单,可扩展。支持Spring项目、SpringBoot项目。 展开 收起
Java
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/geekerdream/exception-handler.git
git@gitee.com:geekerdream/exception-handler.git
geekerdream
exception-handler
exception-handler
master

搜索帮助