Jackson Parsing for json object inside json - java

I have sample json data like below
{"data":{"detection":[{"category":"building","coordinates":{"xmin":"0.31","ymin":"0.42","ymax":"0.82","xmax":"0.89"},"accuracy":"0.66"}]}}
Trying to parse data field in jackson parser and created ObjectCategories class(setter getter) for its values.
#JsonProperty("categories")
private List<ObjectCategory> categories;
#SuppressWarnings("unchecked")
#JsonProperty(DATA)
private void unpackNested(Map<String,Object> data) {
this.categories = (ArrayList<ObjectCategory>) data.get("detection");
}
If we execute the above code, getting this exception - getCategories().get(0).getAccuracy() to java.util.LinkedHashMap cannot be cast to ObjectCategory
getCategories().get(0) returns Map value. How to parse with my ObjectCategory class.

You can convert the value if you originally deserialized it to map.
this.categories = objectMapper
.convertValue(data.get("detection"),
new TypeReference<List<ObjectCategory>>() {});

Related

Convert multiple Java Beans to JSON

I have multiple Java bean classes that are associated to each other (JSON Array + JSON Object) since they have a nested structure.
There are about 10 classes. Is there a way to collectively convert these classes or at-least one by one?
I had created these classes out of a JSON data which I don't have access to right now.
So, now, what I'm looking forward is to create a dummy JSON out of those classes.
Using GSON, I tried converting one of these Bean classes however, I got an empty result. Here is one of the beans called Attachment.java.
Attachment.java
package mypackagename;
import java.io.Serializable;
public class Attachment implements Serializable{
private Payload payload;
private String type;
public Payload getPayload() {
return payload;
}
public void setPayload(Payload payload) {
this.payload = payload;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Implementation
Gson gson = new Gson();
Attachment attachment = new Attachment();
String json = gson.toJson(attachment);
Sure you got an empty result. Because your JSON object is empty. You should add data to your object and test it again as below:
Attachment attachment = new Attachment(new Payload("Test Payload"), "Test attachment");
String json = new Gson().toJson(attachment);
Log.e("Test", "Json: " + json); // result: Json: {"payload":{"test":"Test Payload"},"type":"Test attachment"}
To avoid empty object, you have to set a default value to your payload and type becaus Gson will ignore any null value.
This section of the Gson User Guide: https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
The fourth bullet point explains how null fields are handled.

Convert Json string to Java object gives null (null)

Hello i got this Json string
{"NexusResource":{"resourceURI":"http://nexus.ad.hrm.se/nexus/service/local/repositories/snapshots/content/se/hrmsoftware/hrm/hrm-release/16.1-SNAPSHOT/","relativePath":"/se/hrmsoftware/hrm/hrm-release/16.1-SNAPSHOT/","text":"16.1-SNAPSHOT","leaf":false,"lastModified":"2018-04-09 12:23:59.0 UTC","sizeOnDisk":-1}}
I want to convert this to an object of a class named NexusResource that looks like this
public class NexusResource {
#JsonProperty("resourceURI") private String resourceURI;
#JsonProperty("relativePath") private String relativePath;
#JsonProperty("text") private String text;
#JsonProperty("leaf") private Boolean leaf;
#JsonProperty("lastModified") private String lastModified;
#JsonProperty("sizeOnDisk") private Integer sizeOnDisk;
#JsonIgnore private Map<String, Object> additionalProperties = new HashMap<>();
}
i try to convert it with an ObjectMapper
ObjectMapper mapper = new ObjectMapper();
NexusResource resource = mapper.readValue(version, NexusResource.class);
were version is the Json string but when i log resource all i get is null (null) even though version got all the data.
You can configure your ObjectMapper to unwrap the root value, in order to de-serialize into your POJO.
E.g.:
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
See API.
You could also work around that by modifying your POJO (see Karol's answer).
Failure to choose either should result in a com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException being thrown, with message: Unrecognized field "NexusResource".
NexusResource is not a root of your JSON but a key. To make your Java mapping work you should define a wrapping type:
public class NexusResources {
#JsonProperty("NexusResource") private NexusResource root;
...
}
and then use it to map:
ObjectMapper mapper = new ObjectMapper();
NexusResources root = mapper.readValue(version, NexusResources.class);
NexusResource resource = root.getRoot();
The problem is that the JSON does not match the class you are trying to parse. Please notice that the JSON has a field called "NexusResource" that has all the other fields. Whereas the class NexusResource.class just has the fields. Two things you can do. Change the JSON to match NexusResource.class, or create a new class that matches the JSON.
1) Change the json to the following.
{"resourceURI":"http://nexus.ad.hrm.se/nexus/service/local/repositories/snapshots/content/se/hrmsoftware/hrm/hrm-release/16.1-SNAPSHOT/","relativePath":"/se/hrmsoftware/hrm/hrm-release/16.1-SNAPSHOT/","text":"16.1-SNAPSHOT","leaf":false,"lastModified":"2018-04-09 12:23:59.0 UTC","sizeOnDisk":-1}
2) Create new class that actually matches your Json.
class NexusResourceJson {
#JsonProperty("NexusResource ")
NexusResource resource;
public NexusResource getResource() {return resource;}
}
ObjectMapper mapper = new ObjectMapper();
NexusResource resource = mapper.readValue(version, NexusResourceJson.class).getResource();

Java - Google GSON syntax error

So I'm trying to parse a request that comes in JSON format, but the Google GSON library throws a syntax error.
The request looks like this: {"action":"ProjectCreation", data:{"projectName": "test project"}}.
Which doesn't look like it has a syntax error to me...
Here is the error that GSON gives me:
Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 20 path $.
EDIT:
I fixed the syntax error in the JSON request, it now looks like this {"action":"ProjectCreation", "data":{"projectName": "test project"}}.
GSON is still throwing the same error....
EDIT:
The code responsible for parsing the request looks like this:
private Type type = new TypeToken<Map<String, Object>>(){}.getType();
private String action;
private String responseAction;
private Map<String, String> data;
private Type dataType = new TypeToken<Map<String, String>>(){}.getType();
private Gson gson = new Gson();
private String requestId;
private Client client = new Client("127.0.0.1", 5699);
/**
* Constructor for this class, sets initial parameters
* #param request
* #param _requestId
*/
public ActionThread(String request, String _requestId) {
System.out.println(request);
//Parse the request into a map
Map<String, Object> _request = gson.fromJson(request, type);
//Give action the correct naming convention
action = _request.get("action") + "Request";
responseAction = _request.get("action") + "Response";
//Parse the data into a map
String _data = _request.get("data").toString();
data = gson.fromJson(_data, dataType);
//Set the request id
requestId = _requestId;
}
_request.get("data").toString() is not the JSON representation of your data object. It's the string representation of the inner map you just parsed that is equal to {projectName=test project}.
One easy and quick way to solve this would be to convert your data object into its JSON representation and then parse it again:
Map<String, String> data = gson.fromJson(gson.toJson(_request.get("data")), dataType);
It might be worth to consider having dedicated classes as well, for instance:
class Action {
#SerializedName("action")
String name;
Data data;
}
class Data {
String projectName;
}
and then
Action action = gson.fromJson(request, Action.class);
If you want to have the nested data object as a field directly in the Action class you could also write a custom deserializer.

JsonIgnore on subattributes [duplicate]

I'm using SpringMVC and have the following Method.
#RequestMapping("/login")
public #ResponseBody User login(User user) {
// some operation here ....
return user;
}
In most cases, SpringMVC converts an object to JSON in a proper manner. However sometimes you might need to customize the JSON. Where can I customize the JSON for ALL the User object. I want the behavior of converting a User object to JSON to be consistent across the board. I guess a listener or interface can achieve that. Does that kind of solution exist?
PS. What if the Object I wanna convert is an instance of third-party class? I cannot customize it in the class definition because I don't have the source code...
Spring uses Jackson to serialize and deserialize JSON by default. You can use Jackson's #JsonSerialize annotation on your User type and provider a JsonSerializer implementation which performs the serialization as you want it.
Below posting an example for deserializing json Array to Arraylist
#RequestMapping(value = "/mapJsonObjects", method = RequestMethod.POST)
public static ModelAndView parseJSONObjects(#RequestParam String jsonList,HttpServletRequest request,
HttpServletResponse response) throws Exception {
JSONParser parser=new JSONParser();
ArrayList filteredList = new ArrayList();
Object obj = parser.parse(jsonList);
JSONArray newList = (JSONArray)obj;
filteredList = newList;
-----------
}
To convert an array List to json array. First add the below beans to springServlet.xml
<bean name="jsonView"
class="org.springframework.web.servlet.view.json.JsonView">
<property name="contentType">
<value>text/html</value>
</property>
</bean>
Then from the controller return the arraylist as below
Map<String, Object> filteredMap = new LinkedHashMap<String, Object>();
List<Accountdb> filteredList;
------filteredMap logic -----------
filteredAccountMap.put("rows", filteredList);
return new ModelAndView("jsonView", filteredMap);

Ignore a java bean field while converting to jSON

Ignore a java bean field while converting to jSON
I am having a java bean and sending JSON as response , In that java bean I want to have
some transient fields , that should not come into JSON .
#XmlRootElement(name = "sample")
class Sample{
private String field1;
#XmlTransient
private String transientField;
//Getter and setters
public String toJSON() throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(this);
return json;
}
}
When I am calling toJSON method I am still getting "transientField" in JSON.
And I have a get rest API that returns this Sample JSON as response.
#GET
#Path("/somePath/")
#Produces({"application/json"})
Sample getSample();
In this response also I am getting that transient field .
Am I doing something wrong? Please help me to do this .
Try using #JsonIgnore instead.
method 1: use annotation #JsonIgnoreProperties("fieldname") to your POJO
example : #JsonIgnoreProperties(ignoreUnknown = true, value = {"fieldTobeIgnored"})
method 2:#JsonIgnore for a specific field that is to be ignored deserializing JSON

Categories

Resources