该文章为原创(转载请注明出处):如何使SpringMVC的表单和get申请参数反对json转换? – 简书 (jianshu.com)
实在业务场景
前端申请须要表单传递json字符串或者get申请参数携带了json字符串的数据
后端只能在格局上做斗争?
例如:
前端表单
userJson:{"name":"xxx", "phone":"123"}
前端Get申请
/user/test?userJson=%7B%22name%22%3A%22xxx%22%2C%20%22phone%22%3A%22123%22%7D
后端接管表单1
@GetMapping("test.do")
public RestResponse<Void> test(@ModelAttribute String userJson) {
body.setUser(JSON.parseObject(userJson, User.class));
// service.handleUser(body);
}
@Data
static class User {
private String phone;
private String name;
}
后端接管表单2
@GetMapping("test.do")
public RestResponse<Void> test(@ModelAttribute TestBody body) {
body.setUser(JSON.parseObject(body.getUserJson(), User.class));
// service.handleUser(body);
}
@Data
static class TestBody {
private String userJson;
}
static class User {
private String phone;
private String name;
}
后端接管Get申请
@GetMapping("test.do")
public RestResponse<Void> test(@RequestParam String userJson) {
body.setUser(JSON.parseObject(userJson, User.class));
// service.handleUser(body);
}
@Data
static class User {
private String phone;
private String name;
}
反对json的解决方案
利用springmvc提供的@ControllerAdvice切面,在WebDataBinder中退出应用json反序列化的形式
来进行string与各种类型的转换
package com.nuonuo.accounting.guiding.support.spring;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.TypeUtils;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import java.util.Set;
import static java.util.Collections.singleton;
/**
* Fastjson来主动绑定参数
* 反对表单、get申请参数
*
* @author uhfun
* @see RequestMappingHandlerAdapter#initControllerAdviceCache()
* 寻找@ControllerAdvice切面下@InitBinder注解的办法
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#INIT_BINDER_METHODS
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDataBinderFactory(org.springframework.web.method.HandlerMethod)
* 依据切面构建InitBinderMethod办法
* @see org.springframework.web.method.annotation.InitBinderDataBinderFactory#initBinder
* 初始化binder时反射调用
* @see ModelAttribute
*/
@ControllerAdvice
public class StringToAnyObjectSupport {
private static volatile boolean INITIALIZED = false;
@InitBinder
public void initStringToAnyObjectConverter(WebDataBinder dataBinder) {
GenericConversionService conversionService;
if (dataBinder.getConversionService() instanceof GenericConversionService) {
if (!INITIALIZED) {
conversionService = (GenericConversionService) dataBinder.getConversionService();
conversionService.addConverter(new StringToAnyObjectConverter());
INITIALIZED = true;
}
} else {
throw new IllegalStateException("dataBinder的ConversionService不是GenericConversionService类型实例");
}
}
static class StringToAnyObjectConverter implements GenericConverter {
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return singleton(new ConvertiblePair(String.class, Object.class));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> type = targetType.getType();
if (TypeUtils.getClassFromMapping(type.getName()) != null) {
return TypeUtils.cast(source, type, ParserConfig.getGlobalInstance());
} else {
return JSON.parseObject((String) source, type);
}
}
}
}
如何应用?
后端接管表单1
@GetMapping("test.do")
public RestResponse<Void> test(@ModelAttribute("userJson") User user) {
}
static class User {
private String phone;
private String name;
}
后端接管表单2
@GetMapping("test.do")
public RestResponse<Void> test(@ModelAttribute TestBody body) {
User user = body.getUserJson();
// service.handleUser(body);
}
@Data
static class TestBody {
private User userJson;
}
static class User {
private String phone;
private String name;
}
后端接管Get申请
@GetMapping("test.do")
public RestResponse<Void> test(@RequestParam User userJson) {
}
@Data
static class User {
private String phone;
private String name;
}
该文章为原创(转载请注明出处):如何使SpringMVC的表单和get申请参数反对json转换? – 简书 (jianshu.com)
发表回复