Spring Boot(Web)初探四( 异常处理与使用)

本文介绍了一种在后台代码中使用异常处理机制向前端页面反馈结果的方法,通过定义统一的返回码和返回体,实现了对所有结果的JSON格式统一返回,并通过自定义异常和异常处理类减少了代码冗余。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

后台代码向前端页面反馈结果

上一篇中我们说了数据访问,我们在类中定义了约束,不能为空等操作,但是只有成功之后前台浏览器才有Person的json信息,或者删除用户等操作有一些条件,这些条件在service判断之后返回给Controller controller层在进行判断,代码很冗余,这样很不友好。
像这种情况我们就可以使用异常处理来进行

1.在后台返回Object错误的时候统一处理返回

  @PostMapping("/person/{id}")
  public Object updateById(@PathVariable("id")Integer id,@Valid Person person,BindingResult result){
        logger.info("更改的对象是:{}"+person);
        if (result.hasErrors()){
            logger.error("增加错误信息--->{}",result.getFieldError().getDefaultMessage());
            //直接将错误信息返回
            return result.getFieldError().getDefaultMessage();
        }
        return personService.saveOrUpdate(person);
    }

2.操作时候有条件限制的时候使用异常处理返回
更改删除用户Service

/**
     * 删除一个Person
     * @param id
     */
    @Transactional
    public void deleteById(Integer id) throws Exception{
        Person person = findById(id);
        if (person==null){
            throw new Exception("删除的信息不存在");
        }else if(person.getAge()>80){
            throw new Exception("80岁以上允许删除");
        }
        personDao.delete(id);
    }

这两种方式相比较后者比前者更好一点可以将所有的错误,不符合我们要求的数据都以异常的形式抛出,可以使系统在处理问题的方式上统一化。
我们发现这里抛异常的话,还是不够优雅,希望对返回消息进行定制统一的规则。
这里我们对每个请求结果定义一个返回码,方便后期维护

package com.xuzhao.enums;

/**
 * Created by xz 
 * 定义返回码方便管理
 */
public enum ResultEnum {
    UNKONW_ERROR(-100,"系统未知错误"),//没有处理的异常
    SUCCESS(0,"SUCCES"),
    MESSAGE_NOTFOND(101,"用户信息不存在"),
    CANNOT_DELETE_BYOUND80(102,"不能删除年龄大于80岁的"),
    ERROR(-1,"操作出错"),
    VALIDATE_FALSE(-99,"验证不通过")
    ;
    private Integer code;
    private String msg;

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

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

定义统一的返回体,对所有的结果进行返回统一的JSON

package com.xuzhao.entity;

/**
 * Http请求返回对象
 * Created by xz
 */
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;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

自定义异常拦截我们的抛出的异常统一封装消息体

package com.xuzhao.exception;

/**
 * Created by xz 
 * 自定义异常---Exception无法实现返回码的设置,这里我们就要自定异常来实现
 */

import com.xuzhao.enums.ResultEnum;

/**
 * 继承RuntimeException spring只对RuntimeException进行事务回滚
 */
public class PersonException extends RuntimeException {
    private Integer code;
    public PersonException(Integer code,String msg){
        super(msg);
        this.code = code;
    }
    public PersonException(ResultEnum resultEnum){
        super(resultEnum.getMsg());
        this.code = resultEnum.getCode();
    }

    public Integer getCode() {
        return code;
    }

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

为了减少代码的冗余量加入工具类封装返回信息

package com.xuzhao.utils;

import com.xuzhao.entity.Result;
import com.xuzhao.enums.ResultEnum;

/**
 * Created by xz 
 * 异常返回码处理工具类
 */
public class ResultUtil {
    /**
     * 成功
     * @param obj
     * @return
     */
    public static Result success(Object obj){
        Result result = new Result();
        result.setCode(ResultEnum.SUCCESS.getCode());
        result.setMsg(ResultEnum.SUCCESS.getMsg());
        result.setData(obj);
        return result;
    }

    /**
     * 失败了
     * @param code
     * @param msg
     * @return
     */
    public static Result eror(Integer code,String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

自定义异常的捕获处理类

package com.xuzhao.handle;

import com.xuzhao.entity.Result;
import com.xuzhao.exception.PersonException;
import com.xuzhao.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 by xz on 2017/9/3.
 * 这里完成了异常的捕获 对抛出的异常进行处理
 */
@ControllerAdvice
public class ExceptionHandle {

    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
    @ExceptionHandler(value = Exception.class)
    @ResponseBody//由于返回Json 类也没有RestController
    public Result handle(Exception e){
        if (e instanceof PersonException){
            return ResultUtil.eror(((PersonException) e).getCode(),e.getMessage());
        }else{
            logger.error("【系统异常】{}",e);
            return ResultUtil.eror(-100,"未知错误");
        }
    }
}

定义异常的处理类对我们抛出的异常进行处理

package com.xuzhao.handle;

import com.xuzhao.entity.Result;
import com.xuzhao.exception.PersonException;
import com.xuzhao.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 by xz on 2017/9/3.
 * 这里完成了异常的捕获 对抛出的异常进行处理
 */
@ControllerAdvice
public class ExceptionHandle {

    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
    @ExceptionHandler(value = Exception.class)
    @ResponseBody//由于返回Json 类也没有RestController
    public Result handle(Exception e){
        if (e instanceof PersonException){
            return ResultUtil.eror(((PersonException) e).getCode(),e.getMessage());
        }else{
            logger.error("【系统异常】{}",e);
              return ResultUtil.eror(ResultEnum.UNKONW_ERROR.getCode(),ResultEnum.UNKONW_ERROR.getMsg());
        }
    }
}

改写service

 /**
     * 删除一个Person
     * @param id
     */
    @Transactional
    public void deleteById(Integer id) throws Exception{
        Person person = findById(id);
        if (person==null){
//            throw new Exception("删除的信息不存在");
            throw new PersonException(ResultEnum.MESSAGE_NOTFOND);
        }else if(person.getAge()>80){
//            throw new Exception("80岁以上允许删除");
            throw new PersonException(ResultEnum.CANNOT_DELETE_BYOUND80);
        }
        personDao.delete(id);
    }

改写controller

//添加函数
 @PutMapping("/person")
    public Result addPerson(@Valid Person person,BindingResult result){
        if (result.hasErrors()){
            logger.error("增加错误信息--->{}",result.getFieldError().getDefaultMessage());
            return ResultUtil.eror(ResultEnum.VALIDATE_FALSE.getCode(),ResultEnum.VALIDATE_FALSE.getMsg()+":"+result.getFieldError().getDefaultMessage());
            ;
        }
        return ResultUtil.success(personService.saveOrUpdate(person));
    }
//更新数据函数
@PostMapping("/person/{id}")
    public Result updateById(@PathVariable("id")Integer id, @Valid Person person, BindingResult result){
        logger.info("更改的对象是:{}"+person);
        if (result.hasErrors()){
            logger.error("增加错误信息--->{}",result.getFieldError().getDefaultMessage());
            return ResultUtil.eror(ResultEnum.VALIDATE_FALSE.getCode(),ResultEnum.VALIDATE_FALSE.getMsg()+":"+result.getFieldError().getDefaultMessage());
        }
        return ResultUtil.success( personService.saveOrUpdate(person));
    }
//删除函数
@DeleteMapping("/person/{id}")
    public Result deleteById(@PathVariable("id") Integer id)throws Exception{
        personService.deleteById(id);
        return  ResultUtil.success("删除成功");
    }
//查询函数
 @GetMapping("/person/{id}")
    public Result findById(@PathVariable(value = "id") Integer id){
        Person person = personService.findById(id);
        if (person==null){
            return ResultUtil.eror(ResultEnum.MESSAGE_NOTFOND.getCode(),ResultEnum.MESSAGE_NOTFOND.getMsg());
        }
        return ResultUtil.success(personService.findById(id));
    }
 /**
     *  查询出所有信息
     使用postMan工具添加参数 参数名是类的属性名 选择GET方式
     服务器请求地址是:http://127.0.0.1/person/   (在数据库查看刚才添加的ID)
     在postMan下查看结果,成功的话会返回添加的Peron对象
     * @return
     */
    @GetMapping("/person")
    public Result findAll(){
        List<Person> personList = personService.findAll();
        if (personList==null||personList.size()<=0){
            return ResultUtil.eror(ResultEnum.MESSAGE_NOTFOND.getCode(),ResultEnum.MESSAGE_NOTFOND.getMsg());
        }
        return ResultUtil.success(personService.findAll());
    }

接下来我们启动项目进行测试
浏览器输入:
http://127.0.0.1/person/

{
    "code": 101,
    "msg": "用户信息不存在",
    "data": null
}

数据库中添加两条数据
浏览器输入:
http://127.0.0.1/person/

{
    "code": 0,
    "msg": "SUCCES",
    "data": [
        {
            "id": 1,
            "name": "张三",
            "sex": "男",
            "age": 88
        },
        {
            "id": 2,
            "name": "小新",
            "sex": "女",
            "age": 22
        }
    ]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值