I need to unmarshall JSON having array as a top-level element:
[
{
"test1":
{
"name": "Boost",
"fraction": 0.55
}
},
{
"test2":
{
"name": "Boost",
"fraction": 0.55
}
}
]
My top-level element looks like this:
import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
public class Wrapper<T> {
#XmlTransient
private List<T> items;
public Wrapper() {
items = new ArrayList<>();
}
public Wrapper(List<T> items) {
this.items = items;
}
#XmlElement
public List<T> getItems() {
return items;
}
}
Unmarshalling is done in this method:
private <T> T get(String path, Class<T> aClass) {
WebTarget target = root.path(path);
Invocation.Builder request = target.request(MediaType.APPLICATION_JSON_TYPE);
return request.get(aClass);
}
When I tried to marshall an existing object into json I have got the following result:
{
"items" : [
{
"test1":
{
"name": "Boost",
"fraction": 0.55
}
},
{
"test2":
{
"name": "Boost",
"fraction": 0.55
}
}
]}
How can I force JAXB to skip this items key?
Thanks for your help.
I solved the problem using GenericType new GenericType<List<MyObject>>() {}
Related
I have a class FolderResult with the following model defined. I am getting duplicate entries for uploadDetails. When i inspect the map has only one entry
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.HashMap;
import java.util.Map;
public class FolderResult {
private String folderType;
#JsonProperty("uploadDetails")
private Map<String, Object> uploadDetails = new HashMap<>();
public String getFolderType() {
return folderType;
}
public void setFolderType(String folderType) {
this.folderType = folderType;
}
#Override
public String toString() {
return "FolderResult{"
+ "folderType='"
+ folderType
+ '\''
+ ", uploadDetails="
+ uploadDetails
+ '}';
}
#JsonAnyGetter
public Map<String, Object> getUploadDetails() {
return uploadDetails;
}
#JsonAnySetter
public void setUploadDetails(String key, Object value) {
uploadDetails.putIfAbsent(key, value);
}
}
In the API Response for 201, i have defined this class as the output.
I get duplicate responses.
{
"folderType": "mri",
"uploadDetails": {
"mriLocationsFile": {
"uploadUrl": "String",
"fileUri": "import/folders/1349/files/4310",
"presignParams": {
"accessKeyId": "ff=",
"secretAccessKey": "dd==",
"sessionToken": "dd",
"path": "dd",
"region": "dd"
}
},
"mriLocationsFile": {
"uploadUrl": "String",
"fileUri": "import/folders/1349/files/4310",
"presignParams": {
"accessKeyId": "ff=",
"secretAccessKey": "dd==",
"sessionToken": "dd",
"path": "dd",
"region": "dd"
}
}
}
I would like only one uploadDetails in json like below. What should i fix in model
{
"folderType": "mri",
"uploadDetails": {
"mriLocationsFile": {
"uploadUrl": "String",
"fileUri": "import/folders/1349/files/4310",
"presignParams": {
"accessKeyId": "ff=",
"secretAccessKey": "dd==",
"sessionToken": "dd",
"path": "dd",
"region": "dd"
}
}
}
I want to receive Json data from server using Retrofit.
Below is Data class and Json example.
After finish transfer the 'Page' object is returned from Response.body().
But inside it the array 'cards' has 'null' value.
How can I get the correct data?
[Page.java]===========
public class Page {
public List<Cards> cards;
public Page(List<Cards> cards) {
this.cards = cards;
}
public class Cards {
public String card_type;
public Cards(String card_type) {
this.card_type = card_type;
}
}
}
[Json example]===============
{
"page": {
"cards": [
{
"card_type": "text",
"card": {
"value": "Hello, Welcome to App!",
"attributes": {
"text_color": "#262626",
"font": {
"size": 30
}
}
}
},
{
"card_type": "title_description",
"card": {
"title": {
"value": "Check out our App every week for exciting offers.",
"attributes": {
"text_color": "#262626",
"font": {
"size": 24
}
}
},
"description": {
"value": "Offers available every week!",
"attributes": {
"text_color": "#262626",
"font": {
"size": 18
}
}
}
}
},
]
}
}
first of all your model class not have get methods , your methods are setter not getter and its normal you cant get data without getter method , change your model like below :
at first , do not use inner class , made classes separate together
public class Page {
public List<cards> cards;
public List<cards> getCards() {
return cards;
}
public class cards {
public String card_type;
public String getCard_type() {
return card_type;
}
public card card;
public card getCard() {
return card;
}
}
public class card {
public String value;
public String getValue() {
return value;
}
public attributes attributes;
public String getAttributes() {
return attributes;
}
}
now this classes correct for your index 0 of cards , but your Json sample not have organization at next index ... but you can made title class or description class and add it to card class for get more data from any index of your list.
public class MyResponse {
private List<Data> data;
public static class Data {
private long id;
private String name;
}
}
Using Jackson this gets serialized to the following JSON:
{
"data": [
{
"id": 115125,
"name": "AAAY"
}
]
}
What I need instead is the JSON like this, i,e. omitting the wrapping Data class:
[
{
"id": 115125,
"name": "AAAY"
}
]
Place the #JsonValue annotation on the data field:
public class MyResponse {
#JsonValue
private List<Data> data;
...
}
I am trying to map the following JSON to my POJO using Jackson. I have the following JSON and following POJOs. kindly let me know how to map the JSON to POJO.
JSON string :
{
"Application": {
"id": "0",
"name": "MyApp",
"users": [
{
"User": {
"id": "2",
"name": "Beth Jones"
}
}
],
"groups": [
{
"Group": {
"id": "1",
"name": "SimpleGroup",
"users": [
{
"User": {
"id": "2",
"name": "Beth Jones"
}
}
]
}
}
]
}
}
The POJO according to the client specification is below :
package com.example.custom;
//import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.example.Application;
import com.example.Group;
import com.example.User;
import java.util.Collection;
//#JsonIgnoreProperties(ignoreUnknown = true)
public class MyApplication extends Application {
private Collection<User> users;
private Collection<Group> groups;
public MyApplication(String id, String name) {
super(id, name);
}
public void setUsers(Collection<User> users) {
this.users = users;
}
public void setGroups(Collection<Group> groups) {
this.groups = groups;
}
#Override
public Collection<User> getUsers() {
return this.users;
}
#Override
public User getUser(String userId) {
for (User user: MyParser.myApp.getUsers()) {
if (user.getId().equals(userId))
return user;
}
return null;
}
#Override
public Collection<Group> getGroups() {
return this.groups;
}
#Override
public Group getGroup(String groupId) {
for (Group group: MyParser.myApp.getGroups()) {
if (group.getId().equals(groupId))
return group;
}
return null;
}
#Override
public String toString() {
return "MyApplication{" +
"users=" + users +
", groups=" + groups +
'}';
}
}
Mapping Logic :
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyParser.myApp = mapper.readValue(rewriter.getText(),MyApplication.class);
The resulting object is not able to capture anything as it is all null. Kindly help. Thanks in advance.
I think you should model your JSON correctly, In the users list you shouldn't specify it again that the key is User, that should be preassumed that a list of users will only contain user, same goes for groups list.
IMHO the JSON should look something like this :
{
"application": {
"id": "0",
"name": "MyApp",
"users": [ . ==> Since this is a user List, it will definitely contains user.
{
"id": "2",
"name": "Beth Jones"
}
],
"groups": [
{
"id": "1",
"name": "SimpleGroup",
"users": [
{
"id": "2",
"name": "Beth Jones"
}
]
}
]
}
}
Now the POJO also needs some modification, I am just adding the bare-minimum POJO.
class Application { <====== Top Level Class
private Long id;
private String name;
private List<User> users; // Application has some Users
private List<Group> groups; // Application has some groups
}
class User {
private Long id;
private String name;
}
class Group {
private Long id;
private String name;
private List<User> users; // Each group has some associated users.
}
Now you can use any standard JSON library for Java and convert your JSON into POJO. This will simplify your structure and you won't face null issues with this structure.
I have been using jackson to deserialize successfully json objects and arrays, but this time I just can't wrap my head around how to approach deserialization for the following object. How can I, with Jackson or any other json parsing library, deserialize:
[
{
"name": "x",
"elements": {
"key1": {
"name": "a",
"type": "b"
},
"key2": {
"name": "a",
"type": "b"
}
}
},
{
"name": "y",
"elements": {
"key3": {
"name": "a",
"type": "b"
}
}
}
]
into a list, List<Test>, where Test is defined below?
public class Test {
public class Element {
public String name;
public String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public String name;
public Map<String, Element> elements;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Element> getElements() {
return elements;
}
public void setElements(Map<String, Element> elements) {
this.elements = elements;
}
}
Finally, my deserializing code:
public List<Test> test(final InputStream inputStream) {
List<Test> test = null;
try {
test = mapper.readValue(inputStream, new TypeReference<List<Test>>() { });
} catch (final IOException e) {
log.error("Unable to deserialize json",e);
}
return test;
}
If that is not possible, what object can I actually deserialize my json into? One thing I cannot know ahead of time is the name of the keys (key1, key2, key3 in the example).
It looks like this:
ObjectMapper mapper = new ObjectMapper();
List<Test> tests = mapper.readValue(jsonInput, new TypeReference<List<Test>>() { };
would do it. The only tricky part is that TypeReference, which is needed to pass generic type information. Other libs use similar approaches (GSON has TypeToken or such).