New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue setting values from / to JSON Objects? #432
Comments
It should work. Could you please provide a test case to illustrate this problem? |
Regardless of version (2.2.0 or 2.3.0) this is the result I get with the following test: @Test
public void testPathSetting() {
Map<String, Object> data = Maps.newLinkedHashMap();
data.put("key1", LocalDate.now());
data.put("key3", "hello");
Configuration jsonConfig = Configuration.builder()
.options(Option.DEFAULT_PATH_LEAF_TO_NULL, Option.SUPPRESS_EXCEPTIONS)
.build();
Map<String, Object> newObject = new LinkedHashMap<>();
DocumentContext reader = JsonPath.parse(data, jsonConfig);
DocumentContext writer = JsonPath.parse(newObject, jsonConfig);
Object value;
Map<JsonPath, JsonPath> conversionPaths = new LinkedHashMap<>();
conversionPaths.put(JsonPath.compile("$.key1"), JsonPath.compile("$.key"));
conversionPaths.put(JsonPath.compile("$.key2"), JsonPath.compile("$.ok"));
conversionPaths.put(JsonPath.compile("$.key3"), JsonPath.compile("$.nested.key3"));
for(Map.Entry<JsonPath, JsonPath> path : conversionPaths.entrySet()) {
JsonPath fromPath = path.getKey();
JsonPath toPath = path.getValue();
value = reader.read(fromPath);
writer.set(toPath, value);
}
assertThat(newObject, hasEntry("key", data.get("key1")));
assertThat(newObject, hasEntry("ok", data.get("key2")));
assertThat(newObject, hasKey("nested"));
Object valOldPath = JsonPath.read(data, "$.key3");
Object valNewPath = JsonPath.read(newObject, "$.nested.key3");
assertThat(valNewPath, is(valOldPath));
} Obtained result: java.lang.AssertionError:
Expected: map containing ["nested"->ANYTHING]
but: map was [<key=2018-01-25>, <ok=null>]
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.Assert.assertThat(Assert.java:923)
at com.wdpr.cap.accounting.jsonpath.converter.ObjectConverterTest.testPathSetting(ObjectConverterTest.java:86)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Expected: JUnit test passes. |
Note, if I remove the following option: Option.DEFAULT_PATH_LEAF_TO_NULL, Then the result I get is this from that same test: java.lang.AssertionError:
Expected: map containing ["key"-><2018-01-25>]
but: map was []
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.Assert.assertThat(Assert.java:923)
at com.wdpr.cap.accounting.jsonpath.converter.ObjectConverterTest.testPathSetting(ObjectConverterTest.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Expected: I would of thought that this option would not have direct impact to the test. But rather than having key2 as null (which is translated to "ok" key in the new object), then both of these keys should just not be present, is my thought. |
If we trying to add something to empty json ("{}") by Json Path like "$.nonexistent.node" we can see an exception com.jayway.jsonpath.PathNotFoundException: Missing property in path $['nonexistent'] It was cool, if we have some option to create an absent part of json path if it is expected |
The option to create absents parts in a json by calling the set Method would be very appreciated. eg.: @RequestMapping(path = "/test", method = RequestMethod.POST)
ResponseEntity<?> mapPerson(@RequestBody PersonPojo1 input) {
Map<String, String> mappingMap = new HashMap<>();
mappingMap.put("$.orderList[0].order[0].firstName", "$.businessPartners.businessPartner.firstName");
mappingMap.put("$.orderList[0].order[0].lastName", "$.businessPartners.businessPartner.surName");
Gson gsonObject = new GsonBuilder().create();
String inputJson = gsonObject.toJson(input);
PersonPojo2 output = new PersonPojo2();
String outputJson = gsonObject.toJson(output);
for(Entry<String, String> keyPair : mappingMap.entrySet()) {
JsonPath.parse(outputJson).set(keyPair.getValue(), JsonPath.read(inputJson, keyPair.getKey()));
}
output = gsonObject.fromJson(outputJson, PersonPojo2.class);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("").buildAndExpand(output).toUri();
return ResponseEntity.created(location).body(output);
} |
@ChrisLeeBare Any solution for this issue...? |
Hello, it seems that this implementation of JsonPath works pretty well when setting the first level of keys of an object (from existing to new instance).. eg
if we set values this way (with the specific options set in "jsonConfig" below):
then this works for all first level keys.. eg
The above, causes newObject to be filled in with the desired new keys on the right using the data that had been previously set from the source "data" set.
But if I'm trying to convert to nested paths such as these, it does not work and the newObject map above is not filled in:
Is there a better way of doing that that I am overlooking? Or can this be a bug?
The text was updated successfully, but these errors were encountered: