springboot 参数校验及封装返回格式

pom文件配置:

springboot项目需要的jar包引用。

快速创建springboot项目可在官网,地址:https://start.spring.io/

参数校验引入jar包

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.5.0</version>
        </dependency>

网上找的好多都是配置下面这个包,但是不生效,不知道什么原因:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

封装统一的返回格式:

package cn.dto;

import cn.enums.ResEnum;
import com.alibaba.fastjson.JSONObject;

import java.io.Serializable;

public class ResDTO<T> implements Serializable {

    private static final long serialVersionUID = -1391045602107628480L;

    private Integer code;
    private String msg;
    private T data;

    public ResDTO() {
    }

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

    public ResDTO(T data, Integer code, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

    public ResDTO(ResEnum resEnum) {
        this.data = null;
        this.code = resEnum.code();
        this.msg = resEnum.message();
    }

    public ResDTO(ResEnum resEnum,T data) {
        this.data = data;
        this.code = resEnum.code();
        this.msg = resEnum.message();
    }

    public static String error(){
        return JSONObject.toJSONString(new ResDTO(ResEnum.ERROE));
    }

    public static String success(){
        return JSONObject.toJSONString(new ResDTO(ResEnum.SUCESS));
    }

    public  ResDTO<T> success(T data){
        return new ResDTO<T>(ResEnum.SUCESS,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.enums;

public enum ResEnum {
    SUCESS(1,"成功"),
    IS_NULL(2,"查询接果为空"),
    PARAM_IS_ERROR(3,"参数错误"),
    EXCUTER_ERROR(4,"执行失败"),
    ERROE(9,"系统异常");


    private Integer code;
    private String message;

    ResEnum(int code, String message) {
        this.code=code;
        this.message=message;
    }


    public Integer code(){
        return this.code;
    }
    public String message(){
        return this.message;
    }
}

实体类

package cn.entity;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;

public class TestEntity implements Serializable {
    private static final long serialVersionUID = -543680037107475493L;


    @NotBlank(message = "id不能为空")
    private String id;

    @NotEmpty(message = "value不能为空")
    private String value;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

控制层

package cn.controller;

import cn.enums.ResEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import cn.dto.*;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@ControllerAdvice
public class BaseController {

    private Logger logger = LoggerFactory.getLogger(BaseController.class);

    /**
     * 参数校验异常
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResDTO bindExceptionHandler(MethodArgumentNotValidException ex) throws Exception {
        BindingResult result = ex.getBindingResult();
        StringBuilder s=new StringBuilder();
        if (result.hasErrors()) {

            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p ->{
                FieldError fieldError = (FieldError) p;
                s.append(fieldError.getField()+":"+fieldError.getDefaultMessage());
            });
        }
        logger.error("ExceptionController.bindExceptionHandler:"+s);
        return new ResDTO(ResEnum.PARAM_IS_ERROR);
    }
    /**
     * 处理其他异常
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResDTO exceptionHandler(Exception ex) throws Exception {
        String msg = ex.getMessage();
        logger.error("ExceptionController.exceptionHandler:"+msg);
        return new ResDTO(ResEnum.ERROE);
    }

}
package cn.controller;

import cn.dto.ResDTO;
import cn.entity.TestEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.List;

@RestController
@RequestMapping("/con")
@Validated
public class TestController extends BaseController{

    @RequestMapping("/test")
    public @ResponseBody ResDTO<TestEntity> test(@RequestBody @Validated TestEntity testEntity){
        return new ResDTO<TestEntity>().success(testEntity);
    }

    @RequestMapping("/test2")
    public @ResponseBody ResDTO test2(@NotBlank String id,
                                      @NotBlank String value){
        return new ResDTO().success();
    }

}

测试ok:

127.0.0.1:8080/con/test

{"id":"","value":""}

返回:

{

    "code": 3,

    "msg": "参数错误",

    "data": null

}

 日志记录:

 问题记录:

在controller类的方法参数请求方式上,如果需要用josn格式,需要加上 @RequestBody 否在 使用json格式提交会报错,返回对象加上 @ResponseBody 注解,返回格式会自动转成json,不需要单独自己去转换。

单个参数,不做对象传参时需要在controller类上加上@Validated注解 

发现一个问题就是这种捕获的异常是exception异常,按照我的分装返回的就是系统异常,很明显这个返回不正确。

需要再增加一单个参数异常处理。

/**
     * 单个参数校验时抛出的异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public ResDTO handleBindGetException(ConstraintViolationException ex){
        //获取参数校验异常message
        List<String> defaultMsg = ex.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        logger.error("ExceptionController.exceptionHandler:"+ex);
        return new ResDTO(ResEnum.PARAM_IS_ERROR);
    }

还有在网上有很多介绍参数异常是BindException这个,这个异常已经不用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值