{
"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.json
至TestCase
使用Jackson
,然后映射responseMap.json
至Map<String, MockResponse>
,然后在我的代码中搜索 mockResponseKey
在 map 上。
但我想做的是当我映射testCase.json
时至TestCase
使用Jackson
,我想要变量mockResponse
的值根据变量 mockResponseKey
的值自动设置使用第一个JSON
map 。
最佳答案
您需要为 TestCase
类编写自定义反序列化器。在自定义反序列化器中,您可以解析基本属性:responseMapFileLocation
、mockResponseKey
并从其他文件加载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
文件夹中。
另请参阅:
- How use jackson ObjectMapper inside custom deserializer?
- Jackson Streaming API - 如果您想以更快的方式实现
MockResponse
反序列化。
关于java - 使用 Jackson 根据另一个字段(键)映射 JSON 字段(到值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56297495/