Java 使用Jackson基于另一个字段(键)将JSON字段(映射到值)

Java 使用Jackson基于另一个字段(键)将JSON字段(映射到值),java,jackson,deserialization,json-deserialization,objectmapper,Java,Jackson,Deserialization,Json Deserialization,Objectmapper,我有上面的JSON(/Users/user1/Desktop/responseMap.JSON),它基本上是一个Map,其中MockResponse是下面的POJO: { "key1": { "parameter1": "String1", "parameter2": "String2" }, "key2": { "parameter1": "String3", "parameter2": "String4" }, "key3": {

我有上面的
JSON
(/Users/user1/Desktop/responseMap.JSON),它基本上是一个
Map
,其中
MockResponse
是下面的
POJO

{
  "key1": {
    "parameter1": "String1",
    "parameter2": "String2"
  },
  "key2": {
    "parameter1": "String3",
    "parameter2": "String4"
  },
  "key3": {
    "parameter1": "String5",
    "parameter2": "String6"
  }
}
现在,我有另一个
POJO
-
TestCase
,还有另一个
JSON
-
TestCase.JSON
,如下所示:

public class MockResponse {
    public String parameter1;
    public String parameter2;
} 
testCase.json

public class TestCase {

    public String responseMapFileLocation;
    public String mockResponseKey;
    public MockResponse mockResponse;
}
我能做的是首先使用
Jackson
testCase.json
映射到
testCase
,然后将
responseMap.json
映射到
map
,然后在我的代码中搜索映射中的
mockResponseKey


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

仅使用Jackson无法实现您的要求。Jackson主要是一个编组/解编组工具,将JSON转换为对象,反之亦然。换句话说,在解组时必须知道对象的值

但是,您可以使用以下代码将json解组为哈希映射:

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

使用mockResponseKey搜索MockResponse-as-a-string,然后将代码解组为新的MockResponse。

在测试类中调整getter setter并将字段标记为private,我可以使其动态(导入来自
org.codehaus.jackson
包)

输出将是

public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        TestCase testCase = mapper.readValue(new File("C:\\UsersJson2.json"), TestCase.class);
        System.out.println(testCase);

    }

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

TestCase [responseMapFileLocation=/Users/user1/Desktop/responseMap.json, mockResponseKey=key1, mockResponse=MockResponse [parameter1=String1, parameter2=String2]]
两个
JSON
文件都位于
resource
文件夹中

另见:

  • -如果您想以更快的方式实现
    MockResponse
    反序列化

上面的json是Map类型,请检查如何映射到json的Map。如果添加库是一个选项,
ModelMapper
值得一看。@Pankaj我已经发布了一个答案,看看让m eknow它是否适用于您解决了这个问题吗?下面的答案有用吗?
public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        TestCase testCase = mapper.readValue(new File("C:\\UsersJson2.json"), TestCase.class);
        System.out.println(testCase);

    }
TestCase [responseMapFileLocation=/Users/user1/Desktop/responseMap.json, mockResponseKey=key1, mockResponse=MockResponse [parameter1=String1, parameter2=String2]]
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);
    }
}
TestCase{responseMapFileLocation='./resource/responseMap.json', mockResponseKey='key1', mockResponse=MockResponse{parameter1='String1', parameter2='String2'}}