一、需求描述

我们开发过程中遇到过JSON字符串数据赋值到实体对象的属性,一个实体类中可能包含我们之前封装好的实体对象,比如Person.java里面包含Home home,Home.java有String Address,有自定义的Room room属性,然后需要一个这样的字符串给Person赋值

      String jsonString = "name:李明,higher:12,age:32,date:2022-04-09 10-20-21,home.room.size:12,home.address:河北省邯郸市";

之前单级别的类我们可以通过ObjectMapper、Gson去转化到实体类,但是现在是是多级的赋值,我们可以做一个赋值的工厂

二、实际操作一下

Person类
package com.attributeAssignMent;

import java.util.Date;

/**
 * @author zhr_java@163.com
 * @date 2022/4/9 17:01
 */
public class Person {

    private String name;

    private String higher;

    private Integer age;

    private Date date;
    private Home home;

    @Override
    public String toString() {

        return "Person{" +
                "name='" + name + '\'' +
                ", higher='" + higher + '\'' +
                ", age=" + age +
                ", date=" + date +
                ", home=" + home +
                '}';
    }

    public Home getHome() {

        return home;
    }

    public void setHome(Home home) {

        this.home = home;
    }

    public Date getDate() {

        return date;
    }

    public void setDate(Date date) {

        this.date = date;
    }

    public Integer getAge() {

        return age;
    }

    public void setAge(Integer age) {

        this.age = age;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getHigher() {

        return higher;
    }

    public void setHigher(String higher) {

        this.higher = higher;
    }

}

Home类
package com.attributeAssignMent;

/**
 * @author zhr_java@163.com
 * @date 2022/4/10 17:39
 */
public class Home {

    private String address;

    private Room room;

    @Override
    public String toString() {

        return "Home{" +
                "address='" + address + '\'' +
                ", room=" + room +
                '}';
    }

    public Room getRoom() {

        return room;
    }

    public void setRoom(Room room) {

        this.room = room;
    }

    public String getAddress() {

        return address;
    }

    public void setAddress(String address) {

        this.address = address;
    }

}

Room类
package com.attributeAssignMent;

/**
 * @author zhr_java@163.com
 * @date 2022/4/10 17:40
 */
public class Room {
  private String size;

  @Override
  public String toString() {

    return "Room{" +
            "size='" + size + '\'' +
            '}';
  }

  public String getSize() {

    return size;
  }

  public void setSize(String size) {

    this.size = size;
  }

}

StringUtils类
package com.attributeAssignMent;

/**
 * @author zhr_java@163.com
 * @date 2022/4/9 17:03
 */
public class StringUtils {

  public static String initcap(String string) {
    if (string.equals("") || string == null) {
      return string;
    }
    if (string.length() == 1) {
      return string.toUpperCase();
    } else {
      return string.substring(0, 1).toUpperCase() + string.substring(1);
    }
  }
}

BeanUtils类
package com.attributeAssignMent;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author zhr_java@163.com
 * @date 2022/4/9 17:07
 */
public class BeanUtils {
  public static void setValue(Object obj, String value) {
    String result[] = value.split(",");
    for (int i = 0; i < result.length; i++) {
      Object currentObj = obj;
      Object currentObjBefore = obj;
      String attribute[] = result[i].split(":");
      // 添加try防止获取不到属性对象而终止操作
      try {
        // 判断属性名称里面是否有点,如果有点的话就应该是联级
        if (attribute[0].contains(".")) {
          String temp[] = attribute[0].split("\\.");
          // 最后一个该赋值了
          for (int o = 0; o < temp.length - 1; o++) {
            Field field = currentObj.getClass().getDeclaredField(temp[o]);
            Method getMethod =
                currentObj.getClass().getDeclaredMethod("get" + StringUtils.initcap(temp[o]));
            Method setMethod =
                currentObj
                    .getClass()
                    .getDeclaredMethod("set" + StringUtils.initcap(temp[o]), field.getType());

            // 判断该属性未实例化
            if (getMethod.invoke(currentObj) == null) {
              // 创建一个实例
              currentObj = field.getType().getDeclaredConstructor().newInstance();
              setMethod.invoke(currentObjBefore, currentObj);
              currentObjBefore = currentObj;
            } else {
              currentObj = getMethod.invoke(currentObj);
            }
          }

          // 获取成员,这里是为了要获取属性的类型
          Field field = currentObj.getClass().getDeclaredField(temp[temp.length - 1]);
          System.out.println(field);
          Method method =
              currentObj
                  .getClass()
                  .getDeclaredMethod(
                      "set" + StringUtils.initcap(temp[temp.length - 1]), field.getType());
          System.out.println(method);
          Object attributeValue = BeanUtils.convertParam(field.getType().getName(), attribute[1]);
          // 调用方法
          method.invoke(currentObj, attributeValue);
        } else {
          // 根据属性名获取属性对象
          Field field = obj.getClass().getDeclaredField(attribute[0]);
          // 获取属性对应的set方法
          Method method =
              obj.getClass()
                  .getDeclaredMethod("set" + StringUtils.initcap(attribute[0]), field.getType());
          Object attributeValue = convertParam(field.getType().getName(), attribute[1]);
          // 给对象里面的属性赋值
          method.invoke(obj, attributeValue);
        }
      } catch (Exception e) {

      }
    }
  }

  /**
   * 根据类中的属性更改传入属性的类型,此处建议根据实际开发来扩展,建议先把基本的八大类型扩展出来
   *
   * @param attType 属性类型
   * @param value 属性值
   * @return
   */
  public static Object convertParam(String attType, String value) {
    if ("double".equals(attType) || "java.lang.Double".equals(attType)) {
      return Double.parseDouble(value);
    } else if ("int".equals(attType) || "java.lang.Integer".equals(attType)) {
      return Integer.parseInt(value);
    } else if ("java.util.Date".equals(attType)) {
      SimpleDateFormat time;
      if (value.matches("\\d{4}-\\d{2}-\\d{2}")) {
        time = new SimpleDateFormat("yyyy-MM-dd");
      } else if (value.matches("\\d{2}-\\d{2}-\\d{2}")) {
        time = new SimpleDateFormat("HH-mm-ss");
      } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}-\\d{2}-\\d{2}")) {
        time = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
      } else {
        return new Date();
      }
      try {
        return time.parse(value);
      } catch (ParseException e) {
        e.printStackTrace();
        return new Date();
      }

    } else {
      return value;
    }
  }
}

ClassInstanceFactory类
package com.attributeAssignMent;

/**
 * @author zhr_java@163.com
 * @date 2022/4/9 17:20
 */
public class ClassInstanceFactory {

  public ClassInstanceFactory() {}

  /**
   * 实例化对象的创建方法:该对象可以根据传入的字符串结构"属性:内容,属性:内容"
   *
   * @param clazz 要被赋值的目标对象
   * @param value 目标对象被赋的值
   * @param <T> 所有类型对象
   * @return 已经被赋值后的目标对象
   */
  public static <T> T create(Class<?> clazz, String value) {
    try {
      // 通过目标对象的无参构造实例化
      Object obj = clazz.getDeclaredConstructor().newInstance();
      //通过反射设置属性
      BeanUtils.setValue(obj,value);
      return (T) obj;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}

Test类
package com.attributeAssignMent;

/**
 * @author zhr_java@163.com
 * @date 2022/4/9 17:33
 */
public class Test {
  public static void main(String[] args) {
    //测试单级赋值
      String jsonString = "name:李明,higher:12,age:32,date:2022-04-09 10-20-21,home.room.size:12,home.address:河北省邯郸市";
      Person person = ClassInstanceFactory.create(Person.class,jsonString);
    System.out.println(person.toString());
  }
}

效果图:
在这里插入图片描述

关注我的公众号SpaceObj 领取idea系列激活码

posted on 2023-05-10 18:20  张伯灵  阅读(34)  评论(0编辑  收藏  举报