2018-03-29 SpringCloud 下划线参数丢失

场景

遇到一个不常见的问题:
当Controller的参数为 Model参数绑定形式,且参数以下划线开头时,取不到参数,丢失了。

其实这篇文章和SpringCloud关系不大,但是属于Spring家族的相关内容。

例子:

@RestController
public class HealthyController {

    @RequestMapping(value = "/test/param", method = RequestMethod.GET)
    public String testParam(ParamModel param) {
        return param.toString();
    }
    

    public static class ParamModel {
        private String _api;
        private String _app;
    }

}


原理

一言不合翻源码:比Google还快

//WebDataBinder.java

public static final String DEFAULT_FIELD_MARKER_PREFIX = "_";

protected void checkFieldMarkers(MutablePropertyValues mpvs) {
        if (getFieldMarkerPrefix() != null) {
            String fieldMarkerPrefix = getFieldMarkerPrefix();
            PropertyValue[] pvArray = mpvs.getPropertyValues();
            for (PropertyValue pv : pvArray) {
                if (pv.getName().startsWith(fieldMarkerPrefix)) {
                    String field = pv.getName().substring(fieldMarkerPrefix.length());
                    if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {
                        Class fieldType = getPropertyAccessor().getPropertyType(field);
                        mpvs.add(field, getEmptyValue(field, fieldType));
                    }
                    mpvs.removePropertyValue(pv);
                }
            }
        }
    }

这里的含义就是 如果你的URL或者Form里面有 下划线开头的参数,他就给你擦了。

2018-03-29 SpringCloud 下划线参数丢失_第1张图片
稳住别慌问题不大.png

具体来讲:

  1. 只要你有下划线开头的变量,就给你擦了。
  2. 如果被下划线的变量,还有对应的原始下划线变量,并且没有传原始变量,则填了个空值。

还有这种操作?

问题是谁会用下划线开头的变量?

答曰:PHP,C++,C,Python,谁都有可能。。。。

解决办法

request 里面是可以拿到的,要不就放在ThreadLocal里面?。。
要么,就别用下划线了?
要不,就继承这个DataBinder,替换他的设置?

你可能感兴趣的:(2018-03-29 SpringCloud 下划线参数丢失)