I have JSON that I get using retrofit
[{
"id":"1",
"name":"name",
"fields_json":{
"f1":"value1",
"f2":"value2",
"f3":"value3"
}
},{
"id":"2",
"name":"name2",
"fields_json":{
"f1":"value1",
"f2":"value2",
"f3":"value3"
}
}]
I want get List of Person(long id, String name, Map fields)
How I may get fields_json as Map in this class?
If you change your json a bit, so you can use special response classes
{"persons":[{id":"1","name":"name", ...} ] }
public class Response {
#SerializedName("persons")
#Expose
public ArrayList<Person> persones;
}
public class Person {
#SerializedName("id")
#Expose
public String id;
#SerializedName("name")
#Expose
public String name;
#SerializedName("fields_json")
#Expose
public FieldsJson fieldsJson;
}
public class FieldsJson {
#SerializedName("f1")
#Expose
public String f1;
#SerializedName("f2")
#Expose
public String f2;
#SerializedName("f3")
#Expose
public String f3;
}
and set this class as response
#POST("/url")
Call<Response> getPersones(
....
);
So, if you wish You can describe public fieldsJson as Map
Map<String, Object> fieldsJson
It cannot be added as a Map object.
Instead you need to create another java class that contains the f1-f3 variables.
Then add this new class as a variable with the name of fields_json to your current class.
Related
I'm trying to deserialize a JSON object using Jackson annotation, but I can't deserialize it:
Is an array of a type "Deposito"
{
"depositos": [
{
"deposito": {
"id": "13168775373",
"nome": "Geral",
"saldo": "100000.0000000000",
"desconsiderar": "N",
"saldoVirtual": "100000.0000000000"
}
}
]
}
my java class:
#JsonUnwrapped
#JsonProperty(value ="depositos")
private List<Deposito> depositos;
my deposito class:
#JsonRootName(value = "deposito")
public class Deposito {
private String id;
private String nome;
private Double saldo;
private String desconsiderar;
private Double saldoVirtual;
}
You would need to add an additional class to your model:
public class DepositoMetadata {
private Deposito deposito;
}
Now you need to adjust your main java class (as you called it):
private List<DepositoMetadata> depositos;
Finally, you can remove #JsonRootName(value = "deposito") from your Deposito class.
I want to create a DTO for Jackson to serialize my jsonPatch variables into a json patch variable.
I have this attributes to represent the class Person:
#JsonProperty("lastName")
private String lastName;
#JsonProperty("firstName")
private String firstName;
#JsonProperty("age")
private int age;
#JsonProperty("a")
private A classA;
And also the class A has:
#JsonProperty("colour")
private String colour;
#JsonProperty("quantity")
private BigDecimal quantity;
The DTO that I created was something like this:
#JsonProperty("path")
protected String path;
#JsonProperty("op")
protected String operation;
#JsonProperty("value")
protected Object values;
The json patch that I receive can have on the values class either a Person or the class A:
Patch for Person:
[
{
"value":
{
"lastName": "Doe",
"firsName": "John"
},
"path": /people",
"op": "replace"
}
]
Patch for A:
[
{
"value":
{
"quantity": 12.1,
},
"path": /A",
"op": "remove"
}
]
The value can be either a Person or a class A, as I told you, that's why the value is an Object class.
My problem is that when Jackson serializes the value from Person, it serializes to a Map, and when the value is from object A, it serializes to a double, which will lead to casting the values, which could be very dangerous.
Is there any way to tell Jackson that the values are from a Person object or from an A object, so it can serialize without any cast?
I would recommend creating a common class with all the properties and add JsonIgnoreProperties to the class so that Jackson will ignore unknown properties while deserializing
#JsonIgnoreProperties(ignoreUnknown = true)
class Common {
#JsonProperty("colour")
private String colour;
#JsonProperty("quantity")
private BigDecimal quantity;
#JsonProperty("lastName")
private String lastName;
#JsonProperty("firstName")
private String firstName;
#JsonProperty("age")
private int age;
#JsonProperty("a")
private A classA;
}
And then after deserializing the JSON to Common object just do null check to identify deserialized JSON is Person or A class
if(common.getFirstName()!=null && common.getLastName()!=null)
// Person class
if(common.getQuantity()!=null)
// A class
I have a json like this:
"subject": {
"category": [
{
"name": "name1"
},
{
"name": "name2"
},
{
"name": "name3"
},
{
"name": "name4"
}
]
}
So it is an object containing a name array. What could be an equivalent Pojo for this?
Should I create a Subject object which has a string list called category?
I tried this:
public class Subject {
#JsonProperty(value = "category")
private List<String> name;
//getter setter ...
}
But I get nested exception: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
Every object should ideally be a class and every array a collection in Java.
It should be:
public class Subject {
private List<Category> category;
//getters and setters
}
class Category{
String name;
//getters and setters
}
yes you are right ..you can implement POJO like you mentioned
class Subject{
List<String> categories;
// getters and setters
}
In this json file you have Subject object containing one Array of objects "category" if you need values from that Subject object you should extract like this
console.log(Subject.category[0].name);
Why don't you just use Gson. Its pretty solid and well tested.
Subject subject = new Gson().fromJson(jsonObject.toString(), Subject.class);
You can also try this if Gson isn't an option here
public class Subject{
private List<Category> category;
//setter/getter(s)
private static class Category{
String name;
}
}
In addition to dev8080 answer I would suggest using jsonschema2pojo service.
If you paste there your source JSON and select Source type: JSON you will have the following output:
---------------com.example.Subject.java---------------
package com.example;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
public class Subject {
#Valid
private List<Category> category = new ArrayList<Category>();
public List<Category> getCategory() {
return category;
}
public void setCategory(List<Category> category) {
this.category = category;
}
}
---------------com.example.Category.java---------------
package com.example;
public class Category {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And you can easily tweak it using options or adopt some parts by hand.
Hi I'm writing an android App that interfaces with an external webservice that outputs JSON formatted info.
I'm using GSON to generate POJOs for the output of the web service, but I'm having a problem with this entity:
player: {
1: {
number: "6",
name: "Joleon Lescott",
pos: "D",
id: "2873"
},
2: {
number: "11",
name: "Chris Brunt",
pos: "D",
id: "15512"
},
3: {
number: "23",
name: "Gareth McAuley",
pos: "D",
id: "15703"
}
}
Using a service like http://www.jsonschema2pojo.org/ I was able to generate a POJO that matches to this output like this:
public class Player {
#SerializedName("1")
#Expose
private com.example._1 _1;
#SerializedName("2")
#Expose
private com.example._2 _2;
.....
}
public class _1 {
#Expose
private String name;
#Expose
private String minute;
#Expose
private String owngoal;
#Expose
private String penalty;
#Expose
private String id;
....
}
However I would like to tweak this a little bit and instead of having an object for _1, _2, etc, I would like to have an array or list containing all data, like this:
public class Players{
private List<Player> players;
}
public class Player{
#Expose
private int position;
#Expose
private String name;
#Expose
private String minute;
#Expose
private String owngoal;
#Expose
private String penalty;
#Expose
private String id;
....
}
How can I accomplish this, without manually parsing the JSON file?
Register a TypeAdapter for your Players class. In the deserialize method iterate over keys in the json and add them to an ArrayList. That should work, I think. An example in pseudo-code:
class PlayersAdapter implements JsonDeserializer<Players> {
public Players deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) {
List<Player> players = new ArrayList<>();
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
players.add(ctx.deserialize(entry.getValue(), Players.class));
}
return new Players(players);
}
}
// ...
Gson gson = new GsonBuilder()
.registerTypeAdapter(Players.class, new PlayersAdapter())
.create();
I have the following JSON:
{
"data": {
"1": {
"id":"1",
"name":"test1"
},
"2": {
"id":"2",
"name":"test2"
}
}
}
I want to parse the "data" into an Object with Jackson. If I parse it as Map<String, Object> it works well, whereas "1", "2" (...) are used as Key with the respective data as value, represented by a Map again.
Now I want to parse this JSON to Map<String, TypeA> whereas class TypeA would have two fields, id and name.
Can someone give me a hint how to to that?
I always get the following error:
Could not read JSON: No suitable constructor found for type [simple
type, class TypeA]: can not instantiate from JSON object (need to
add/enable type information?)
Thanks a lot in advance,
tohoe
The following should work out for you.
public class MyDataObject {
private final Map<String, TypeA> data;
#JsonCreator
public MyDataObject(#JsonProperty("data") final Map<String, TypeA> data) {
this.data = data;
}
public Map<String, TypeA> getData() {
return data;
}
}
public class TypeA {
private final String id;
private final String name;
#JsonCreator
public TypeA(#JsonProperty("id") final String id,
#JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
The #JsonCreator is used for describing how to create your objects together with the name of the properties #JsonProperty. Even if they are nested.
To deserialize the whole thing:
ObjectMapper mapper = new ObjectMapper();
final MyDataObject myDataObject = mapper.readValue(json, MyDataObject.class);