博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
踩坑之变量命名
阅读量:6914 次
发布时间:2019-06-27

本文共 2281 字,大约阅读时间需要 7 分钟。

hot3.png

###背景 应用中需要内置几个特殊字段(createUser,updateUser,createTime,updateTime,status,batchId,source,id)来记录数据导入的状态。要求这几个字段不和用户自定义的业务字段冲突,就考虑选择的内置字段名称要尽反人类一点,和常规的字段命名习惯相悖。

使用的开发技术照常是Java,SpringMVC,MyBatis。Java的变量命名规则: 变量名大小写敏感. 一个变量名字可以是任意合法的标示符,即一个不限长度的 Unicode字母、数字, 以字母, "$", 或 "_"开头。惯例以字母开头定义变量名 , 而不是 "$" 或 "_"。所以就考虑变量前后都缀上"_"。 然后就开始踩坑。

###以“_”开头 问题:后台接收请求数据后,在SpringMVC解析绑定参数时参数值丢失了。

原因:因为WebDataBind在解析绑定请求参数到变量之前,会做checkFieldDefaults(),checkFieldMarkers()。 默认地,CheckFieldDefaults会把前缀“!”的请求参数的值当作被前缀的参数的默认值,然后把把前缀“!”的请求参数删除。checkFieldMarkers会给被前缀"_"的请求参数在空值的状态下填上设定好的默认的"空值",然后把把前缀“_”的请求参数删除。2段代码如下:

protected void checkFieldDefaults(MutablePropertyValues mpvs) {	if (getFieldDefaultPrefix() != null) {		String fieldDefaultPrefix = getFieldDefaultPrefix();		PropertyValue[] pvArray = mpvs.getPropertyValues();		for (PropertyValue pv : pvArray) {			if (pv.getName().startsWith(fieldDefaultPrefix)) {				String field = pv.getName().substring(fieldDefaultPrefix.length());				if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {					mpvs.add(field, pv.getValue());				}				mpvs.removePropertyValue(pv);			}		}	}}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);			}		}	}}

###以“$”开头 下划线不行,那就用$吧。SpringMVC是成功绑定获取到值了。但是接下来用Mybatis拼接sql时出错了。$开头的参数全部找不到getter方法,代码跟踪走起。发现mybatis使用org.apache.ibatis.reflection.Reflector反射获取参数值。在初始化Reflector填充<参数,getter>映射获取getter的时,对getter方法进行过滤,规则如下:

private boolean isValidPropertyName(String name) {    return !(name.startsWith("$") || "serialVersionUID".equals(name) || "class".equals(name));}

过滤掉以$开头的getter。

###最后 后来就extends一下ConfigurableWebBindingInitializer,把WebDataBind的fieldMarkerPrefix设置成null。

也许是解决方案不对,才会用到反人类的变量命名,才会踩到坑。

转载于:https://my.oschina.net/braveCS/blog/703816

你可能感兴趣的文章
leetcode121买股票
查看>>
SQL SERVER 2008中启用相应的功能
查看>>
Implementing a small Cron service in C# - CodeProject
查看>>
REST::Neo4p – PERL版本的”OGM”
查看>>
linux中service *** start与直接运行/usr/bin/***的区别
查看>>
剑指offer题目java实现
查看>>
Linux内核之于红黑树and AVL树
查看>>
LoaderManager使用详解(二)---了解LoaderManager
查看>>
EtherCAT对PHY有要求?
查看>>
ios应用内下载并安装另一个应用
查看>>
SQL GROUP BY 语句
查看>>
简单介绍一些HTML代码(字幕、音频和视频)
查看>>
Java——复选框:JCheckBox
查看>>
用android模拟器Genymotion定位元素
查看>>
iOS学习:UILabel和sizeWithFont方法
查看>>
java-学习-自我规划
查看>>
在Ubuntu下搭建ASP.NET 5开发环境
查看>>
互联网时代下,数据产业正成为一种新的生意
查看>>
咸阳供电公司助力“智慧城市”建设
查看>>
OpenDaylight的Helium(氦)版本安装
查看>>