Jackson XmlMapper not converting list values - java

I have a case, xml string need to be convert as json string, code is below. List is not converting as List in JSON, last entry only present in the output.
Code:
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree("<Find Status=\"Success\"><Result><Provider><lastUpdated>1545391251168</lastUpdated><connection><entityType>CIMHTTPGETRequest</entityType><entityId>M7IH6HVWAAAAU74VJ5F5PBJZ</entityId></connection><connection><entityType>CIMHTTPGETRequest</entityType><entityId>M7IH6HWBAAAAU74VJ7KW72FB</entityId></connection><connection><entityType>CIMHTTPGETRequest</entityType><entityId>M7IH6HWCAAAAU74VJ4TQATY4</entityId></connection></Provider></Result></Find>".getBytes());
ObjectMapper jsonMapper = new ObjectMapper();
System.out.println(jsonMapper.writeValueAsString(node));
}
Actual output is:
{"Status":"Success","Result":{"Provider":{"lastUpdated":"1545391251168","connection":{"entityType":"CIMHTTPGETRequest","entityId":"M7IH6HWCAAAAU74VJ4TQATY4"}}}}
Expected output is:
{"Status":"Success","Result":{"Provider":{"lastUpdated":"1545391251168","connection":[{"entityType":"CIMHTTPGETRequest","entityId":"M7IH6HVWAAAAU74VJ5F5PBJZ"},{"entityType":"CIMHTTPGETRequest","entityId":"M7IH6HWBAAAAU74VJ7KW72FB"},{"entityType":"CIMHTTPGETRequest","entityId":"M7IH6HWCAAAAU74VJ4TQATY4"}]}}}
Dependencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.8</version>
</dependency>

Related

JSONObject sent via JerseyTest coming blank [duplicate]

I'm building a RESTful web service. I've been locked in a situation where I'm not able to proceed. I've a DAO (a POJO) that has a JSONObject as a member variable. When I try to make a POST call from client (Postman or user-defined javascript) and try to debug, the value gathered in the getter of the JSONObject is empty ({}) whereas the other members of the class obtain their appropriate values. I've tried annotating the JSONObject and its getter with #XmlElement, #JsonProperty and so on.. Nothing worked.
The class looks like :
package org.somepackage
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonProperty;
import org.json.JSONObject;
#XmlRootElement
public class someClass {
private String someID;
private String someName;
private JSONObject someJsonObject;
public someClass () {
}
public someClass (String id, String name,
JSONObject jsonObj) {
someID=id;
someName=name;
someJsonObject=jsonObj;
}
public String getSomeID() {
return someID;
}
public void setSomeID(String id) {
this.SomeID= id;
}
public String getSomeName() {
return someName;
}
public void setSomeName(String name) {
this.someName= name;
}
public JSONObject getSomeJsonObject() {
return someJsonObject;
}
public void setSomeJsonObject(JSONObject jsonObj) {
this.someJsonObject= jsonObj;
}
}
I appreciate your help!
Thanks.
EDIT
Example JSON
{
"name": "ABCD",
"ID": "P63784433",
"theJSON":{
"string":"foo",
"number":5,
"array":[1,2,3],
"object":{
"property":"value‌​",
"subobj":{
"arr":["foo","ha"],
"numero":1
}
}
}
}
DEPENDENCY
web.xml dependency on Jackson
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.2</version>
</dependency>
RESOURCES AND PROVIDER REGISTER through web.xml
<!-- Register JAX-RS Application -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.package.MyApplication</param-value>
</init-param>
<!-- Register resources and providers under my.package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
<!-- Register custom provider -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>my.package.mapper.ObjectMapperProvider</param-value>
</init-param>`
MyApplication.java
`#ApplicationPath("/")
public class MyApplication extends ResourceConfig {
public MyApplication() {
// Register resources and providers using package-scanning.
packages("my.package");
register(ObjectMapperProvider.class);
}`
The problem is that Jackson doesn't know how to create the JSONObject (at least not without some help). Jackson mainly handle basic type and POJOs. If you want to be able to handle JSONObject (assuming this is the object from org.json), you can add the jackson-datatype-json-org for the Jackson support.
Below is a complete test. Here are the dependencies I used to test
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20141113</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
Note: The Jackson version I am using for jackson-datatype-json-org is the same Jackson version used by jersey-media-json-jackson 2.16. If you are using a different version of this jersey jackson, you will need to make sure the version of Jackson it pulls in is the same version of jackson-datatype-json-org you are using. This way we are not mixing Jackson versions.
Here's the test using Jersey Test Framework
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.json.JSONObject;
import org.junit.Test;
import static junit.framework.Assert.*;
/**
*
* #author Paul Samsotha
*/
public class JsonOrgTest extends JerseyTest {
public static class Model {
public String firstName;
public String lastName;
public JSONObject other;
// should br private with correct getters and setters
}
#Path("model")
public static class ModelResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response post(Model model) {
return Response.ok(model).build();
}
}
#Provider
public static class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperProvider() {
mapper = new ObjectMapper();
mapper.registerModule(new JsonOrgModule());
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
#Override
public ResourceConfig configure() {
return new ResourceConfig(ModelResource.class)
.register(ObjectMapperProvider.class)
.register(JacksonFeature.class);
}
#Override
public void configureClient(ClientConfig config) {
config.register(JacksonFeature.class);
config.register(ObjectMapperProvider.class);
}
#Test
public void should_return_org_json_data() {
final String json
= "{\n"
+ " \"firstName\": \"pee\",\n"
+ " \"lastName\": \"skillet\",\n"
+ " \"other\": {\n"
+ " \"age\": 100,\n"
+ " \"birthday\": \"yesterday\"\n"
+ " }\n"
+ "}";
Response response = target("model").request().post(Entity.json(json));
if (response.getStatus() != 200) {
System.out.println(response.getStatus() + ": " + response.readEntity(String.class));
fail("should return data and 200");
} else {
Model model = response.readEntity(Model.class);
JSONObject other = model.other;
System.out.println(other.toString());
assertEquals("pee", model.firstName);
assertEquals("skillet", model.lastName);
assertEquals(100, other.getInt("age"));
assertEquals("yesterday", other.getString("birthday"));
}
}
}
What you should also do is get rid of all the Jackson dependencies you have in your comment above. You only need one dependency for Jackson JSON support.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
Also notice the ObjectMapperProvider in the test. You will need to this to register the JsonOrgModule with the ObjectMapper in order for Jackson to be able to handle JSONObject. This is important. If you don't have the ContextResolver, the above example will fail.

JSON response from string in Javalin

I am trying to create the response in JSON format from a string in Javalin. JSON object must be from a string, not from class.
public static void main(String[] args) {
Javalin app = Javalin.create().start(9000);
String jsonString = "{'test1':'value1','test2':{'id':0,'name':'testName'}}";
JsonObject jsonObject= JsonParser.parseString(jsonString).getAsJsonObject();
app.error(404, ctx -> ctx.json(jsonObject));
...
}
With the code above, I am getting a 500 server error.
If you are using Gson, then switch to using Jackson, when using Javalin methods such as ctx.json().
If you used Maven to import Javalin, and if you used the javalin-bundle, then you will already have Jackson, for example:
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin-bundle</artifactId>
<version>3.13.3</version>
</dependency>
If you only used javalin and not javalin-bundle then you will need to add Jackson yourself - for example:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.2</version>
</dependency>
The following is the code from the question, but re-worked to use Jackson (and to use valid JSON):
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.Javalin;
public class App {
public static void main(String[] args) throws JsonProcessingException {
Javalin app = Javalin.create().start(9000);
String jsonString = "{\"test1\":\"value1\",\"test2\":{\"id\":0,\"name\":\"testName\"}}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(jsonString);
app.error(404, ctx -> ctx.json(jsonNode));
}
}

How to convert a Java object to JSON object in Eclipse

My requirement is to convert a plain Java object to JSON format -
The Java object has following format -
Record Id: 168349200
Name: jane
City: abababa
State: ababab
Insertion Date: 18/04/2017 10:16:17
I have gone through some tutorials and found that GSON library is a way to do it. I tried to install the gson jar in my Eclipse project (using Eclipse Mars Release (4.5.0)).
But when I do -
import com.google.gson.Gson
in the class where I want to do the conversion of the Java object to JSON it throws an exception.
I think I have not added the GSON jar file properly.
Can some one please help.
Thanks.
Try:
Gson gson = new Gson();
String jsonString = null;
try {
jsonString = gson.toJson(javaObject);
} catch (Exception e) {
e.printStackTrace();
}
From Java Object to Json using ObjectMapper:
ObjectMapper objMapper = new ObjectMapper().setSerializationInclusion(Include.NON_NULL);
MyObject mObject = new MyObject();
String jsonObject ="";
mObject.setField1(value1);
mObject.setField2(value2);
mObject.setField3(value3);
try {
jsonObject = objMapper.writeValueAsString(mObject);
System.out.println(jsonObject); //You can then store it in a file
} catch (JsonProcessingException e) {
e.printStackTrace();
}
You should add these imports:
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
And in the pom.xml these lines:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.5</version>
</dependency>

How do I get value from JSON using JsonPath in Java?

I want to get the value from the JSON object using JsonPath.Could anyone please suggest me the appropriate jars which i would need because as per my knowledge i am getting this exception for the jars i am using for jsonpath .
package jsonPg;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import com.jayway.jsonpath.JsonPath;
public class ReadJsonPath {
static String file = "D:\\AutomationSample\\Sample_Json.txt";
public static void main(String[] args) throws JSONException, IOException {
JsonReadFile jsonReadFile=new JsonReadFile();
JSONObject jsonObj=jsonReadFile.parseJSONFile(file);
String jsonObject=jsonObj.toString();
String json="";
System.out.println(jsonObject);
// Object val = JsonPath.read(jsonObject,"");
String val1=JsonPath.read(jsonObject," $.payload[*].supplierDataMap[*].COMPANYDETAILS.customFieldList[*].DISPLAYGSID .value");
System.out.println(val1);
}
}
here is the code which i have written and below is the exception which is thrown at runtime
Exception in thread "main" java.lang.NoSuchFieldError: FACTORY_SIMPLE
at com.jayway.jsonpath.spi.impl.JsonSmartJsonProvider.<init>(JsonSmartJsonProvider.java:38)
at com.jayway.jsonpath.spi.impl.JsonSmartJsonProvider.<init>(JsonSmartJsonProvider.java:41)
at com.jayway.jsonpath.spi.JsonProviderFactory.<clinit> (JsonProviderFactory.java:24)
at com.jayway.jsonpath.Configuration.defaultConfiguration(Configuration.java:62)
at com.jayway.jsonpath.internal.JsonReader.<init>(JsonReader.java:26)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:462)
at jsonPg.ReadJsonPath.main(ReadJsonPath.java:27)`
Any kind of help would be appreciated .
Thanks in advance .
You can achieve your goal with JsonPath library on its own. Here is an example:
String jsonString = "{ \"list\": [ { \"name\": \"foo1\"}, { \"name\": \"foo2\"} ]}";
DocumentContext docCtx = JsonPath.parse(jsonString);
JsonPath jsonPath = JsonPath.compile("$.list[?(#.name == \"foo1\")]");
JSONArray val1=docCtx.read(jsonPath);
System.out.println(val1);
This code will print out:
[{"name":"foo1"}]
Required maven dependency:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.2.0</version>
</dependency>
json-path will also automatically pull json-smart JAR:
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>2.2.1</version>
</dependency>
String jsonString = "{ \"list\": [ { \"name\": \"foo1\"}, { \"name\": \"foo2\"} ]}";
DocumentContext docCtx = JsonPath.parse(jsonString);
JsonPath jsonPath = JsonPath.compile("$.list[?(#.name == foo1)]");
JSONArray val1=docCtx.read(jsonPath);
System.out.println(val1);

JSONObject as a member variable in POJO not recognized -Jersey

I'm building a RESTful web service. I've been locked in a situation where I'm not able to proceed. I've a DAO (a POJO) that has a JSONObject as a member variable. When I try to make a POST call from client (Postman or user-defined javascript) and try to debug, the value gathered in the getter of the JSONObject is empty ({}) whereas the other members of the class obtain their appropriate values. I've tried annotating the JSONObject and its getter with #XmlElement, #JsonProperty and so on.. Nothing worked.
The class looks like :
package org.somepackage
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonProperty;
import org.json.JSONObject;
#XmlRootElement
public class someClass {
private String someID;
private String someName;
private JSONObject someJsonObject;
public someClass () {
}
public someClass (String id, String name,
JSONObject jsonObj) {
someID=id;
someName=name;
someJsonObject=jsonObj;
}
public String getSomeID() {
return someID;
}
public void setSomeID(String id) {
this.SomeID= id;
}
public String getSomeName() {
return someName;
}
public void setSomeName(String name) {
this.someName= name;
}
public JSONObject getSomeJsonObject() {
return someJsonObject;
}
public void setSomeJsonObject(JSONObject jsonObj) {
this.someJsonObject= jsonObj;
}
}
I appreciate your help!
Thanks.
EDIT
Example JSON
{
"name": "ABCD",
"ID": "P63784433",
"theJSON":{
"string":"foo",
"number":5,
"array":[1,2,3],
"object":{
"property":"value‌​",
"subobj":{
"arr":["foo","ha"],
"numero":1
}
}
}
}
DEPENDENCY
web.xml dependency on Jackson
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.2</version>
</dependency>
RESOURCES AND PROVIDER REGISTER through web.xml
<!-- Register JAX-RS Application -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.package.MyApplication</param-value>
</init-param>
<!-- Register resources and providers under my.package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
<!-- Register custom provider -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>my.package.mapper.ObjectMapperProvider</param-value>
</init-param>`
MyApplication.java
`#ApplicationPath("/")
public class MyApplication extends ResourceConfig {
public MyApplication() {
// Register resources and providers using package-scanning.
packages("my.package");
register(ObjectMapperProvider.class);
}`
The problem is that Jackson doesn't know how to create the JSONObject (at least not without some help). Jackson mainly handle basic type and POJOs. If you want to be able to handle JSONObject (assuming this is the object from org.json), you can add the jackson-datatype-json-org for the Jackson support.
Below is a complete test. Here are the dependencies I used to test
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20141113</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
Note: The Jackson version I am using for jackson-datatype-json-org is the same Jackson version used by jersey-media-json-jackson 2.16. If you are using a different version of this jersey jackson, you will need to make sure the version of Jackson it pulls in is the same version of jackson-datatype-json-org you are using. This way we are not mixing Jackson versions.
Here's the test using Jersey Test Framework
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.json.JSONObject;
import org.junit.Test;
import static junit.framework.Assert.*;
/**
*
* #author Paul Samsotha
*/
public class JsonOrgTest extends JerseyTest {
public static class Model {
public String firstName;
public String lastName;
public JSONObject other;
// should br private with correct getters and setters
}
#Path("model")
public static class ModelResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response post(Model model) {
return Response.ok(model).build();
}
}
#Provider
public static class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperProvider() {
mapper = new ObjectMapper();
mapper.registerModule(new JsonOrgModule());
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
#Override
public ResourceConfig configure() {
return new ResourceConfig(ModelResource.class)
.register(ObjectMapperProvider.class)
.register(JacksonFeature.class);
}
#Override
public void configureClient(ClientConfig config) {
config.register(JacksonFeature.class);
config.register(ObjectMapperProvider.class);
}
#Test
public void should_return_org_json_data() {
final String json
= "{\n"
+ " \"firstName\": \"pee\",\n"
+ " \"lastName\": \"skillet\",\n"
+ " \"other\": {\n"
+ " \"age\": 100,\n"
+ " \"birthday\": \"yesterday\"\n"
+ " }\n"
+ "}";
Response response = target("model").request().post(Entity.json(json));
if (response.getStatus() != 200) {
System.out.println(response.getStatus() + ": " + response.readEntity(String.class));
fail("should return data and 200");
} else {
Model model = response.readEntity(Model.class);
JSONObject other = model.other;
System.out.println(other.toString());
assertEquals("pee", model.firstName);
assertEquals("skillet", model.lastName);
assertEquals(100, other.getInt("age"));
assertEquals("yesterday", other.getString("birthday"));
}
}
}
What you should also do is get rid of all the Jackson dependencies you have in your comment above. You only need one dependency for Jackson JSON support.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
Also notice the ObjectMapperProvider in the test. You will need to this to register the JsonOrgModule with the ObjectMapper in order for Jackson to be able to handle JSONObject. This is important. If you don't have the ContextResolver, the above example will fail.

Categories