该文章为原创(转载请注明出处):如何使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);}@Datastatic 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);} @Datastatic 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);}@Datastatic 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 */@ControllerAdvicepublic 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);} @Datastatic 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) {  }@Datastatic class User {    private String phone;    private String name;}
该文章为原创(转载请注明出处):如何使SpringMVC的表单和get申请参数反对json转换? - 简书 (jianshu.com)