CommonsBeanutils1
commons-beanutils 是 Apache 提供的一个用于操作 JAVA bean 的工具包。里面提供了各种各样的工具类,让我们可以很方便的对 bean 对象的属性进行各种操作。
PropertyUtils
org.apache.commons.beanutils.PropertyUtils
类使用 Java 反射 API 来调用 Java 对象上的通用属性 getter 和 setter 操作的实用方法。这些方法的具体使用逻辑其实是由 org.apache.commons.beanutils.PropertyUtilsBean
来实现的。
这个类有个共有静态方法 getProperty()
,接收两个参数 bean (类对象)和 name(属性名),方法会返回这个类的这个属性的值。
1 | PropertyUtils.getProperty(new Cat(), "name"); |
类似这样的代码就会自动找到name属性的getter方法,也就是 getName ,然后调用,获得返回值。除此之外PropertyUtils.getProperty 还支持递归获取属性,比如a对象中有属性b,b对象中有属性c,我们可以通过PropertyUtils.getProperty(a, “b.c”); 的方式进行递归获取。通过这个方法,使用者可以很方便地调用任意对象的getter,适用于在不确定JavaBean是哪个类对象时使用。
然后这里就发现在TemplatesImpl
的利用链中是有一个方法getOutputProperties()
这个方法是outputProperties
的getter,所以我们就可以利用这点去触发。
对于readObject的选择上,用了优先队列PriorityQueue
类的readObject,因为他readObject中调用了了 heapify() 方法, heapify() 中调用了 siftDown() , siftDown() 中调用了siftDownUsingComparator() , siftDownUsingComparator() 中调⽤的comparator.compare() ,就可以去触发BeanComparator
的compare方法完成调用链。
无cc依赖
这里说一下无cc依赖的改造,主要先分析当前哪里用到了cc的依赖,
当我们传入的comparator为空的时候他会去调用cc依赖中的ComparableComparator
那这其实就是找一个类来代替这个类,这个类的要求实现java.util.Comparator 接口,实现 java.io.Serializable 接口,Java、shiro或commons-beanutils自带,且兼容性强
这里用p神发现的一个类CaseInsensitiveComparator
这个是 java.lang.String 类下的一个内部私有类,其实现了
Comparator 和 Serializable ,且位于Java的核心代码中,兼容性强,是一个完美替代品。
我们通过 String.CASE_INSENSITIVE_ORDER 即可拿到上下文中的 CaseInsensitiveComparator 对象,用它来实例化BeanComparator
所以就可以直接写出需要cc的cb1链
1 | InputStream inputStream = Test.class.getResourceAsStream("Evil.class"); |