介绍
在SpringBoot中,post提交的JSON数据时候,自动将参数信息转为实体对象,并且校验字段信息
实现
POM文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.silly.demo</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<description>spring boot 样例代码</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!--打包或编译跳过单元测试-->
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
</dependencies>
</project>
JSONParam 注解
定义参数的key值
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author :silly
* @description:JSON参数
* @date :2021/7/15 16:23
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface JSONParam {
/**
* 表单提交的json字符串字段名
*/
String value();
}
JSONMethodArgumentResolver 方法转换器
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.silly.demo.utils.ValidatorUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author :silly
* @description:json方法转换器
* @date :2021/7/15 16:24
*/
public class JSONMethodArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 判断是否支持
*
* @param parameter
* @return
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JSONParam.class);
}
/**
* 参数转换
*
* @param parameter
* @param container
* @param request
* @param factory
* @return
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
NativeWebRequest request, WebDataBinderFactory factory) {
//获取方法体上的的JSONParam注解
JSONParam paramAnnotation = parameter.getParameterAnnotation(JSONParam.class);
//获取注解上带的参数名
String paramName = paramAnnotation.value();
//获取提交的参数值
String paramValue = request.getParameter(paramName);
// 开始处理空格
Map<String, Object> map = (Map<String, Object>) JSONObject.parse(paramValue);
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
Map<String, Object> removeSpaceMap = new HashMap<>();
for (Map.Entry<String, Object> entry : entrySet) {
if (entry.getValue() instanceof String) {
removeSpaceMap.put(entry.getKey(), ((String) entry.getValue()).trim());
} else {
removeSpaceMap.put(entry.getKey(), entry.getValue());
}
}
//转换为实体对象
Type type = parameter.getGenericParameterType();
Object object = JSON.parseObject(JSON.toJSONString(removeSpaceMap), type);
if (object != null) {
//调用validator 校验参数
ValidatorUtils.validate(object);
}
return object;
}
}
ValidatorUtils参数校验工具类
import org.hibernate.validator.HibernateValidator;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
/**
* @author :silly
* @description:校验工具类
* @date :2021/7/15 17:33
*/
public class ValidatorUtils {
private ValidatorUtils() {
}
private static Validator validator;
/**
* 获取实例信息
*
* @return
*/
public static Validator getInstance() {
if (validator == null) {
synchronized (ValidatorUtils.class) {
if (validator == null) {
validator = Validation.byProvider(HibernateValidator.class).
configure().failFast(false).buildValidatorFactory().getValidator();
}
}
}
return validator;
}
/**
* 校验
*/
public static <T> void validate(T object) {
StringBuilder sb = new StringBuilder();
Set<ConstraintViolation<T>> constraintViolations = getInstance().validate(object);
if (constraintViolations != null && constraintViolations.size() > 0) {
for (ConstraintViolation<T> constraintViolation : constraintViolations) {
sb.append(constraintViolation.getMessage());
}
throw new RuntimeException(sb.toString());
}
}
}
WebConfiguration 将解析器加入到框架中
import com.silly.demo.web.resolver.method.JSONMethodArgumentResolver;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* @author :silly
* @description:web 配置
* @date :2021/4/14 11:08
*/
@Configuration
@AllArgsConstructor(onConstructor = @_(@Autowired))
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new JSONMethodArgumentResolver());
}
}
案例应用
User 用户实体
@Getter
@Setter
public class User {
@NotEmpty(message = "用户名不能为空")
private String userName;
@NotEmpty(message = "密码不能为空")
private String passWord;
@NotNull(message = "爱好不能为空")
private List<String> hobby;
}
UserController接口使用
@RestController
@RequestMapping(value = "/user")
public class UserController {
/**
* 用户信息
*
* @param user
* @return
*/
@RequestMapping(value = "/add")
public RestResponse add(@JSONParam("user") User user) {
return RestResponse.success("成功", user);
}
}
结果展示
执行失败
-
请求参数
-
执行结果
执行成功
-
请求参数
-
执行结果
{
"success": true,
"message": "成功",
"data": {
"userName": "张三",
"passWord": "111111",
"hobby": [
"乒乓球",
"跳舞",
"写代码"
]
}
}