将 InputStream 中包含的 json diff 结果分离到 Java 中的映射中
separating json diff results contained inside of an InputStream into a map in Java
我将 Supplier 接收到一个方法中,该方法将根据根据 JsonDiff 所做的每个更改创建一个对象。供应商设置如下:
ObjectMapper mapper = new ObjectMapper();
// jsons to compare
String json1= "{}";
String json2= "{\"name\":\"Sean\", \"state\":\"Colorado\"}";
// convert jsons to JsonNode
JsonNode json1Node = mapper.readTree(json1);
JsonNode json2Node = mapper.readTree(json2);
// create Supplier<InputStream>
Supplier<InputStream> diffs = () ->
new ByteArrayInputStream(JsonDiff.asJson(json1Node, json2Node).toString().getBytes());
产生的差异(在将其转换为 InputStream 之间)看起来像这样:
[{"op":"add", "path": "/name", "value": "Sean"}, {"op":"add", "path": "/State", "value": "Colorado"}]
当我收到这个供应商时,我希望能够将每个补丁单独成一个对象。该对象将简单地存储信息,设置如下:
private enum Op {
ADD, REPLACE, REMOVE
}
private Op op;
private String path;
private String value;
public Patch(Op op, String path, String value {
this.op = op;
this.path = path;
this.value = value;
}
// getter methods
根据这个特定示例,我应该能够创建 2 个对象,1 个用于名称,1 个用于状态。
我的尝试是这样的:
private List<Patch> patches;
Map<String, String> map = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
try {
// convert JSON string to Map
map = mapper.readValue(diffs.get().toString(), new TypeReference<HashMap<String, String>>() {});
// create patches
for (String value : map.values()) {
HashMap<String, String> result = mapper.readValue(value, HashMap.class);
patches.add(new Patch(Patch.Op.valueOf(result.get("op").toUpperCase()), result.get("path"), result.get("value")));
}
}catch (IOException e) {
e.printStackTrace();
}
它在 "readValue" 行抛出以下异常:
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'java': was expecting ('true', 'false' or 'null')
at [Source: java.io.ByteArrayInputStream@1abf3bf; line: 1, column: 5]
似乎(至少这是我的解释)diff.get().toString() 调用没有返回任何远程接近 Json.
的东西
有人知道怎么做吗?
由于 jsondiff 的结果是一个数组,您可能无法将其解析为映射而不是列表。
此外,您不必调用 Supplier 输出的 toString() 方法。
这是一个使用最新版本的 jackson 的工作示例:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1-1</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
<version>1.9</version>
</dependency>
public class Json {
static class Patch {
enum Op {
ADD, REMOVE, REPLACE;
};
private final Op op;
private final String path;
private final String value;
@JsonCreator
public Patch(//
@JsonProperty("op") String op, //
@JsonProperty("path") String path, //
@JsonProperty("value") String value) {
this.op = Op.valueOf(op.toUpperCase());
this.path = path;
this.value = value;
}
@Override
public String toString() {
return "Patch [op=" + op + ", path=" + path + ", value=" + value + "]";
}
}
public static void main(String[] args) throws Exception {
// jsons to compare
String json1 = "{}";
String json2 = "{\"name\":\"Sean\", \"state\":\"Colorado\"}";
// convert jsons to JsonNode
JsonNode json1Node = mapper.readTree(json1);
JsonNode json2Node = mapper.readTree(json2);
// create Supplier<InputStream>
final String strDiff = JsonDiff.asJson(json1Node, json2Node).toString();
Supplier<InputStream> diffs = () -> new ByteArrayInputStream(strDiff.getBytes());
MappingIterator<Patch> iterator = new ObjectMapper()//
.readerFor(Patch.class) //
.readValues(diffs.get());
List<Patch> patches = new ArrayList<>();
while (iterator.hasNext()) {
patches.add(iterator.next());
}
System.out.println(patches);
}
}
输出为:
[Patch [op=ADD, path=/name, value=Sean], Patch [op=ADD, path=/state, value=Colorado]]
我将 Supplier 接收到一个方法中,该方法将根据根据 JsonDiff 所做的每个更改创建一个对象。供应商设置如下:
ObjectMapper mapper = new ObjectMapper();
// jsons to compare
String json1= "{}";
String json2= "{\"name\":\"Sean\", \"state\":\"Colorado\"}";
// convert jsons to JsonNode
JsonNode json1Node = mapper.readTree(json1);
JsonNode json2Node = mapper.readTree(json2);
// create Supplier<InputStream>
Supplier<InputStream> diffs = () ->
new ByteArrayInputStream(JsonDiff.asJson(json1Node, json2Node).toString().getBytes());
产生的差异(在将其转换为 InputStream 之间)看起来像这样:
[{"op":"add", "path": "/name", "value": "Sean"}, {"op":"add", "path": "/State", "value": "Colorado"}]
当我收到这个供应商时,我希望能够将每个补丁单独成一个对象。该对象将简单地存储信息,设置如下:
private enum Op {
ADD, REPLACE, REMOVE
}
private Op op;
private String path;
private String value;
public Patch(Op op, String path, String value {
this.op = op;
this.path = path;
this.value = value;
}
// getter methods
根据这个特定示例,我应该能够创建 2 个对象,1 个用于名称,1 个用于状态。
我的尝试是这样的:
private List<Patch> patches;
Map<String, String> map = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
try {
// convert JSON string to Map
map = mapper.readValue(diffs.get().toString(), new TypeReference<HashMap<String, String>>() {});
// create patches
for (String value : map.values()) {
HashMap<String, String> result = mapper.readValue(value, HashMap.class);
patches.add(new Patch(Patch.Op.valueOf(result.get("op").toUpperCase()), result.get("path"), result.get("value")));
}
}catch (IOException e) {
e.printStackTrace();
}
它在 "readValue" 行抛出以下异常:
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'java': was expecting ('true', 'false' or 'null')
at [Source: java.io.ByteArrayInputStream@1abf3bf; line: 1, column: 5]
似乎(至少这是我的解释)diff.get().toString() 调用没有返回任何远程接近 Json.
的东西有人知道怎么做吗?
由于 jsondiff 的结果是一个数组,您可能无法将其解析为映射而不是列表。 此外,您不必调用 Supplier 输出的 toString() 方法。
这是一个使用最新版本的 jackson 的工作示例:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1-1</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
<version>1.9</version>
</dependency>
public class Json {
static class Patch {
enum Op {
ADD, REMOVE, REPLACE;
};
private final Op op;
private final String path;
private final String value;
@JsonCreator
public Patch(//
@JsonProperty("op") String op, //
@JsonProperty("path") String path, //
@JsonProperty("value") String value) {
this.op = Op.valueOf(op.toUpperCase());
this.path = path;
this.value = value;
}
@Override
public String toString() {
return "Patch [op=" + op + ", path=" + path + ", value=" + value + "]";
}
}
public static void main(String[] args) throws Exception {
// jsons to compare
String json1 = "{}";
String json2 = "{\"name\":\"Sean\", \"state\":\"Colorado\"}";
// convert jsons to JsonNode
JsonNode json1Node = mapper.readTree(json1);
JsonNode json2Node = mapper.readTree(json2);
// create Supplier<InputStream>
final String strDiff = JsonDiff.asJson(json1Node, json2Node).toString();
Supplier<InputStream> diffs = () -> new ByteArrayInputStream(strDiff.getBytes());
MappingIterator<Patch> iterator = new ObjectMapper()//
.readerFor(Patch.class) //
.readValues(diffs.get());
List<Patch> patches = new ArrayList<>();
while (iterator.hasNext()) {
patches.add(iterator.next());
}
System.out.println(patches);
}
}
输出为:
[Patch [op=ADD, path=/name, value=Sean], Patch [op=ADD, path=/state, value=Colorado]]