spring boot 输入参数统一校验

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot 输入参数统一校验相关的知识,希望对你有一定的参考价值。

1 引入spring boot validate    maven 依赖

 <!-- 验证 -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>

 

2  输入参数 模型 dto

package com.example.demo.input;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

public class AccountCreateInput {

    @Size(min=6, max=30,message = "账号名长度必须在6,30之间")
    private String loginName ;
    @NotEmpty(message = "密码不能为空")
    private String loginPwd;
    private String realName;

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getLoginPwd() {
        return loginPwd;
    }

    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }
}

 

3 启用统一验证错误处理 。 当参数模型验证未通过,会抛出

MethodArgumentNotValidException  异常,统一处理即可。 
package com.example.demo.config;

import com.example.demo.Infrastructure.FriendlyException;
import com.example.demo.Infrastructure.UnauthorizedException;
import com.example.demo.Infrastructure.http.ResultModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class GlobalExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultModel jsonErrorHandler(HttpServletRequest req, Exception e) {

        // 友好提示错误
        if (e instanceof FriendlyException) {
            logger.info(e.getMessage());
            return ResultModel.internalServerError(e.getMessage());
        }
        // 权限校验
        else if (e instanceof UnauthorizedException) {
            logger.info(e.getMessage());
            return ResultModel.Unauthorized(e.getMessage());

        }
        // 全局统一校验
        else if(e instanceof MethodArgumentNotValidException ){
            MethodArgumentNotValidException  ex = (MethodArgumentNotValidException ) e;

            BindingResult result = ex.getBindingResult();
            StringBuffer sb = new StringBuffer();

            for (FieldError error : result.getFieldErrors()) {
                String field = error.getField();
                String msg = error.getDefaultMessage();
                String message = String.format("%s:%s ", field, msg);
                sb.append(message);
            }

            return ResultModel.internalServerError(sb.toString());
        }
        // 未知异常
        else {
            logger.error(e.getMessage(), e);
            return ResultModel.internalServerError(e.toString());
        }
    }

}

4  在controller 中标注需要验证的输入参数,在CreateAccountInput 参数前,添加@validated 注解

package com.example.demo.controller;

import com.example.demo.Infrastructure.http.ResultModel;
import com.example.demo.domain.Account;
import com.example.demo.input.AccountCreateInput;
import com.example.demo.service.IAccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@Api(value = "Account api", description = "api of account")
@RestController
@RequestMapping("/account")
public class AccountController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    IAccountService accountService;

    @ApiOperation(value = "account index list", notes = "账户列表信息")
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ResultModel index() {

        List<Account> rows = this.accountService.findAll();
        return ResultModel.ok(rows);
    }

    @ApiOperation(value = "create a account", notes = "a account name")

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResultModel create(
            @ApiParam(name = "model", value = "input a account entity") @RequestBody @Validated AccountCreateInput model)  {

        this.accountService.Create(model);
        Account entity = this.accountService.findAccountByName(model.getLoginName());
        return ResultModel.ok(entity);
    }

    @ApiOperation(value = "find account by name", notes = "根据登录名查找账户")
    @RequestMapping(value = "/query", method = RequestMethod.GET)
    public ResultModel query(@RequestParam String name)  {
        this.logger.info(String.format("url:/account/query?name=%s ",name));

        List<Account> rows = this.accountService.findAllByName(name);
        return ResultModel.ok(rows);

    }
}

5 最后swagger  请求时结果:

请求参数,密码不填

image

响应结果:

image

以上是关于spring boot 输入参数统一校验的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 统一参数校验统一异常统一响应,这才是优雅的处理方式!

手把手写一个基于Spring Boot框架下的参数校验组件(JSR-303)

Spring Boot 统一参数校验统一异常统一响应,这才是优雅的处理方式!

Validated校验在springboot框架中的应用(教程版)

Spring Boot配合Hibernate Validator参数校验

Spring Boot参数校验以及分组校验的使用