【SpringMvc 参数绑定】下划线参数绑定到驼峰字段

【SpringMvc 参数绑定】下划线参数绑定到驼峰字段

 

重写ServletModelAttributeMethodProcessor

package com.bilibili.uosdk.controller.api.server;

import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;

import javax.servlet.ServletRequest;
import javax.validation.Valid;

/**
 * 支持将下划线参数 req param 绑定到 驼峰字段
 * 目前仅对使用了注解 javax.validation.Valid 的实体类参数生效
 * @author : wangjia
 * @date : 2020/6/18 16:55
 */
public class Snake2CamelServletModelAttributeMethodProcessor extends ServletModelAttributeMethodProcessor {
    /**
     * Class constructor.
     *
     * @param annotationNotRequired if "true", non-simple method arguments and
     *                              return values are considered model attributes with or without a
     *                              {@code @ModelAttribute} annotation
     */
    public Snake2CamelServletModelAttributeMethodProcessor(boolean annotationNotRequired) {
        super(annotationNotRequired);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Valid.class);
    }

    @Override
    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
        ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
        Assert.state(servletRequest != null, "No servletRequest");
        ServletRequestDataBinder servletRequestDataBinder = (ServletRequestDataBinder) binder;
        //更换请求参数绑定器
        new SnakeCakeToCamelServletRequestDataBinder(servletRequestDataBinder.getTarget()).bind(servletRequest);
    }

}
 重写ServletRequestDataBinder
package com.bilibili.uosdk.controller.api.server;

import com.google.common.base.CaseFormat;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.web.bind.ServletRequestDataBinder;

import javax.servlet.ServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * 将下划线风格参数 LOWER_UNDERSCORE 转化为驼峰添加到待绑定参数列表中,供参数绑定使用
 * @author : wangjia
 * @date : 2020/6/18 16:46
 */
public class SnakeCakeToCamelServletRequestDataBinder extends ServletRequestDataBinder {

    public SnakeCakeToCamelServletRequestDataBinder(Object target) {
        super(target);
    }

    /**
     * 将下划线风格参数 LOWER_UNDERSCORE 转化为驼峰添加到  pvs 中,供参数绑定使用
     *
     * @param mpvs    请求参数列表
     * @param request 请求
     */
    @Override
    protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
        List<PropertyValue> pvs = mpvs.getPropertyValueList();
        ArrayList<PropertyValue> extCamelPv = new ArrayList<>();

        HashSet<String> existName = new HashSet<>();
        for (PropertyValue pv : pvs) {
            existName.add(pv.getName());
        }

        for (PropertyValue pv : pvs) {
            String name = pv.getName();
            //如果包含下划线,才尝试添加装成驼峰的 PropertyValue
            if (name.contains("_")) {
                String camelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
                //原参数列表不存在同名参数
                if (!name.equalsIgnoreCase(camelName) && !existName.contains(camelName)) {
                    extCamelPv.add(new PropertyValue(camelName, pv.getValue()));
                }
            }
        }
        pvs.addAll(extCamelPv);
    }

}

配置自定义HandlerMethodArgumentResolver  Snake2CamelServletModelAttributeMethodProcessor添加到配置中

<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean class="com.bilibili.uosdk.controller.api.server.Snake2CamelServletModelAttributeMethodProcessor">
            <constructor-arg value="true"/>
        </bean>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

发表评论

电子邮件地址不会被公开。 必填项已用*标注