一、需求描述
我们开发过程中遇到过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; |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| 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 { |
| |
| 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]); |
| |
| 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) { |
| |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| public class ClassInstanceFactory { |
| |
| public ClassInstanceFactory() {} |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| |
| |
| |
| 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系列激活码

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)