• 动态封装对象,属性来自json


    需求: 如何动态的获取一个对象的字段,假如一个对象里面有name,age,sex三个字段,我想取name的值,这个name是存在一个json中,json的格式如下[{"key":"name"},{"key":"age"},{"key":"sex"}]先遍历这个json,然后再根据key的值,取对象中对应的属性值。  也就是获取json对应的key的value,封装到对象中。

    GPT给出的答案:

    1. 在 Java 中,你可以按照以下步骤动态获取一个对象的字段:
    2. 1. 遍历 JSON 数组,获取每个对象的 `key` 值。
    3. 2. 使用获取到的 `key` 值作为属性名称,利用 Java 反射机制获取对象的对应属性值。
    4. 下面是一个示例代码:
    5. import com.fasterxml.jackson.databind.JsonNode;
    6. import com.fasterxml.jackson.databind.ObjectMapper;
    7. import java.util.List;
    8. public class Main {
    9. public static void main(String[] args) throws Exception {
    10. String jsonStr = "[{\"key\":\"name\"},{\"key\":\"age\"},{\"key\":\"sex\"}]";
    11. ObjectMapper objectMapper = new ObjectMapper();
    12. List data = objectMapper.readValue(jsonStr, List.class);
    13. Person person = new Person("John", 25, "male");
    14. for (JsonNode item : data) {
    15. String key = item.get("key").asText();
    16. Object value = getValueByKey(person, key);
    17. System.out.println(key + ": " + value);
    18. }
    19. }
    20. public static Object getValueByKey(Object obj, String key) throws Exception {
    21. return obj.getClass().getMethod("get" + capitalize(key)).invoke(obj);
    22. }
    23. public static String capitalize(String str) {
    24. if (str == null || str.isEmpty()) {
    25. return str;
    26. }
    27. return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    28. }
    29. }
    30. class Person {
    31. private String name;
    32. private int age;
    33. private String sex;
    34. public Person(String name, int age, String sex) {
    35. this.name = name;
    36. this.age = age;
    37. this.sex = sex;
    38. }
    39. public String getName() {
    40. return name;
    41. }
    42. public int getAge() {
    43. return age;
    44. }
    45. public String getSex() {
    46. return sex;
    47. }
    48. }
    49. 这段代码将输出:
    50. name: John
    51. age: 25
    52. sex: male
    53. 请注意,上述代码中的 `Person` 类是一个简单的示例,具有 `name`、`age` 和 `sex` 三个字段,并为每个字段提供了对应的 `get` 方法。你可以根据你的实际需求修改代码以适应你的对象结构和命名规则。

    问题: 基于上面的问题,那要是想设置对象属性值呢?

    GPT的答案:

    1. 如果你想设置对象的属性值,你可以按照以下步骤进行操作:
    2. 1. 遍历 JSON 数组,获取每个对象的 `key` 值和对应的属性值。
    3. 2. 使用获取到的 `key` 值作为属性名称,利用 Java 反射机制设置对象的属性值。
    4. 下面是一个示例代码:
    5. import com.fasterxml.jackson.databind.JsonNode;
    6. import com.fasterxml.jackson.databind.ObjectMapper;
    7. import java.util.List;
    8. public class Main {
    9. public static void main(String[] args) throws Exception {
    10. String jsonStr = "[{\"key\":\"name\",\"value\":\"John\"},{\"key\":\"age\",\"value\":25},{\"key\":\"sex\",\"value\":\"male\"}]";
    11. ObjectMapper objectMapper = new ObjectMapper();
    12. List data = objectMapper.readValue(jsonStr, List.class);
    13. Person person = new Person();
    14. for (JsonNode item : data) {
    15. String key = item.get("key").asText();
    16. Object value = item.get("value").asText();
    17. setValueByKey(person, key, value);
    18. }
    19. System.out.println(person);
    20. }
    21. public static void setValueByKey(Object obj, String key, Object value) throws Exception {
    22. obj.getClass().getMethod("set" + capitalize(key), value.getClass()).invoke(obj, value);
    23. }
    24. public static String capitalize(String str) {
    25. if (str == null || str.isEmpty()) {
    26. return str;
    27. }
    28. return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    29. }
    30. }
    31. class Person {
    32. private String name;
    33. private int age;
    34. private String sex;
    35. public Person() {
    36. }
    37. public String getName() {
    38. return name;
    39. }
    40. public void setName(String name) {
    41. this.name = name;
    42. }
    43. public int getAge() {
    44. return age;
    45. }
    46. public void setAge(int age) {
    47. this.age = age;
    48. }
    49. public String getSex() {
    50. return sex;
    51. }
    52. public void setSex(String sex) {
    53. this.sex = sex;
    54. }
    55. @Override
    56. public String toString() {
    57. return "Person{" +
    58. "name='" + name + '\'' +
    59. ", age=" + age +
    60. ", sex='" + sex + '\'' +
    61. '}';
    62. }
    63. }
    64. 这段代码将输出:
    65. Person{name='John', age=25, sex='male'}
    66. 请注意,上述代码中的 `Person` 类是一个简单的示例,具有 `name`、`age` 和 `sex` 三个字段,并为每个字段提供了对应的 `get` 和 `set` 方法。你可以根据你的实际需求修改代码以适应你的对象结构和命名规则。

    具体在工作中的处理逻辑:

    1. 1. Mysql 任务属性字段已经确认,例如字段已经有了name,age
    2. 2. 变更:属性字段可配置,即支持用户前端设置,例如用户需要添加属性 地址address,联系方式phone等字段,字段个数不定。同时支持可以设置默认值或者选项值,例如:性别:男、女
    3. 3. 要求:在不修改Mysql结构的情况下,支持变更要求
    4. 4. 解决:① 设计规则,形成json规则字符串。
    5. 在创建任务的时候记录 此时用户需要的字段,若是已经存在的字段-则直接记录。 若是新添加的属性,则直接记录。
    6. ② 设置Mysql对应结果字段,原有字段不变,例如:name,age。动态字段可以在表中新增一个custom_field,数据是json形式的,例如[{"key":"我的自定义标签","value":"val2"}]保存动态字段结果。
    7. 交互如下:
    8. ③ 结果返回前端展示:查询数据库,将对象转换JSON,返回前端。JSON具体格式前后端商量即可。
    9. ④ 前端提交参数入库(编辑):JSON转换对象,操作数据库保存。
    10. 5. 技术:JSON和反射
    11. [
    12. {
    13. "canUpdate": 1,
    14. "enable": 1,
    15. "fieldName": "affiliatedCompany", //对应mysql表字段affiliated_company
    16. "id": 11,
    17. "inputBox": 1,
    18. "insertTime": "2023-09-05 15:45:02",
    19. "remark": "",
    20. "sort": 10,
    21. "status": 1,
    22. "tag": "所属公司", //字段的中文含义,在页面显示
    23. "type": 1,
    24. "updateTime": "2023-09-14 17:55:04"
    25. },
    26. {
    27. "canUpdate": 1,
    28. "enable": 1,
    29. "fieldName": "url", //对应mysql表字段url
    30. "id": 64,
    31. "inputBox": 1,
    32. "insertTime": "2023-10-09 09:42:19",
    33. "remark": "",
    34. "status": 1,
    35. "tag": "网址",
    36. "type": 1,
    37. "updateTime": "2023-10-09 11:14:34"
    38. },
    39. {
    40. "canUpdate": 1,
    41. "dicInfoList": [
    42. {
    43. "dicValue": "val1",
    44. "id": 104,
    45. "tagLibraryId": 68
    46. },
    47. {
    48. "dicValue": "val2",
    49. "id": 105,
    50. "tagLibraryId": 68
    51. },
    52. {
    53. "dicValue": "val3",
    54. "id": 106,
    55. "tagLibraryId": 68
    56. }
    57. ], //下拉框的可选项
    58. "enable": 1,
    59. "fieldName": "", //自定义添加的,没有mysql对应字段,这个值就是空字符串
    60. "id": 68,
    61. "inputBox": 2,
    62. "insertTime": "2024-01-28 14:21:24",
    63. "remark": "",
    64. "status": 1,
    65. "tag": "我的自定义标签", //自定义添加的,页面显示
    66. "type": 1,
    67. "updateTime": "2024-01-28 14:21:24"
    68. }
    69. ]
    70. 相关代码Util
    71. /**
    72. * @description: 将 对象中的属性值 ,转换json
    73. * @return: void
    74. * @author: hezha
    75. * @time: 2023/9/12 16:19
    76. */
    77. public static void transData(net.sf.json.JSONArray jsonArray, Object obj) {
    78. try {
    79. for(int i=0; i< jsonArray.size() ;i++){
    80. net.sf.json.JSONObject jsonObject = jsonArray.getJSONObject(i);
    81. String key = jsonObject.getString("key");
    82. String field = jsonObject.getString("field");
    83. if(org.apache.commons.lang3.StringUtils.isNotEmpty(field)){
    84. //有值,代表是基础指标,数据库就会存在对应的字段
    85. Object value = getValueByKey(obj, field);
    86. jsonObject.put("value", value!=null?value:"");
    87. }else{
    88. //无值,就是这个json不是基础字段,是扩展字段,就是存储在custom_field中的
    89. Object customField = getValueByKey(obj, "customField");
    90. if(customField != null){
    91. String customFieldStr = (String) customField;
    92. JSONArray customFieldArr = JSONArray.fromObject(customFieldStr);
    93. for(int j= 0; j< customFieldArr.size(); j++){
    94. JSONObject customFieldJson = customFieldArr.getJSONObject(j);
    95. String customFieldKey = customFieldJson.getString("key");
    96. String customFieldValue = customFieldJson.getString("value");
    97. if(key.equals(customFieldKey)){
    98. jsonObject.put("value", customFieldValue);
    99. }
    100. }
    101. }
    102. }
    103. }
    104. }catch (Exception e){
    105. e.printStackTrace();
    106. }
    107. }
    108. public static Object getValueByKey(Object obj, String key) throws Exception {
    109. return obj.getClass().getMethod("get" + capitalize(key)).invoke(obj);
    110. }
    111. public static String capitalize(String str) {
    112. if (str == null || str.isEmpty()) {
    113. return str;
    114. }
    115. return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    116. }
    117. public static void setValueByKey(Object obj, String key, Object value) throws Exception {
    118. obj.getClass().getMethod("set" + capitalize(key), value.getClass()).invoke(obj, value);
    119. }
    120. /**
    121. * @description: 将json字符串转换对用的对象
    122. * @return: java.lang.Object
    123. * @author: hezha
    124. * @time: 2023/9/5 20:16
    125. */
    126. public static Object transObj(String jsonStr, Object obj){
    127. JSONArray array = new JSONArray();
    128. try {
    129. JSONArray jsonArray = JSONArray.fromObject(jsonStr);
    130. for(int i=0; i< jsonArray.size(); i++){
    131. JSONObject jsonObject = jsonArray.getJSONObject(i);
    132. String field = jsonObject.get("field") != null? jsonObject.getString("field"):"";
    133. Object value = jsonObject.get("value") != null? jsonObject.get("value"):"";
    134. if(com.wenge.util.StringUtils.isNotEmpty(field)){
    135. //字段不为空,就是基础字段,数据库中就有字段来保存
    136. Helper.setValueByKey(obj, field, value);
    137. }else{
    138. JSONObject json = new JSONObject();
    139. //如果是null 就是扩展字段,所有的扩展字段使用一个json 存储在custom_field中
    140. String key = jsonObject.getString("key");
    141. json.put("key", key);
    142. json.put("value", value);
    143. array.add(json);
    144. }
    145. }
    146. if(array.size() > 0){
    147. setValueByKey(obj, "CustomField", array.toString());
    148. }
    149. }catch (Exception e){
    150. e.printStackTrace();
    151. }
    152. return obj;
    153. }

  • 相关阅读:
    DFS专题训练1
    报错记录—feign转对象为linkedHashMap
    正雅齿科儿童咬合诱导及青少年隐形矫治线上线下融合峰会成功开展
    Matlab之查询子字符串在字符串中的起始位置函数strfind
    Python OpenCV 视频抽帧处理并保存
    ESP8266-Arduino编程实例-BMA400加速度传感器驱动
    基于springboot实现多线程抢锁的demo
    进程管理命令 动态监控进程 rpm yum
    如何实现多个不同目录下的Anaconda软件环境切换
    企业专线成本高?贝锐蒲公英轻松实现财务系统远程访问
  • 原文地址:https://blog.csdn.net/zhanghe687/article/details/132802692