BeanUtils getProperty的一个坑
背景介绍
短信平台需要支持多种短信的发送,短信文案皆不相同,假设有以下类
@Data
public abstract class MsgBase {public static final String ALIBABA_GROUP = "阿里巴巴集团";public static final String ANT_GROUP = "蚂蚁集团";/*** 接收人手机号*/private String receivePhone;/*** 接收人姓名*/private String name;/*** 咨询电话*/private String consultationPhone;/*** 集团名称*/private String groupName;/*** 内容模版* 模版内容中的变量使用${}引用,其中变量名要在成员变量中*/private String template;/*** 发送*/public void send() {// 替换模版中的变量replaceTemplate();// 省略发送 。。。}/*** 替换模版*/private void replaceTemplate() {// 把所有属性压到Map中Map<String, Object> fieldParamMap = Maps.newConcurrentMap();try {for (Field field : this.getClass().getDeclaredFields()) {fieldParamMap.put(field.getName(), BeanUtils.getProperty(this, field.getName()));}for (Field field : this.getClass().getSuperclass().getDeclaredFields()) {fieldParamMap.put(field.getName(), BeanUtils.getProperty(this, field.getName()));}// 变量替换 ...} catch (Exception e) {throw new RuntimeException("send message Error!", e);}}
}
/*** 充值通知短信*/
@Data
public class RechargeNoticeMsgBase extends MsgBase {/*** 充值日期*/private String date;/*** 充值金额*/private String amount;
}
/*** 快递收获通知短信*/
@Data
public class ExpressHarvestNoticeMsgBase extends MsgBase {/*** 取件码*/private String code;/*** 快递柜*/private String expressDeliveryCabinet;
}
在不同场景下会构造不同的短信,一开始短信中没有集团名称,后来才有的需求,后面同学这考虑到集团名称只有几个,因此在Base类中定义了几个静态常量,以供子类共享,但是却带来了问题:
public class MsgTestMain {public static void main(String[] args) {RechargeNoticeMsgBase msg = new RechargeNoticeMsgBase();msg.setAmount("100");msg.setDate("2020-12-20");msg.setGroupName(MsgBase.ALIBABA_GROUP);msg.setConsultationPhone("13123457890");msg.setTemplate("【companyName】 ${name} 您好,您在${date}充值了${amount}元,如有疑问请联系 ${consultationPhone}");msg.setReceivePhone("13112345678");msg.setName("张三");msg.send();}
}
运行测试类,发现如下异常:
Exception in thread "main" java.lang.RuntimeException: send message Error!at beanutils.MsgBase.replaceTemplate(MsgBase.java:68)at beanutils.MsgBase.send(MsgBase.java:49)at beanutils.MsgTestMain.main(MsgTestMain.java:14)
Caused by: java.lang.NoSuchMethodException: Unknown property 'ALIBABA_GROUP' on class 'class beanutils.RechargeNoticeMsgBase'at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1270)at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:809)at org.apache.commons.beanutils.BeanUtilsBean.getNestedProperty(BeanUtilsBean.java:711)at org.apache.commons.beanutils.BeanUtilsBean.getProperty(BeanUtilsBean.java:737)at org.apache.commons.beanutils.BeanUtils.getProperty(BeanUtils.java:380)at beanutils.MsgBase.replaceTemplate(MsgBase.java:64)
也就是在执行 BeanUtils.getProperty(“ALIBABA_GROUP”)发生异常,当前实例没有这个Field!这是为什么呢?BeanUtils内部是怎么实线的呢?
原理说明
跟踪代码:
org.apache.commons.beanutils.BeanUtils#getProperty
-> org.apache.commons.beanutils.BeanUtilsBean#getProperty
-> org.apache.commons.beanutils.BeanUtilsBean#getNestedProperty
-> org.apache.commons.beanutils.PropertyUtilsBean#getNestedProperty
-> org.apache.commons.beanutils.PropertyUtilsBean#getSimpleProperty
...
-> org.apache.commons.beanutils.PropertyUtilsBean#getPropertyDescriptors(java.lang.Class)
-> java.beans.Introspector#getBeanInfo(java.lang.Class<?>)
-> java.beans.Introspector#getBeanInfo()
-> java.beans.Introspector#getTargetPropertyInfo
getTargetPropertyInfo方法部分代码如下图:
其中getPublicDeclareMethods方法如下:
通过以上代码可知BeanUtils获取Field并未通过java.lang.Class#getFields来获取,而是通过getMethods来获取,这个方法返回的是public的方法,并且排除了静态方法,因此想通过BeanUtils获取静态属性是不行的!
解决方案
- 定义一个常量类,避免使用静态变量
- 修改replaceTemplae,通过Modifier.isStatic方法判断是否是静态变量,如果是将其排除
BeanUtils getProperty的一个坑相关推荐
- 最近,我在Spring的BeanUtils踩了不少坑
点击关注公众号,实用技术文章及时了解 来源:www.jianshu.com/p/357b55852efc 背景 最近项目中在和第三方进行联调一个接口,我们这边发送http请求给对方,然后接收对方的回应 ...
- 困扰多日的C#调用Haskell问题竟然是Windows的一个坑
最近一直被C#调用Haskell时的"尝试读取或写入受保护的内存"问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected ...
- SAP WM LT10事务代码的一个坑?
SAP WM LT10事务代码的一个坑? 执行事务代码LT10,试图将storage type SAM下物料库存的几个SU转入同一个货架上.Storage type SAM有启用SUM功能的. 执行, ...
- mysql div 没有小数,mysql order by limit 的一个坑
mysql order by limit 的一个坑 分页查询的时候遇到的坑: 发现的问题: 对单个无索引的字段进行排序后limit .发现当被排序字段有相同值时并且在limit范围内,取的值并不是正常 ...
- 移动端开发碰到一个坑
移动端开发真是不断踩坑,今天在做一个移动端的组件,又发现了一个坑,记录到日志里面,做个记录,以便以后再遇到这个问题有个记录可以参考. 在ios中的chrome浏览器中,手指从屏幕上方移动出屏幕(一定要 ...
- centos 升级mysql_CentOS 7下升级MySQL5.7.23的一个坑
发现CentOS 7下升级MySQL5.7.23的一个坑,以前面升级到MySQL 5.7.23的一个集群为例 在我们环境下打开文件描述符个数的参数open_files_limit在MySQL 5.6. ...
- 0705 - 说说 NSPopover 的一个坑
今天开发 iTips,遇到一个很诡异的问题:NSOutlineView 中的 NSTableCellView 中的 NSTextField,始终有一个背景色,无论怎么设置都无法去掉.如下图中左侧部分所 ...
- nodejs request module里的json参数的一个坑
今天工作的时候遇到一个坑,在客户端用nodejs给服务器发送HTTP请求,服务器老是报错:In the context of Data Services an unknown internal ser ...
- 记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑
我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也 ...
最新文章
- 深度学习需要掌握的 13 个概率分布(附代码)
- 两位院士同时受聘,山东大学再添强援
- 【论文解读】KDD20 | 图神经网络在生物医药领域的应用
- android 富文本框架_五种JavaScript富文本编辑器,总有一款适合你
- CentOS linux7 设置开机启动服务
- HookProc 和 CallNextHookEx
- 12v驱动光耦用多大的电阻_倍思10000mAh PD快充充电宝拆解,内置多合一双向快充芯片...
- Linux中vectormath无法通过pip安装的解决办法
- ThinkPHP胜出Laravel 近4倍,主流框架性能测试
- 织梦响应式酒店民宿住宿类网站织梦模板(自适应手机端)
- ShadowGun 的学习笔记 - GodRays
- re库中group(), groups(), groupdict() 用法
- 【小应用】社交距离检测
- 前端HTML、CSS学习完整笔记(中下篇)
- excel计数连续负数(正数)
- 【数据分析 —— 认识数据】
- CUDA安装 + tensorflow gpu版本出现的问题:Not creating XLA devices, tf_xla_enable_xla_devices not set
- cad直线和圆弧倒角不相切_CAD圆角、倒角分不清?详细讲解CAD圆角与倒角对象的区别和技巧...
- 迅雷、QQ旋风-链接自动转换(Download link conversion)
- 如何开发一款ios应用程序