springmvc 参数解析器

需求:
现在有一个实体类,若使用spring mvc自定义的 @RequestBody 会自动注入相应字段名的属性,但这要求字段名和实体类的属性名一致才行,然而由于前期的一些缘故,前端的字段是下划线的形式,不是小驼峰形式,因此无法找到相应的字段,从而无法注入;

解决方案:自定义参数解析器


package golden.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
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 javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

//用于处理前端json传来的对象属性,支持下划线和驼峰
public class RequestBodyBindingHandler implements HandlerMethodArgumentResolver {
    private static MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(RequestBodyBinding.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest httpServletRequest = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        String body = readBody(httpServletRequest);
        Type targetObject = methodParameter.getParameterType();
        return convert(body, targetObject.getTypeName());
    }

    private Object convert(String body, String clazzName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException {
        Class<?> aClass = Class.forName(clazzName);
        Object instance = aClass.getConstructor().newInstance();
        JSONObject jsonObject = JSONObject.parseObject(body);
        Field[] fields = aClass.getDeclaredFields();
        Map<String, Field> fieldsMap = new HashMap<>(fields.length);
        for (int i = 0; i < fields.length; i++) {
            fieldsMap.put(fields[i].getName(), fields[i]);
        }
        jsonObject.forEach((key, val) -> {
            String name = modifyUnderLineToHump(key);
            if (fieldsMap.containsKey(name)) {
                Field field = fieldsMap.get(name);
                field.setAccessible(true);
                try {
                    field.set(instance, val);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        return instance;
    }

    private String modifyUnderLineToHump(String key) {
        char[] chars = key.toCharArray();
        int j = 0;
        boolean bonux = false;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '_') {
                bonux = true;
                continue;
            }
            if (bonux) {
                chars[j++] = (char) (chars[i] & '_');
                bonux = false;
            } else {
                chars[j++] = chars[i];
            }
        }
        char[] chars1 = Arrays.copyOf(chars, j);
        return new String(chars1);
    }


    private String readBody(HttpServletRequest httpServletRequest) throws IOException {
        BufferedReader reader = httpServletRequest.getReader();
        StringBuilder str = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            str.append(line);
        }
        return str.toString();
    }
}

   <mvc:annotation-driven>
       <mvc:argument-resolvers>
           <bean class="golden.utils.RequestBodyBindingHandler"/>
       </mvc:argument-resolvers>
   </mvc:annotation-driven>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值