统一返回结果
统一结果类
- 在 项目目录 下 新建 一个 common 包
- 在 common 包中创建一个 response 包
| package com.codervibe.demo.common.response; |
| |
| import lombok.Data; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| @Data |
| public class R { |
| private Boolean success; |
| private Integer code; |
| private String message; |
| private Map<String, Object> data = new HashMap<>(); |
| |
| |
| private R() { |
| } |
| |
| |
| public static R ok() { |
| R r = new R(); |
| r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess()); |
| r.setCode(ResultCodeEnum.SUCCESS.getCode()); |
| r.setMessage(ResultCodeEnum.SUCCESS.getMessage()); |
| return r; |
| } |
| |
| |
| public static R error() { |
| R r = new R(); |
| r.setSuccess(ResultCodeEnum.UNKNOWN_ERROR.getSuccess()); |
| r.setCode(ResultCodeEnum.UNKNOWN_ERROR.getCode()); |
| r.setMessage(ResultCodeEnum.UNKNOWN_ERROR.getMessage()); |
| return r; |
| } |
| |
| |
| public static R setResult(ResultCodeEnum result) { |
| R r = new R(); |
| r.setSuccess(result.getSuccess()); |
| r.setCode(result.getCode()); |
| r.setMessage(result.getMessage()); |
| return r; |
| } |
| |
| |
| |
| |
| |
| |
| public R data(Map<String, Object> map) { |
| this.setData(map); |
| return this; |
| } |
| |
| |
| public R data(String key, Object value) { |
| this.data.put(key, value); |
| return this; |
| } |
| |
| |
| public R message(String message) { |
| this.setMessage(message); |
| return this; |
| } |
| |
| |
| public R code(Integer code) { |
| this.setCode(code); |
| return this; |
| } |
| |
| |
| public R success(Boolean success) { |
| this.setSuccess(success); |
| return this; |
| } |
| |
| } |
| |
结果类枚举
| package com.codervibe.demo.common.response; |
| |
| import lombok.Getter; |
| |
| @Getter |
| public enum ResultCodeEnum { |
| SUCCESS(true,20000,"成功"), |
| UNKNOWN_ERROR(false,20001,"未知错误"), |
| PARAM_ERROR(false,20002,"参数错误"), |
| NULL_POINT(false,20003,"空指针错误"), |
| HTTP_CLIENT_ERROR(false,20004,"客户端错误") |
| |
| ; |
| private Boolean success; |
| private Integer code; |
| private String message; |
| |
| ResultCodeEnum(boolean success,Integer code,String message){ |
| this.success =success; |
| this.code = code; |
| this.message =message; |
| } |
| |
| } |
控制层返回
| package com.codervibe.demo.model; |
| |
| import com.fasterxml.jackson.annotation.JsonFormat; |
| import lombok.AllArgsConstructor; |
| import lombok.Data; |
| import lombok.NoArgsConstructor; |
| import lombok.ToString; |
| import lombok.experimental.Accessors; |
| |
| import java.util.Date; |
| |
| |
| |
| |
| |
| |
| |
| |
| @Data |
| @AllArgsConstructor |
| @NoArgsConstructor |
| @ToString |
| @Accessors(chain = true) |
| public class User { |
| private int id; |
| |
| |
| |
| private String username; |
| |
| |
| |
| |
| private String password; |
| |
| |
| |
| |
| private String email; |
| |
| |
| |
| |
| @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") |
| private Date createTime; |
| |
| |
| |
| |
| private String role; |
| |
| private static final long serialVersionUID = 1L; |
| } |
| |
| package com.codervibe.demo.controller; |
| |
| import com.codervibe.demo.common.response.R; |
| import com.codervibe.demo.model.User; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.springframework.web.bind.annotation.GetMapping; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| import org.springframework.web.bind.annotation.RestController; |
| |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.List; |
| |
| @RestController |
| @RequestMapping("/user") |
| public class UserController { |
| Logger logger = LoggerFactory.getLogger(UserController.class); |
| @GetMapping("/list") |
| public R list() { |
| |
| |
| |
| List<User> userList = new ArrayList<>(); |
| userList.add(new User(1, "孙悟空", "1111", "94df@f4m2.com.cn", new Date(), "1")); |
| userList.add(new User(2, "金蝉子", "1111", "461b@91y35u.xyz", new Date(), "1")); |
| userList.add(new User(3, "鲁班七号", "11111", "6959@687kyp.com", new Date(), "1")); |
| userList.add(new User(4, "鲁班大师", "11111", "fa57@196bmfgq.com.cn", new Date(), "1")); |
| userList.add(new User(5, "安其拉", "111111", "88ac@o23wg.com", new Date(), "1")); |
| |
| logger.info("用户列表 :"+userList.toString()); |
| |
| return R.ok().data("userItems", userList).message("用户列表"); |
| } |
| } |
| |
| C:\Users\Administrator\Desktop>curl http://localhost:5767/demo/user/list |
| { |
| "success": true, |
| "code": 20000, |
| "message": "用户列表", |
| "data": { |
| "userItems": [ |
| { |
| "id": 1, |
| "username": "孙悟空", |
| "password": "1111", |
| "email": "94df@f4m2.com.cn", |
| "createTime": "2024-01-20 23:14:44", |
| "role": "1" |
| }, |
| { |
| "id": 2, |
| "username": "金蝉子", |
| "password": "1111", |
| "email": "461b@91y35u.xyz", |
| "createTime": "2024-01-20 23:14:44", |
| "role": "1" |
| }, |
| { |
| "id": 3, |
| "username": "鲁班七号", |
| "password": "11111", |
| "email": "6959@687kyp.com", |
| "createTime": "2024-01-20 23:14:44", |
| "role": "1" |
| }, |
| { |
| "id": 4, |
| "username": "鲁班大师", |
| "password": "11111", |
| "email": "fa57@196bmfgq.com.cn", |
| "createTime": "2024-01-20 23:14:44", |
| "role": "1" |
| }, |
| { |
| "id": 5, |
| "username": "安其拉", |
| "password": "111111", |
| "email": "88ac@o23wg.com", |
| "createTime": "2024-01-20 23:14:44", |
| "role": "1" |
| } |
| ] |
| } |
| } |
统一异常处理
- 使用统一返回结果时,还有一种情况,就是程序的保存是由于运行时异常导致的结果,有些异常我们可以无法提前预知,不能正常走到我们return的R对象返回。
- 因此,我们需要定义一个统一的全局异常来捕获这些信息,并作为一种结果返回控制层
@ControllerAdvice 该注解为统一异常处理的核心
- 是一种作用于控制层的切面通知(Advice),该注解能够将通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法收集到一个类型,并应用到所有控制器上
- 该类中的设计思路:
- 使用@ExceptionHandler注解捕获指定或自定义的异常;
- 使用@ControllerAdvice集成@ExceptionHandler的方法到一个类中;
- 必须定义一个通用的异常捕获方法,便于捕获未定义的异常信息;
- 自定一个异常类,捕获针对项目或业务的异常;
- 异常的对象信息补充到统一结果枚举中;
自定义全局异常类
- 在common 包中 新建一个 exception 包
- 自定义异常类 的 名字为 项目名 + exception
| package com.codervibe.demo.common.exception; |
| |
| import com.codervibe.demo.common.response.ResultCodeEnum; |
| import lombok.Data; |
| |
| @Data |
| public class DemoException extends RuntimeException{ |
| private Integer code; |
| |
| public DemoException(Integer code, String message) { |
| super(message); |
| this.code = code; |
| } |
| |
| public DemoException(ResultCodeEnum resultCodeEnum) { |
| super(resultCodeEnum.getMessage()); |
| this.code = resultCodeEnum.getCode(); |
| } |
| |
| @Override |
| public String toString() { |
| return "DemoException{" + "code=" + code + ", message=" + this.getMessage() + '}'; |
| } |
| |
| |
| } |
| |
统一异常处理器
| package com.codervibe.demo.common.exception; |
| |
| import com.codervibe.demo.common.response.R; |
| import com.codervibe.demo.common.response.ResultCodeEnum; |
| import org.springframework.web.bind.annotation.ControllerAdvice; |
| import org.springframework.web.bind.annotation.ExceptionHandler; |
| import org.springframework.web.bind.annotation.ResponseBody; |
| import org.springframework.web.client.HttpClientErrorException; |
| |
| @ControllerAdvice |
| public class GlobalExceptionHandler { |
| |
| @ExceptionHandler(Exception.class) |
| @ResponseBody |
| public R error(Exception e) { |
| e.printStackTrace(); |
| return R.error(); |
| } |
| |
| |
| @ExceptionHandler(NullPointerException.class) |
| @ResponseBody |
| public R error(NullPointerException e) { |
| e.printStackTrace(); |
| return R.setResult(ResultCodeEnum.NULL_POINT); |
| } |
| |
| @ExceptionHandler(HttpClientErrorException.class) |
| @ResponseBody |
| public R error(IndexOutOfBoundsException e) { |
| e.printStackTrace(); |
| return R.setResult(ResultCodeEnum.HTTP_CLIENT_ERROR); |
| } |
| |
| |
| @ExceptionHandler(DemoException.class) |
| @ResponseBody |
| public R error(DemoException e) { |
| e.printStackTrace(); |
| return R.error().message(e.getMessage()).code(e.getCode()); |
| } |
| } |
控制层展示
- 以下为展示当遇到null指定异常时,返回的结果信息
| { |
| "success": false, |
| "code": 20007, |
| "message": "空指针异常", |
| "data": {} |
| } |
加我粉丝群 企鹅 179469398
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步