Controller 层参数校验方案
标签:
JavaScript
思路
Controller层有两种校验场景
单个参数的校验
// 用户登录 Controller 方法@PostMapping("/login")public Message login(String verifyCode,String account,String password){ //....
return null;
}实体类的校验
实体类User里,有多个字段需要校验,比如用户名不能为空,密码不能为空等等
// 添加用户 Controller 方法@PostMapping("/add")public Message addUser(User user){ //....
return null;
}下面介绍GET参数校验的实现方法。
环境
注意,Spring boot 内已经集成了Hibernate validator
Spring boot
Hibernate validator
lombok
Hibernate 参数校验 - GET参数校验模式 的实现
编写配置类
package com.spz.demo.security.config;import lombok.extern.slf4j.Slf4j;import org.hibernate.validator.HibernateValidator;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;import javax.validation.Validation;import javax.validation.Validator;import javax.validation.ValidatorFactory;/**
* 配置 Hibernate 参数校验
* 参考:https://blog.csdn.net/u010454030/article/details/53009327
*/@Slf4j(topic = "SYSTEM_LOG")//日志模块@Configuration@EnableAutoConfigurationpublic class ValidatorConfig { @Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator());//快速校验,只要有错马上返回
return postProcessor;
} @Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator(); return validator;
}
}编写验证错误信息提示
校验未通过时,将抛出ConstraintViolationException异常,此时需要在异常处理方法里获取错误信息,并进行返回
package com.spz.demo.security.config;import com.spz.demo.security.bean.Message;import org.springframework.http.HttpStatus;import org.springframework.stereotype.Component;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.bind.annotation.ResponseStatus;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import javax.validation.ValidationException;import java.util.Set;@ControllerAdvice@Componentpublic class GlobalExceptionHandler { /**
* hibernate 参数校验出错会抛出 ConstraintViolationException 异常
* 在此方法中处理,将错误信息输出
* @param exception
* @return
*/
@ExceptionHandler
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST) public Object handle(ValidationException exception) {
String errorInfo = ""; if(exception instanceof ConstraintViolationException){
ConstraintViolationException exs = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> violations = exs.getConstraintViolations(); for (ConstraintViolation<?> item : violations) {
errorInfo = errorInfo + "[" + item.getMessage() + "]";
}
} return new Message().setErrorMessage(errorInfo);
}
}Message类是包装请求返回,一般在Controller层使用,用于返回json格式数据
package com.spz.demo.security.bean;import com.fasterxml.jackson.annotation.JsonInclude;import com.spz.demo.security.common.MessageCode;import lombok.Data;import java.io.Serializable;import java.util.HashMap;import java.util.Map;/**
* 请求响应Bean
* 使用JSON包装请求返回,使用jackson库
*
* @author spz
*/@Data@JsonInclude(JsonInclude.Include.NON_NULL)public class Message implements Serializable { private int code ; private String message ; private Map<String,Object> data = new HashMap<String, Object>(); /**
* 自定义返回
* @param code
* @param message
* @return
*/
public Message setMessage(int code, String message){ this.code = code; this.message = message; return this;
} /**
* 返回成功
* @return
*/
public Message setSuccessMessage(){ this.code = MessageCode.SUCCESS ; this.message = "操作成功" ; return this;
} /**
* 返回成功
* @param message
* @return
*/
public Message setSuccessMessage(String message){ this.code = MessageCode.SUCCESS ; this.message = message ; return this;
} /**
* 返回错误
* @param message
* @return
*/
public Message setErrorMessage(String message){ this.code = MessageCode.ERROR ; this.message = message ; return this;
} /**
* 返回警告
* @param message
* @return
*/
public Message setWarnMessage(String message){ this.code = MessageCode.WARN ; this.message = message ; return this;
} /**
* 返回未登录
* @param message
* @return
*/
public Message setNoLoginMessage(String message){ this.code = MessageCode.NO_LOGIN ; this.message = message ; return this;
} /**
* 返回没有权限
* @param message
* @return
*/
public Message setPermissionDeniedMessage(String message){ this.code = MessageCode.PERMISSION_DENIED ; this.message = message ; return this;
}
}Controller 层使用校验
package com.spz.demo.security.controller;import com.spz.demo.security.bean.Message;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.validation.constraints.NotEmpty;/**
* 用户控制器
*
* @author spz
*/@Slf4j(topic = "USER_LOG")@RestController@RequestMapping("/user")@Validated//需要使用Hibernate非实体类参数校验,需要加入此注解public class UserController { @Autowired
StringRedisTemplate redis; /**
* 用户登录
* @return
*/
@PostMapping("/login") public Message login(@NotEmpty(message = "账号不能为空") String account,
@NotEmpty(message = "密码不能为空") String password,
@NotEmpty(message = "验证码不能为空") String verifyCode){ //....
return new Message().setSuccessMessage();
}
}使用时,发送用户登录请求,如果参数校验失败,将返回错误信息:
{ "code": 5000, "message": "[验证码不能为空]", "data": { }
}
作者:萌璐琉璃
链接:https://www.jianshu.com/p/aa8b3163b30a
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦