How to parse nested json object as it is using Jackson - java

I have the following JSON structure:
{
"sets": [
{...},
{
"id": "id",
"html": "<html></html>",
"javascript": "{onError: function (event) {}}",
"css": ".someclass {}",
"translations": {
"en": { "LABEL_1": "Some label text", "HEADER_1": "Some header text" },
"fr": { "LABEL_1": "Some label text", "HEADER_1": "Some header text" }
}
}
]
}
I have an object that represents this JSON for deserialization purpose
#Data //Lombok
#NoArgsConstructor //Lombok
public class Set {
#JsonProperty("screenSetID")
private String screenSetID;
#JsonProperty("html")
private String html;
#JsonProperty("css")
private String css;
#JsonProperty("javascript")
private String javascript;
#JsonProperty("translations")
private String translations;
}
I have the following piece of code to deserialize JSON
private List<Set> parseSetsData(String json) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(json, TypeReference<List<Set>(){});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
How I can parse translations JSON object as it is?

Any Jason object could be mapped to Map<String, Object> and any Json List could be mapped to List<Object>. So you could parse your JSON as follows:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModules(new JavaTimeModule());
objectReader = objectMapper.reader();
Map<String, Object> parsedJson = (Map<String, Object>)objectReader.forType(Map.class).readValue(jsonString)
Note that your JSON is a JSON object and not JSON list, so this example parses it to Map

I'm sure you understand that the that you want is part of on array hats why I had to use a for loop:
ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.readTree(json);
treeNode=treeNode.findValue("sets");
for (Iterator<JsonNode> it = treeNode.elements(); it.hasNext(); ) {
JsonNode node = it.next();
String theValueYouWant=node.findValue("translations").textValue();
}

Json I found that when you deserialize your item it should look like the following;
public class En
{
#JsonProperty("LABEL_1")
public String lABEL_1;
#JsonProperty("HEADER_1")
public String hEADER_1;
}
public class Fr
{
#JsonProperty("LABEL_1")
public String lABEL_1;
#JsonProperty("HEADER_1")
public String hEADER_1;
}
public class Translations
{
public En en;
public Fr fr;
}
public class Set
{
public String id;
public String html;
public String javascript;
public String css;
public Translations translations;
}
However, in your class, "translations" is a string, but in a JSON structure, it points to an object.

Related

How parse nested escaped json with Jackson?

Consider json:
{
"name": "myName",
"myNestedJson": "{\"key\":\"value\"}"
}
Should be parsed into classes:
public class MyDto {
String name;
Attributes myNestedJson;
}
public class Attributes {
String key;
}
Can it be parsed without writing stream parser? (Note that myNestedJson contains json escaped json string)
I think you can add a constructor to Attributes that takes a String
class Attributes {
String key;
public Attributes() {}
public Attributes(String s) {
// Here, s is {"key":"value"} you can parse it into an Attributes
// (this will use the no-arg constructor)
try {
ObjectMapper objectMapper = new ObjectMapper();
Attributes a = objectMapper.readValue(s, Attributes.class);
this.key = a.key;
} catch(Exception e) {/*handle that*/}
}
// GETTERS/SETTERS
}
Then you can parse it this way:
ObjectMapper objectMapper = new ObjectMapper();
MyDto myDto = objectMapper.readValue(json, MyDto.class);
This is a little dirty but your original JSON is too :)

Mapping JSON response to Java POJO Class using GSON

I am trying to map below JSON to a POJO Class using Gson library. Below is the JSON response and POJO Class and mapping done
import java.util.Map;
import com.google.gson.JsonElement;
public class DataResponse {
private String $status;
private Map<String, JsonElement> $payload;
public String get$status() {
return $status;
}
public void set$status(String $status) {
this.$status = $status;
}
public Map<String, JsonElement> get$payload() {
return $payload;
}
public void set$payload(Map<String, JsonElement> $payload) {
this.$payload = $payload;
}
}
Here is the Sample JSON.
{
"$status": "OK",
"$payload": {
"$nextStart": "123",
"$results": [
{
"$key": "101",
"score": 3,
"to": "Test1"
},
{
"$key": "102",
"score": 4,
"to": "Test2"
},
]
}
}
Below is the mapping done. Is there some problem with POJO class definition. Since I cannot get all the elements of JSON response mapped to the innermost element from the response. Appreciate your support in providing useful suggestions.
Gson gson = new Gson();
DataResponse dataResponse = gson.fromJson(EntityUtils.toString(response.getEntity()),
DataResponse.class);
While working with marshalling and unmarshalling, it is always good to have a model defined as:
public class DataResponse {
private String $status;
private Payload $payload;
// getters and setters
}
class Payload {
private String $nextStart;
private List<Result> $results;
// getters and setters
}
class Result {
private String $key;
private String score;
private String to;
// getters and setters
}
Now when you convert json to POJO as:
Gson gson = new Gson();
DataResponse dataResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), DataResponse.class);
it can easily convert it.
Also, believe me, it is good for processing in your further code!
Update: if you really want to convert json to Map, then you can do something like this:
import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson("{'key':'value'}", type);
Substitute json string there.

How to Convert JSON to JAVA Object using ObjectMapper?

Java Object
class B {
private String attr;
/***** getters and setters *****/
}
class A {
private String attr1;
private String attr2;
private Map<String,B> attr3;
/***** getters and setters *****/
}
Json Object
json = {attr1 :"val1", attr2 : "val2", attr3 : {attr : "val"}}
How to convert json to java Object (class java contain Map as type of attribute) ?
You can use Jackson to do that:
//Create mapper instance
ObjectMapper mapper = new ObjectMapper();
//Usea a JSON string (exists other methos, i.e. you can get the JSON from a file)
String jsonString= "{'name' : 'test'}";
//JSON from String to Object
MyClass result= mapper.readValue(jsonString, MyClass .class);
You can use Gson library as following:
// representation string for your Json object
String json = "{\"attr1\": \"val1\",\"attr2\": \"val2\",\"attr3\": {\"attr\": \"val\"}}";
Gson gson = new Gson();
A a = gson.fromJson(json, A.class);
Create a model/POJO which resembles your json structure and then by putting json string in json file you can get java object by using below simple code by using JACKSON dependacy
ObjectMapper mapper = new ObjectMapper();
File inRulesFile = (new ClassPathResource(rulesFileName + ".json")).getFile();
List<Rule> rules = mapper.readValue(inRulesFile, new TypeReference<List<Rule>>() {
});
#RunWith(SpringRunner.class)
#SpringBootTest
class PostSaveServiceTest {
private static final String PATH_TO_JSON = "classpath:json/post-save";
private static final String EXTENSION_JSON = ".json";
#Test
void setData() {
ObjectMapper objectMapper = new ObjectMapper();
Post post = runParseJsonFile(objectMapper);
System.out.println(post);
}
private Post runParseJsonFile(ObjectMapper objectMapper) {
File pathToFileJson = getPathToFileJson(PATH_TO_JSON + EXTENSION_JSON);
Post post = null;
try {
post = objectMapper.readValue(pathToFileJson, Post.class);
} catch (IOException e) {
System.out.println("File didn't found : " + e);
}
return post;
}
private File getPathToFileJson(String path) {
File pathToJson = null;
try {
pathToJson = ResourceUtils.getFile(path);
} catch (IOException e) {
e.printStackTrace();
}
return pathToJson;
}
}

serialize json array into java objects

I have a JSON array like as shown below which I need to serialize it to my class. I am using Jackson in my project.
[
{
"clientId": "111",
"clientName": "mask",
"clientKey": "abc1",
"clientValue": {}
},
{
"clientId": "111",
"clientName": "mask",
"clientKey": "abc2",
"clientValue": {}
}
]
In above JSON array, clientValue will have another JSON object in it. How can I serialize my above JSON array into my java class using Jackson?
public class DataRequest {
#JsonProperty("clientId")
private String clientId;
#JsonProperty("clientName")
private int clientName;
#JsonProperty("clientKey")
private String clientKey;
#JsonProperty("clientValue")
private Map<String, Object> clientValue;
//getters and setters
}
I have not used jackson before so I am not sure how can I use it to serialize my JSON array into Java objects? I am using jackson annotation here to serialize stuff but not sure what will be my next step?
You can create a utility function shown below. You may want to change the Deserialization feature based on your business needs. In my case, I did not want to fail on unknown properties => (FAIL_ON_UNKNOWN_PROPERTIES, false)
static <T> T mapJson(String body,
com.fasterxml.jackson.core.type.TypeReference<T> reference) {
T model = null;
if(body == null) {
return model;
}
com.fasterxml.jackson.databind.ObjectMapper mapper =
new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
try {
model = mapper.readValue(body, reference);
} catch (IOException e) {
//TODO: log error and handle accordingly
}
return model;
}
You can call it using similar approach as shown below:
mapJson(clientValueJsonString,
new com.fasterxml.jackson.core.type.TypeReference<List<DataRequest>>(){});
You can try #JsonAnyGetter and #JsonAnySetter annotations with an inner class object. Also clientName should have type String, not int.
public class DataRequest {
private String clientId;
private String clientName;
private String clientKey;
private ClientValue clientValue;
//getters and setters
}
public class ClientValue {
private Map<String, String> properties;
#JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
#JsonAnyGetter
public Map<String,String> getProperties() {
return properties;
}
}

Converting Java objects to JSON with Jackson

I want my JSON to look like this:
{
"information": [{
"timestamp": "xxxx",
"feature": "xxxx",
"ean": 1234,
"data": "xxxx"
}, {
"timestamp": "yyy",
"feature": "yyy",
"ean": 12345,
"data": "yyy"
}]
}
Code so far:
import java.util.List;
public class ValueData {
private List<ValueItems> information;
public ValueData(){
}
public List<ValueItems> getInformation() {
return information;
}
public void setInformation(List<ValueItems> information) {
this.information = information;
}
#Override
public String toString() {
return String.format("{information:%s}", information);
}
}
and
public class ValueItems {
private String timestamp;
private String feature;
private int ean;
private String data;
public ValueItems(){
}
public ValueItems(String timestamp, String feature, int ean, String data){
this.timestamp = timestamp;
this.feature = feature;
this.ean = ean;
this.data = data;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
public int getEan() {
return ean;
}
public void setEan(int ean) {
this.ean = ean;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return String.format("{timestamp:%s,feature:%s,ean:%s,data:%s}", timestamp, feature, ean, data);
}
}
I just missing the part how I can convert the Java object to JSON with Jackson:
public static void main(String[] args) {
// CONVERT THE JAVA OBJECT TO JSON HERE
System.out.println(json);
}
My Question is: Are my classes correct? Which instance do I have to call and how that I can achieve this JSON output?
To convert your object in JSON with Jackson:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(object);
I know this is old (and I am new to java), but I ran into the same problem. And the answers were not as clear to me as a newbie... so I thought I would add what I learned.
I used a third-party library to aid in the endeavor: org.codehaus.jackson
All of the downloads for this can be found here.
For base JSON functionality, you need to add the following jars to your project's libraries:
jackson-mapper-asl
and
jackson-core-asl
Choose the version your project needs. (Typically you can go with the latest stable build).
Once they are imported in to your project's libraries, add the following import lines to your code:
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
With the java object defined and assigned values that you wish to convert to JSON and return as part of a RESTful web service
User u = new User();
u.firstName = "Sample";
u.lastName = "User";
u.email = "sampleU#example.com";
ObjectMapper mapper = new ObjectMapper();
try {
// convert user object to json string and return it
return mapper.writeValueAsString(u);
}
catch (JsonGenerationException | JsonMappingException e) {
// catch various errors
e.printStackTrace();
}
The result should looks like this:
{"firstName":"Sample","lastName":"User","email":"sampleU#example.com"}
Just follow any of these:
For jackson it should work:
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
//will return json in string
For gson it should work:
Gson gson = new Gson();
return Response.ok(gson.toJson(yourClass)).build();
You could do this:
String json = new ObjectMapper().writeValueAsString(yourObjectHere);
This might be useful:
objectMapper.writeValue(new File("c:\\employee.json"), employee);
// display to console
Object json = objectMapper.readValue(
objectMapper.writeValueAsString(employee), Object.class);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json));
You can use Google Gson like this
UserEntity user = new UserEntity();
user.setUserName("UserName");
user.setUserAge(18);
Gson gson = new Gson();
String jsonStr = gson.toJson(user);
Well, even the accepted answer does not exactly output what op has asked for. It outputs the JSON string but with " characters escaped. So, although might be a little late, I am answering hopeing it will help people! Here is how I do it:
StringWriter writer = new StringWriter();
JsonGenerator jgen = new JsonFactory().createGenerator(writer);
jgen.setCodec(new ObjectMapper());
jgen.writeObject(object);
jgen.close();
System.out.println(writer.toString());
Note: To make the most voted solution work, attributes in the POJO have to be public or have a public getter/setter:
By default, Jackson 2 will only work with fields that are either
public, or have a public getter method – serializing an entity that
has all fields private or package private will fail.
Not tested yet, but I believe that this rule also applies for other JSON libs like google Gson.
public class JSONConvector {
public static String toJSON(Object object) throws JSONException, IllegalAccessException {
String str = "";
Class c = object.getClass();
JSONObject jsonObject = new JSONObject();
for (Field field : c.getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
String value = String.valueOf(field.get(object));
jsonObject.put(name, value);
}
System.out.println(jsonObject.toString());
return jsonObject.toString();
}
public static String toJSON(List list ) throws JSONException, IllegalAccessException {
JSONArray jsonArray = new JSONArray();
for (Object i : list) {
String jstr = toJSON(i);
JSONObject jsonObject = new JSONObject(jstr);
jsonArray.put(jsonArray);
}
return jsonArray.toString();
}
}

Categories

Resources