You need to enable JavaScript to run this app. 如何利用JSON映射文件实现Java不同POJO对象之间的自动转换
优惠活动
大模型
产品
解决方案
定价
更多

如何利用JSON映射文件实现Java不同POJO对象之间的自动转换

实现方案

首先修正映射文件的笔误,你提供的mapping.json里存在无效映射项:

// 错误项,没有对应的字段
{
  "userColumn": "last_first",
  "personColumn": "first_last"
}
// 修正为
{
  "userColumn": "name_last",
  "personColumn": "last_name"
}

步骤1:预加载映射配置

在Utility类中静态加载mapping.json,只需要初始化一次,避免每次转换重复读取文件:

import com.google.gson.Gson;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Utility {
    // 静态缓存映射配置,项目启动时加载一次即可
    private static Mapping MAPPING_CONFIG;

    static {
        try (InputStreamReader reader = new InputStreamReader(
                Utility.class.getClassLoader().getResourceAsStream("mapping.json")
        )) {
            MAPPING_CONFIG = new Gson().fromJson(reader, Mapping.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("映射配置文件加载失败", e);
        }
    }
}

步骤2:实现反射调用的通用方法

封装两个通用工具方法,分别用于调用对象的getter取值、调用对象的setter赋值:

// 通用getter调用:根据字段名从目标对象取属性值
private static Object getFieldValue(Object obj, String fieldName) throws Exception {
    // POJO getter规则:get + 字段首字母大写 + 剩余部分
    String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    Method getter = obj.getClass().getMethod(getterName);
    return getter.invoke(obj);
}

// 通用setter调用:根据字段名给目标对象设属性值
private static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
    if (value == null) return; // 空值跳过赋值,可根据需求调整
    // 先获取值的类型,作为setter的入参类型
    Class<?> paramType = value.getClass();
    // POJO setter规则:set + 字段首字母大写 + 剩余部分
    String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    Method setter = obj.getClass().getMethod(setterName, paramType);
    setter.invoke(obj, value);
}

步骤3:实现动态转换逻辑

遍历预加载的映射配置,逐个完成字段的取值、赋值:

public static Person userToPerson(User u) {
    Person person = new Person();
    ArrayList<Pair> columnMap = MAPPING_CONFIG.getColumnMap();
    for (Pair pair : columnMap) {
        try {
            // 从User对象取对应字段的值
            Object value = getFieldValue(u, pair.getUserColumn());
            // 给Person对象对应字段赋值
            setFieldValue(person, pair.getPersonColumn(), value);
        } catch (Exception e) {
            // 单个字段映射失败打日志即可,不中断整个转换,可根据业务需求调整处理逻辑
            System.out.printf("字段映射失败:userColumn=%s, personColumn=%s,错误信息:%s%n",
                    pair.getUserColumn(), pair.getPersonColumn(), e.getMessage());
        }
    }
    return person;
}

优化建议

  • 如果需要支持基础类型(比如int、long而非包装类),可以在setFieldValue方法里增加类型兼容判断,自动处理包装类和基础类型的匹配
  • 如果需要实现Person转User的反向转换,只需要调整get和set的对象,复用同一套映射规则即可
  • 生产环境可以把异常捕获替换为日志框架输出,不要直接打印控制台
  • 可以把字段的getter/setter方法缓存起来,避免每次转换都反射查找方法,提升性能

内容的提问来源于stack exchange,提问作者user1068636

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 07:54:03