博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
统一异常处理+后端参数校验+Springboot-后端统一返回接口
阅读量:2198 次
发布时间:2019-05-03

本文共 7300 字,大约阅读时间需要 24 分钟。

引入依赖

org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true

目录结构

目录结构

1.统一返回接口

1.1 统一响应体定义

package com.suruomo.unified.result;import lombok.Getter;import lombok.Setter;/** * @author suruomo * @date 2020/8/7 15:36 * @description: 自定义统一响应体 * VO( View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。 */@Getter@Setterpublic class ResultVO
{ /** * 状态码,比如1000代表响应成功 */ private int code; /** * 响应信息,用来说明响应情况 */ private String msg; /** * 响应的具体数据 */ private T data; public ResultVO(T data) { this(ResultCode.SUCCESS, data); } public ResultVO(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); this.data = data; }}

1.2 枚举状态码定义

package com.suruomo.unified.result;import lombok.Getter;/** * @author suruomo * @date 2020/8/7 16:10 * @description: 响应码枚举 */@Getterpublic enum ResultCode {    //1000系列通用错误    SUCCESS(1000, "操作成功"),    FAILED(1001, "接口错误"),    VALIDATE_FAILED(1002, "参数校验失败"),    ERROR(1003, "未知错误"),    //2000系列用户错误    USER_NOT_EXIST(2000,"用户不存在"),    USER_LOGIN_FAIL(2001,"用户名或密码错误"),    USER_NOT_LOGIN(2002,"用户还未登录,请先登录"),    NO_PERMISSION(2003,"权限不足,请联系管理员");    private int code;    private String msg;    ResultCode(int code, String msg) {        this.code = code;        this.msg = msg;    }}

2.实体类+参数校验

package com.suruomo.unified.pojo;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import javax.validation.constraints.Email;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;/** * @author suruomo * @date 2020/8/7 15:41 * @description: 实体类 */@Getter@Setter@NoArgsConstructorpublic class User {    @NotNull(message = "用户id不能为空")    private Long id;    @NotNull(message = "用户账号不能为空")    @Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")    private String account;    @NotNull(message = "用户密码不能为空")    @Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")    private String password;    @NotNull(message = "用户邮箱不能为空")    @Email(message = "邮箱格式不正确")    private String email;}

3.全局异常处理

3.1 自定义异常APIException

package com.suruomo.unified.exception;import com.suruomo.unified.result.ResultCode;import lombok.Getter;/** * @author suruomo * @date 2020/8/7 16:43 * @description: 自定义异常 */@Getterpublic class APIException extends RuntimeException {    private int code;    private String msg;    public APIException() {        this(ResultCode.FAILED);    }    public APIException(ResultCode failed) {        this.code=failed.getCode();        this.msg=failed.getMsg();    }}

2.全局异常统一处理

package com.suruomo.unified.exception;import com.suruomo.unified.result.ResultCode;import com.suruomo.unified.result.ResultVO;import lombok.extern.slf4j.Slf4j;import org.springframework.http.HttpStatus;import org.springframework.validation.ObjectError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseStatus;import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.ArrayList;import java.util.List;/** * @author suruomo * @date 2020/8/7 15:39 * @description: 全局异常处理类 */@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler {    /**     * 自定义异常APIException     */    @ExceptionHandler(APIException.class)    @ResponseStatus(HttpStatus.BAD_REQUEST)    public ResultVO APIExceptionHandler(APIException e) {        log.error("api异常");        return  new ResultVO<>(ResultCode.FAILED, e.getMsg());    }    /**     * 方法参数错误异常     * @param e     * @return     */    @ExceptionHandler(MethodArgumentNotValidException.class)    @ResponseStatus(HttpStatus.BAD_REQUEST)    public ResultVO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {        log.error("方法参数错误异常");        List
list=new ArrayList<>(); // 从异常对象中拿到ObjectError对象 if (!e.getBindingResult().getAllErrors().isEmpty()){ for(ObjectError error:e.getBindingResult().getAllErrors()){ list.add(error.getDefaultMessage().toString()); } } // 然后提取错误提示信息进行返回 return new ResultVO<>(ResultCode.VALIDATE_FAILED, list); }}

4.ResponseControllerAdvice-全局处理增强版Controller

实现ResponseBodyAdvice接口重写supports和beforeBodyWrite方法避免Controller里返回数据每次都要用响应体来包装package com.suruomo.unified.controller;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.suruomo.unified.exception.APIException;import com.suruomo.unified.result.ResultVO;import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/** * @author suruomo * @date 2020/8/7 16:38 * @description: 全局处理增强版Controller,避免Controller里返回数据每次都要用响应体来包装 */@RestControllerAdvice(basePackages = {"com.suruomo.unified.controller"}) // 注意哦,这里要加上需要扫描的包public class ResponseControllerAdvice implements ResponseBodyAdvice {    @Override    public boolean supports(MethodParameter returnType, Class
> aClass) { // 如果接口返回的类型本身就是ResultVO那就没有必要进行额外的操作,返回false return !returnType.getGenericParameterType().equals(ResultVO.class); } @Override public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class
> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { // String类型不能直接包装,所以要进行些特别的处理 if (returnType.getGenericParameterType().equals(String.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { // 将数据包装在ResultVO里后,再转换为json字符串响应给前端 return objectMapper.writeValueAsString(new ResultVO<>(data)); } catch (JsonProcessingException e) { throw new APIException(); } } // 将原本的数据包装在ResultVO里 return new ResultVO<>(data); }}

注意直接返回String数据不能直接包装,所以需要额外处理

5.TestController

package com.suruomo.unified.controller;import com.suruomo.unified.pojo.User;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;/** * @author suruomo * @date 2020/8/7 15:45 * @description: */@RestControllerpublic class TestController {    @GetMapping("/getUser")    public User getUser() {        User user = new User();        user.setId(1L);        user.setAccount("12345678");        user.setPassword("12345678");        user.setEmail("123@qq.com");        return user;    }    @PostMapping("/addUser")    public void addUser(@Valid @RequestBody User user){    }}

6.测试

1.POST测试

使用postman测试 请求:
在这里插入图片描述
返回结果:
在这里插入图片描述
2.GET测试
请求:
在这里插入图片描述
返回结果:
get请求结果

转载地址:http://pkqub.baihongyu.com/

你可能感兴趣的文章
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>
使聊天机器人具有个性
查看>>
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>
Logistic regression 为什么用 sigmoid ?
查看>>
Logistic Regression 为什么用极大似然函数
查看>>