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

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

GPT给出的答案:

在 Java 中,你可以按照以下步骤动态获取一个对象的字段:

1. 遍历 JSON 数组,获取每个对象的 `key` 值。
2. 使用获取到的 `key` 值作为属性名称,利用 Java 反射机制获取对象的对应属性值。

下面是一个示例代码:


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        String jsonStr = "[{\"key\":\"name\"},{\"key\":\"age\"},{\"key\":\"sex\"}]";

        ObjectMapper objectMapper = new ObjectMapper();
        List<JsonNode> data = objectMapper.readValue(jsonStr, List.class);

        Person person = new Person("John", 25, "male");

        for (JsonNode item : data) {
            String key = item.get("key").asText();
            Object value = getValueByKey(person, key);
            System.out.println(key + ": " + value);
        }
    }

    public static Object getValueByKey(Object obj, String key) throws Exception {
        return obj.getClass().getMethod("get" + capitalize(key)).invoke(obj);
    }

    public static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }
}

class Person {
    private String name;
    private int age;
    private String sex;

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }
}


这段代码将输出:


name: John
age: 25
sex: male


请注意,上述代码中的 `Person` 类是一个简单的示例,具有 `name`、`age` 和 `sex` 三个字段,并为每个字段提供了对应的 `get` 方法。你可以根据你的实际需求修改代码以适应你的对象结构和命名规则。

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

GPT的答案:

如果你想设置对象的属性值,你可以按照以下步骤进行操作:

1. 遍历 JSON 数组,获取每个对象的 `key` 值和对应的属性值。
2. 使用获取到的 `key` 值作为属性名称,利用 Java 反射机制设置对象的属性值。

下面是一个示例代码:


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        String jsonStr = "[{\"key\":\"name\",\"value\":\"John\"},{\"key\":\"age\",\"value\":25},{\"key\":\"sex\",\"value\":\"male\"}]";

        ObjectMapper objectMapper = new ObjectMapper();
        List<JsonNode> data = objectMapper.readValue(jsonStr, List.class);

        Person person = new Person();

        for (JsonNode item : data) {
            String key = item.get("key").asText();
            Object value = item.get("value").asText();
            setValueByKey(person, key, value);
        }

        System.out.println(person);
    }

    public static void setValueByKey(Object obj, String key, Object value) throws Exception {
        obj.getClass().getMethod("set" + capitalize(key), value.getClass()).invoke(obj, value);
    }

    public static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }
}

class Person {
    private String name;
    private int age;
    private String sex;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}


这段代码将输出:

Person{name='John', age=25, sex='male'}


请注意,上述代码中的 `Person` 类是一个简单的示例,具有 `name`、`age` 和 `sex` 三个字段,并为每个字段提供了对应的 `get` 和 `set` 方法。你可以根据你的实际需求修改代码以适应你的对象结构和命名规则。

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

1. Mysql 任务属性字段已经确认,例如字段已经有了name,age
2. 变更:属性字段可配置,即支持用户前端设置,例如用户需要添加属性 地址address,联系方式phone等字段,字段个数不定。同时支持可以设置默认值或者选项值,例如:性别:男、女
3. 要求:在不修改Mysql结构的情况下,支持变更要求
4. 解决:① 设计规则,形成json规则字符串。
		   在创建任务的时候记录 此时用户需要的字段,若是已经存在的字段-则直接记录。 若是新添加的属性,则直接记录。		   
		 ② 设置Mysql对应结果字段,原有字段不变,例如:name,age。动态字段可以在表中新增一个custom_field,数据是json形式的,例如[{"key":"我的自定义标签","value":"val2"}]保存动态字段结果。
         交互如下:		 
		 ③ 结果返回前端展示:查询数据库,将对象转换JSON,返回前端。JSON具体格式前后端商量即可。
		 ④ 前端提交参数入库(编辑):JSON转换对象,操作数据库保存。
5. 技术:JSON和反射


[
			{
				"canUpdate": 1,
				"enable": 1,
				"fieldName": "affiliatedCompany", //对应mysql表字段affiliated_company
				"id": 11,
				"inputBox": 1,
				"insertTime": "2023-09-05 15:45:02",
				"remark": "",
				"sort": 10,
				"status": 1,
				"tag": "所属公司", //字段的中文含义,在页面显示
				"type": 1,
				"updateTime": "2023-09-14 17:55:04"
			},
			{
				"canUpdate": 1,
				"enable": 1,
				"fieldName": "url",  //对应mysql表字段url
				"id": 64,
				"inputBox": 1,
				"insertTime": "2023-10-09 09:42:19",
				"remark": "",
				"status": 1,
				"tag": "网址",
				"type": 1,
				"updateTime": "2023-10-09 11:14:34"
			},
			{
				"canUpdate": 1,
				"dicInfoList": [
					{
						"dicValue": "val1",
						"id": 104,
						"tagLibraryId": 68
					},
					{
						"dicValue": "val2",
						"id": 105,
						"tagLibraryId": 68
					},
					{
						"dicValue": "val3",
						"id": 106,
						"tagLibraryId": 68
					}
				], //下拉框的可选项
				"enable": 1,
				"fieldName": "",  //自定义添加的,没有mysql对应字段,这个值就是空字符串
				"id": 68,
				"inputBox": 2,
				"insertTime": "2024-01-28 14:21:24",
				"remark": "",
				"status": 1,
				"tag": "我的自定义标签", //自定义添加的,页面显示
				"type": 1,
				"updateTime": "2024-01-28 14:21:24"
			}
		   ]


相关代码Util

 /**
     * @description: 将 对象中的属性值 ,转换json
     * @return: void
     * @author: hezha
     * @time: 2023/9/12 16:19
     */
    public static void transData(net.sf.json.JSONArray jsonArray, Object obj) {
        try {
            for(int i=0; i< jsonArray.size() ;i++){
                net.sf.json.JSONObject jsonObject = jsonArray.getJSONObject(i);
                String key = jsonObject.getString("key");
                String field = jsonObject.getString("field");
                if(org.apache.commons.lang3.StringUtils.isNotEmpty(field)){
                    //有值,代表是基础指标,数据库就会存在对应的字段
                    Object value = getValueByKey(obj, field);
                    jsonObject.put("value", value!=null?value:"");
                }else{
                    //无值,就是这个json不是基础字段,是扩展字段,就是存储在custom_field中的
                    Object customField = getValueByKey(obj, "customField");
                    if(customField != null){
                        String customFieldStr = (String) customField;
                        JSONArray customFieldArr = JSONArray.fromObject(customFieldStr);
                        for(int j= 0; j< customFieldArr.size(); j++){
                            JSONObject customFieldJson = customFieldArr.getJSONObject(j);
                            String customFieldKey = customFieldJson.getString("key");
                            String customFieldValue = customFieldJson.getString("value");
                            if(key.equals(customFieldKey)){
                                jsonObject.put("value", customFieldValue);
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    public static Object getValueByKey(Object obj, String key) throws Exception {
        return obj.getClass().getMethod("get" + capitalize(key)).invoke(obj);
    }

    public static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }


    public static void setValueByKey(Object obj, String key, Object value) throws Exception {
        obj.getClass().getMethod("set" + capitalize(key), value.getClass()).invoke(obj, value);
    }



    /**
     * @description: 将json字符串转换对用的对象
     * @return: java.lang.Object
     * @author: hezha
     * @time: 2023/9/5 20:16
     */
    public static Object transObj(String jsonStr, Object obj){
        JSONArray array = new JSONArray();
        try {
            JSONArray jsonArray = JSONArray.fromObject(jsonStr);
            for(int i=0; i< jsonArray.size(); i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String field = jsonObject.get("field") != null? jsonObject.getString("field"):"";
                Object value = jsonObject.get("value") != null? jsonObject.get("value"):"";
               if(com.wenge.util.StringUtils.isNotEmpty(field)){
                   //字段不为空,就是基础字段,数据库中就有字段来保存
                   Helper.setValueByKey(obj, field, value);
               }else{
                   JSONObject json = new JSONObject();
                   //如果是null 就是扩展字段,所有的扩展字段使用一个json 存储在custom_field中
                   String key = jsonObject.getString("key");
                   json.put("key", key);
                   json.put("value", value);
                   array.add(json);
               }

            }

            if(array.size() > 0){
                setValueByKey(obj, "CustomField", array.toString());
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return obj;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值