java - 使用 Jackson 根据另一个字段(键)映射 JSON 字段(到值)

标签 java jackson deserialization json-deserialization objectmapper

{
  "key1": {
    "parameter1": "String1",
    "parameter2": "String2"
  },
  "key2": {
    "parameter1": "String3",
    "parameter2": "String4"
  },
  "key3": {
    "parameter1": "String5",
    "parameter2": "String6"
  }
}

我有上面的JSON (/Users/user1/Desktop/responseMap.json) 基本上是 Map<String, MockResponse>哪里MockResponse如下POJO :

public class MockResponse {
    public String parameter1;
    public String parameter2;
} 

现在,我有另一个 POJO -TestCase ,还有另一个JSON -testCase.json如下:

public class TestCase {

    public String responseMapFileLocation;
    public String mockResponseKey;
    public MockResponse mockResponse;
}

testCase.json

{
  "responseMapFileLocation": "/Users/user1/Desktop/responseMap.json",
  "mockResponseKey": "key1",
  "mockResponse": null
}

我能做的是第一张 map testCase.jsonTestCase使用Jackson ,然后映射responseMap.jsonMap<String, MockResponse> ,然后在我的代码中搜索 mockResponseKey在 map 上。

但我想做的是当我映射testCase.json时至TestCase使用Jackson ,我想要变量mockResponse的值根据变量 mockResponseKey 的值自动设置使用第一个JSON map 。

最佳答案

您需要为 TestCase 类编写自定义反序列化器。在自定义反序列化器中,您可以解析基本属性:responseMapFileLocationmockResponseKey 并从其他文件加载mockResponse。要反序列化 MockResponse,您可以使用新的 ObjectMapper 实例。下面的代码展示了如何实现这个概念:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.MapType;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();

        System.out.println(mapper.readValue(jsonFile, TestCase.class));
    }
}

class MockResponse {
    public String parameter1;
    public String parameter2;
}

@JsonDeserialize(using = TestCaseFromExternalFileDeserializer.class)
class TestCase {

    public String responseMapFileLocation;
    public String mockResponseKey;
    public MockResponse mockResponse;
}

class TestCaseFromExternalFileDeserializer extends JsonDeserializer<TestCase> {

    private final ObjectMapper mapper;
    private final MapType mapType;

    public TestCaseFromExternalFileDeserializer() {
        mapper = new ObjectMapper();
        mapType = mapper.getTypeFactory().constructMapType(Map.class, String.class, MockResponse.class);
    }

    @Override
    public TestCase deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        TreeNode treeNode = p.readValueAsTree();

        TestCase testCase = new TestCase();
        testCase.responseMapFileLocation = ((JsonNode) treeNode.get("responseMapFileLocation")).asText();
        testCase.mockResponseKey = ((JsonNode) treeNode.get("mockResponseKey")).asText();
        parseMockResponse(testCase);

        return testCase;
    }

    private void parseMockResponse(TestCase testCase) throws IOException {
        Map<String, MockResponse> map = mapper.readValue(new File(testCase.responseMapFileLocation), mapType);

        testCase.mockResponse = map.get(testCase.mockResponseKey);
    }
}

您只需为每个POJO 类实现toString 方法。上面的代码打印:

TestCase{responseMapFileLocation='./resource/responseMap.json', mockResponseKey='key1', mockResponse=MockResponse{parameter1='String1', parameter2='String2'}}

两个 JSON 文件都位于 resource 文件夹中。

另请参阅:

关于java - 使用 Jackson 根据另一个字段(键)映射 JSON 字段(到值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56297495/

相关文章:

java - 如何在 JSON 结构中的特定对象上使用自定义 Jackson JsonDeserializer<T> 类?

java - 如何在同一个 Jersey JAX-RS 应用程序中使用两个版本的 Jackson(1.x 和 2.x)?

c# - 当事先不知道派生类型时使用 DataContractSerializer 反序列化派生类型

java - 如何从文件反序列化到不同的类

java - 如何监听异步服务器端Java Controller ?

java - 使用 Wi-Fi 将我的本地 PC 连接到 ANDROID 设备

java - Jackson:用于反序列化内部集合的对象映射器注释

python - 无法解决python中的Elasticsearch.exceptions.SerializationError以从Elastic Search获取数据

java - hashCode 可以在不同的运行之间返回不同的值吗?

java - 使用MyBatis将用户信息保存到MySQL中