【SpringBoot】Http请求统一异常(返回数据)处理与单元测试(1)

简介: 【SpringBoot】Http请求统一异常(返回数据)处理与单元测试

对返回数据格式的统一

首先规定一下错误的输出格式:

{   
    "code": 1,
    "msg": "提示",
    "data": null
}• 1
• 2
• 3
• 4
• 5

data是一个对象

首先定义一个http请求返回的类

package cn.chenhaoxiang.common.entity;
/**
 * Created with IntelliJ IDEA.
 * User: 陈浩翔.
 * Date: 2018/1/7.
 * Time: 下午 2:17.
 * Explain: http请求返回的最外层对象
 */
public class Result<T> {
    /**
     * 错误码
     */
    private Integer code;
    /**
     * 提示信息
     */
    private String msg;
    /**
     * 返回的具体内容
     */
    private T data;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}


然后可以定义一个工具类:

package cn.chenhaoxiang.utils;
import cn.chenhaoxiang.common.entity.Result;
/**
 * Created with IntelliJ IDEA.
 * User: 陈浩翔.
 * Date: 2018/1/7.
 * Time: 下午 2:45.
 * Explain:
 */
public class ResultUtil {
    public static Result success(Object object){
        Result result = new Result();
        result.setCode(1);
        result.setMsg("成功");
        result.setData(object);
        return  result;
    }
    public static Result successNoData(){
        return  success(null);
    }
    public static Result error(Integer code,String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return  result;
    }
}


这个ResultUtil中的方法,其实写在BaseController中也挺不错的


People实体类中:


@NotBlank(message = "名字不能为空")//String 不是 null 且去除两端空白字符后的长度(trimmed length)大于 0
    private String name;
    @NotNull(message = "分数必传")//CharSequence, Collection, Map 和 Array 对象不能是 null, 但可以是空集(size = 0)
    private Double score;
    private String address;
    @Min(value = 18,message = "年龄必须大于18")//message为提示  20180103
    private Integer age;


属性上的注解,都是限制条件,注释上有说明

在Controller中使用的时候:

    /**
     * 新增一个对象
     * 增加一个功能,如果年龄大于18,就不让添加进数据库 20180103
     * @param people
     * @return
     */
    @PostMapping(value = "/add")
    public Result<People> peopleAdd(@Valid People people, BindingResult bindingResult){//@Valid 注解表示使用数据校验 People类中对年龄进行了限制 ,验证返回结果会在bindingResult对象中 20180103
        //@RequestParam(value = "people")  直接传类的时候,建议不要使用RequestParam注解
        //当然,你可以选择每一个参数都写上,但没必要,更多的时候是直接传类对象,注意url的参数名和类中属性名对上
        if(bindingResult.hasErrors()){//验证出现错误
            return ResultUtil.error(0,bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultUtil.success( peopleDao.save(people));
    }


访问,看结果:


失败的只演示这个,再演示一个添加成功的


这样完成了对返回数据格式的统一

对不同结果统一返回处理

获取分数判断

如果分数小于60,返回”不及格”

分数大于60且小于80,返回”良好”

下面来看代码吧

在Service层的实现类中

    /**
     * 往往业务有点复杂,不能直接返回String,比如在这里
     * @param id
     */
    @Override
    public void getScore(Integer id) throws Exception {
        People people = peopleDao.findOne(id);
        Double score = people.getScore();
        if(score<60){
            //返回 "不及格"
            throw new PeopleException(ResultEnum.FLUNK);
        }else if(score>=60 && score<80 ){
            //返回 "良好"
            throw new PeopleException(ResultEnum.WELL);
        }
        //前面的只是作为校验,也就是条件,条件满足后才有后面的操作
        //如果分数大于80,则给他进行另外的操作,这个时候就不好返回字符串了
        //有的可能用数字来标志,返回1,2,3等等,然后在Controller再判断,这样是可以达到效果,但是代码写起来很别扭,在service中判断一次,controller还需要再判断一次
        // 而且返回1,2,3都是自己标记的,假如这个标志多了呢,是不是很麻烦
        //这个时候,统一异常处理就派上用处了
    }

自定义枚举ResultEnum

package cn.chenhaoxiang.enums;
/**
 * Created with IntelliJ IDEA.
 * User: 陈浩翔.
 * Date: 2018/1/7.
 * Time: 下午 3:31.
 * Explain:
 */
public enum ResultEnum {
    UNKONW_ERROR(-1,"未知错误"),
    ERROR(0,"失败"),
    SUCCESS(1,"成功"),
    FLUNK(100,"不及格"),
    WELL(101,"良好")
    ;
    ResultEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    private Integer code;
    private  String msg;
    public Integer getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}


自定义异常类PeopleException

package cn.chenhaoxiang.exception;
import cn.chenhaoxiang.enums.ResultEnum;
/**
 * Created with IntelliJ IDEA.
 * User: 陈浩翔.
 * Date: 2018/1/7.
 * Time: 下午 3:18.
 * Explain:
 */
public class PeopleException extends RuntimeException {//不要继承Exception ,Spring只对你的异常是RuntimeException的才会进行事务回滚
    private Integer code;
    public PeopleException(ResultEnum resultEnum) {
        super(resultEnum.getMsg());
        this.code = resultEnum.getCode();
    }
    public PeopleException(Integer code,String message) {
        super(message);//父类本身就有message
        this.code = code;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
}


异常捕获 统一异常返回格式

package cn.chenhaoxiang.handle;
import cn.chenhaoxiang.common.entity.Result;
import cn.chenhaoxiang.enums.ResultEnum;
import cn.chenhaoxiang.exception.PeopleException;
import cn.chenhaoxiang.utils.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * Created with IntelliJ IDEA.
 * User: 陈浩翔.
 * Date: 2018/1/7.
 * Time: 下午 3:13.
 * Explain:异常捕获  统一异常返回格式
 */
@ControllerAdvice
public class ExceptionHandle {
    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
    @ExceptionHandler(value = Exception.class)//声明需要捕获的异常类 - 写成PeopleException,就是只会捕获PeopleException异常了
    @ResponseBody //由于返回浏览器那边是json格式,就需要这个
    public Result handle(Exception e){
        if(e instanceof PeopleException){
            PeopleException peopleException = (PeopleException) e;
            return ResultUtil.error(peopleException.getCode(),peopleException.getMessage());
        }else {
            logger.error("[系统异常]-{}",e);
            return ResultUtil.error(ResultEnum.UNKONW_ERROR);
        }
    }
}

固定返回格式,避免逻辑在一个地方处理,另一个地方重复处理,我们用异常来处理

将code和message固定成枚举,来统一管理

目录
打赏
0
0
0
0
988
分享
相关文章
大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
71 10
大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
37 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
Haskell中的HTTP请求:代理与响应状态检查
Haskell中的HTTP请求:代理与响应状态检查
基于SpringBoot+Vue实现的大学生体质测试管理系统设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
42 2
HTTP 范围Range请求
HTTP范围请求是一种强大的技术,允许客户端请求资源的部分内容,提高了传输效率和用户体验。通过正确配置服务器和实现范围请求,可以在视频流、断点续传下载等场景中发挥重要作用。希望本文提供的详细介绍和示例代码能帮助您更好地理解和应用这一技术。
105 19
Spring Boot 如何测试打包部署
本文介绍了 Spring Boot 项目的开发、调试、打包及投产上线的全流程。主要内容包括: 1. **单元测试**:通过添加 `spring-boot-starter-test` 包,使用 `@RunWith(SpringRunner.class)` 和 `@SpringBootTest` 注解进行测试类开发。 2. **集成测试**:支持热部署,通过添加 `spring-boot-devtools` 实现代码修改后自动重启。 3. **投产上线**:提供两种部署方案,一是打包成 jar 包直接运行,二是打包成 war 包部署到 Tomcat 服务器。
49 10
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
401 18
|
2月前
|
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
90 2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长。 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有负面影响; 另一方面,很有可能会由于超时,提示用户服务请求失败。
787 0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
最近在线上往hbase导数据,因为hbase写入能力比较强,没有太在意写的问题。让业务方进行历史数据的导入操作,中间发现一个问题,写入速度太快,并且业务数据集中到其中一个region,这个region无法split掉,处于不可用状态。
1360 0