I want to convert the following JSON string to a java object:
String jsonString = "{
"libraryname": "My Library",
"mymusic": [
{
"Artist Name": "Aaron",
"Song Name": "Beautiful"
},
{
"Artist Name": "Britney",
"Song Name": "Oops I did It Again"
},
{
"Artist Name": "Britney",
"Song Name": "Stronger"
}
]
}"
My goal is to access it easily something like:
(e.g. MyJsonObject myobj = new MyJsonObject(jsonString)
myobj.mymusic[0].id would give me the ID, myobj.libraryname gives me "My Library").
I've heard of Jackson, but I am unsure how to use it to fit the json string I have since its not just key value pairs due to the "mymusic" list involved. How can I accomplish this with Jackson or is there some easier way I can accomplish this if Jackson is not the best for this?
No need to go with GSON for this; Jackson can do either plain Maps/Lists:
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> map = mapper.readValue(json, Map.class);
or more convenient JSON Tree:
JsonNode rootNode = mapper.readTree(json);
By the way, there is no reason why you could not actually create Java classes and do it (IMO) more conveniently:
public class Library {
#JsonProperty("libraryname")
public String name;
#JsonProperty("mymusic")
public List<Song> songs;
}
public class Song {
#JsonProperty("Artist Name") public String artistName;
#JsonProperty("Song Name") public String songName;
}
Library lib = mapper.readValue(jsonString, Library.class);
Check out Google's Gson: http://code.google.com/p/google-gson/
From their website:
Gson gson = new Gson(); // Or use new GsonBuilder().create();
MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
You would just need to make a MyType class (renamed, of course) with all the fields in the json string. It might get a little more complicated when you're doing the arrays, if you prefer to do all of the parsing manually (also pretty easy) check out http://www.json.org/ and download the Java source for the Json parser objects.
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonObject object = (JsonObject) parser.parse(response);// response will be the json String
YourPojo emp = gson.fromJson(object, YourPojo.class);
Gson is also good for it: http://code.google.com/p/google-gson/
"
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
"
Check the API examples: https://sites.google.com/site/gson/gson-user-guide#TOC-Overview
More examples: http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
In my case, I passed the JSON string as a list. So use the below solution when you pass the list.
ObjectMapper mapper = new ObjectMapper();
String json = "[{\"classifier\":\"M\",\"results\":[{\"opened\":false}]}]";
List<Map<String, Object>> map = mapper
.readValue(json, new TypeReference<List<Map<String, Object>>>(){});
Underscore-java (which I am the developer of) can convert json to Object.
import com.github.underscore.U;
String jsonString = "{\n" +
" \"libraryname\":\"My Library\",\n" +
" \"mymusic\":[{\"Artist Name\":\"Aaron\",\"Song Name\":\"Beautiful\"},\n" +
" {\"Artist Name\":\"Britney\",\"Song Name\":\"Oops I did It Again\"},\n" +
" {\"Artist Name\":\"Britney\",\"Song Name\":\"Stronger\"}]}";
Map<String, Object> jsonObject = U.fromJsonMap(jsonString);
System.out.println(jsonObject);
// {libraryname=My Library, mymusic=[{Artist Name=Aaron, Song Name=Beautiful}, {Artist Name=Britney, Song Name=Oops I did It Again}, {Artist Name=Britney, Song Name=Stronger}]}
System.out.println(U.<String>get(jsonObject, "mymusic[0].Artist Name"));
// Aaron
public void parseEmployeeObject() throws NoSuchFieldException, SecurityException, JsonParseException, JsonMappingException, IOException
{
Gson gson = new Gson();
ObjectMapper mapper = new ObjectMapper();
// convert JSON string to Book object
Object obj = mapper.readValue(Paths.get("src/main/resources/file.json").toFile(), Object.class);
endpoint = this.endpointUrl;
String jsonInString = new Gson().toJson(obj);
JsonRootPojo organisation = gson.fromJson(jsonInString, JsonRootPojo.class);
for(JsonFilter jfil : organisation.getSchedule().getTradeQuery().getFilter())
{
String name = jfil.getName();
String value = jfil.getValue();
}
System.out.println(organisation);
}
{
"schedule": {
"cron": "30 19 2 MON-FRI",
"timezone": "Europe/London",
"tradeQuery": {
"filter": [
{
"name": "bookType",
"operand": "equals",
"value": "FO"
},
{
"name": "bookType",
"operand": "equals",
"value": "FO"
}
],
"parameter": [
{
"name": "format",
"value": "CSV"
},
{
"name": "pagesize",
"value": "1000"
}
]
},
"xslt" :""
}
}
public class JesonSchedulePojo {
public String cron;
public String timezone;
public JsonTradeQuery tradeQuery;
public String xslt;
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public JsonTradeQuery getTradeQuery() {
return tradeQuery;
}
public void setTradeQuery(JsonTradeQuery tradeQuery) {
this.tradeQuery = tradeQuery;
}
public String getXslt() {
return xslt;
}
public void setXslt(String xslt) {
this.xslt = xslt;
}
#Override
public String toString() {
return "JesonSchedulePojo [cron=" + cron + ", timezone=" + timezone + ", tradeQuery=" + tradeQuery
+ ", xslt=" + xslt + "]";
}
public class JsonTradeQuery {
public ArrayList<JsonFilter> filter;
public ArrayList<JsonParameter> parameter;
public ArrayList<JsonFilter> getFilter() {
return filter;
}
public void setFilter(ArrayList<JsonFilter> filter) {
this.filter = filter;
}
public ArrayList<JsonParameter> getParameter() {
return parameter;
}
public void setParameter(ArrayList<JsonParameter> parameter) {
this.parameter = parameter;
}
#Override
public String toString() {
return "JsonTradeQuery [filter=" + filter + ", parameter=" + parameter + "]";
}
public class JsonFilter {
public String name;
public String operand;
public String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOperand() {
return operand;
}
public void setOperand(String operand) {
this.operand = operand;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString() {
return "JsonFilter [name=" + name + ", operand=" + operand + ", value=" + value + "]";
}
public class JsonParameter {
public String name;
public String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString() {
return "JsonParameter [name=" + name + ", value=" + value + "]";
}
public class JsonRootPojo {
public JesonSchedulePojo schedule;
public JesonSchedulePojo getSchedule() {
return schedule;
}
public void setSchedule(JesonSchedulePojo schedule) {
this.schedule = schedule;
}
#Override
public String toString() {
return "JsonRootPojo [schedule=" + schedule + "]";
}
Related
I am working on a Spring Boot application and I am finding some problem converting a JSON object (retrieved by a REST call performed using RestTemplate) into a domain object.
This is my main domain object:
public class NotaryDistrict {
String idDistrict;
String denominazione;
String regione;
String provincia;
ArrayList<Localita> localita;
String distretto;
String indirizzo;
String cap;
String telefono;
String fax;
String email;
String pec;
String webUrl;
ArrayList<Carica> cariche;
public NotaryDistrict() {
super();
}
public NotaryDistrict(String idDistrict, String denominazione, String regione, String provincia,
ArrayList<Localita> localita, String distretto, String indirizzo, String cap, String telefono, String fax,
String email, String pec, String webUrl, ArrayList<Carica> cariche) {
super();
this.idDistrict = idDistrict;
this.denominazione = denominazione;
this.regione = regione;
this.provincia = provincia;
this.localita = localita;
this.distretto = distretto;
this.indirizzo = indirizzo;
this.cap = cap;
this.telefono = telefono;
this.fax = fax;
this.email = email;
this.pec = pec;
this.webUrl = webUrl;
this.cariche = cariche;
}
public String getIdDistrict() {
return idDistrict;
}
public void setIdDistrict(String idDistrict) {
this.idDistrict = idDistrict;
}
public String getDenominazione() {
return denominazione;
}
public void setDenominazione(String denominazione) {
this.denominazione = denominazione;
}
public String getRegione() {
return regione;
}
public void setRegione(String regione) {
this.regione = regione;
}
public String getProvincia() {
return provincia;
}
public void setProvincia(String provincia) {
this.provincia = provincia;
}
public ArrayList<Localita> getLocalita() {
return localita;
}
public void setLocalita(ArrayList<Localita> localita) {
this.localita = localita;
}
public String getDistretto() {
return distretto;
}
public void setDistretto(String distretto) {
this.distretto = distretto;
}
public String getIndirizzo() {
return indirizzo;
}
public void setIndirizzo(String indirizzo) {
this.indirizzo = indirizzo;
}
public String getCap() {
return cap;
}
public void setCap(String cap) {
this.cap = cap;
}
public String getTelefono() {
return telefono;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPec() {
return pec;
}
public void setPec(String pec) {
this.pec = pec;
}
public String getWebUrl() {
return webUrl;
}
public void setWebUrl(String webUrl) {
this.webUrl = webUrl;
}
public ArrayList<Carica> getCariche() {
return cariche;
}
public void setCariche(ArrayList<Carica> cariche) {
this.cariche = cariche;
}
#Override
public String toString() {
return "NotaryDistrict [idDistrict=" + idDistrict + ", denominazione=" + denominazione + ", regione=" + regione
+ ", provincia=" + provincia + ", localita=" + localita + ", distretto=" + distretto + ", indirizzo="
+ indirizzo + ", cap=" + cap + ", telefono=" + telefono + ", fax=" + fax + ", email=" + email + ", pec="
+ pec + ", webUrl=" + webUrl + ", cariche=" + cariche + "]";
}
}
As you can see it contains this array field:
ArrayList<Carica> cariche;
This is the field that is giving me problem (if I exclude this one commenting it, it works fine...the others field are correctly mapped)
This is the Carica domain object:
public class Carica {
String idNotary;
String nome;
String cognome;
String carica;
public Carica() {
super();
// TODO Auto-generated constructor stub
}
public Carica(String idNotary, String nome, String cognome, String carica) {
super();
this.idNotary = idNotary;
this.nome = nome;
this.cognome = cognome;
this.carica = carica;
}
public String getIdNotary() {
return idNotary;
}
public void setIdNotary(String idNotary) {
this.idNotary = idNotary;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public String getCarica() {
return carica;
}
public void setCarica(String carica) {
this.carica = carica;
}
#Override
public String toString() {
return "NotaryPosition [idNotary=" + idNotary + ", nome=" + nome + ", cognome=" + cognome + ", carica=" + carica
+ "]";
}
}
Into my business logic code I perform the API call in this way:
ResponseEntity forEntity2 = restTemplate.getForEntity(uri, NotaryDistrict.class);
NotaryDistrict notaryDistrictDetails = forEntity2.getBody();
System.out.println("notaryDistric details: " + notaryDistrictDetails);
{
"idDistrict": "CG7drXn9fvA%253D",
"distretto": "SCIACCA",
"denominazione": "Agrigento e Sciacca",
"provincia": "Agrigento",
"regione": "Sicilia",
"indirizzo": "Viale della Vittoria n.319",
"cap": "92100",
"telefono": "092220111",
"fax": "09222111",
"email": "xxx#yyy.it",
"pec": "zzzz#postacertificata.yyy.it",
"webUrl": null,
"cariche": [
{
"carica": {
"idNotary": "e12oYuuTvE4%253D",
"nome": "Claudia",
"cognome": "Rossi",
"carica": "Presidente"
}
},
{
"carica": {
"idNotary": "XlB2DSwWbfE%253D",
"nome": "Maria",
"cognome": "Verdi",
"carica": "Segretario"
}
},
{
"carica": {
"idNotary": "W8I4vogJ0OM%253D",
"nome": "Giuseppe",
"cognome": "Bianchi",
"carica": "Tesoriere"
}
},
{
"carica": {
"idNotary": "DR6Y%252BA37%252Few%253D",
"nome": "ARIANNA",
"cognome": "Ciani",
"carica": "Consigliere"
}
},
]
}
So all the fields excepet the cariche array are correctly mapped in my NotaryDistrict main domain objects.
The problem occurs when I add the ArrayList cariche; field to this domain object.
I expected that every object into the cariche JSON array has to be mapped with an object into the cariche array of my class.
But I am obtaining this exception:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
at [Source: (PushbackInputStream); line: 1, column: 363] (through reference chain: com.notariato.updateInfo.domain.NotaryDistrict["cariche"]->java.util.ArrayList[0]->com.notariato.updateInfo.domain.Carica["carica"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59) ~[jackson-databind-2.12.4.jar:2.12.4]
The reason of this exception is pretty clear to me: the proble is that the JSON array named cariche contains a wrapper object {...} that itself contains a carica object.
I think that a possible solution is to create a second level wrapper domain object but it is pretty ugly.
Exist a way to set Jackson in order to ignore this {...} wrapper objects and consider only its content, the carica object that must be mapped into this Java array:
ArrayList<Carica> cariche;
One way to do this is to write a custom deserializer. (In fact, if Ralph's comment is correct, this is currently the only way.) You do need to add one more class to your application, but it's a short class.
Below, you'll find a Spring Boot test which includes such a deserializer. As the comments say, it's not production-ready code, but the tests pass, and modifying it to do what you want should be reasonably easy. You may want to read up on how to write Jackson deserializers; if you find any good resource on that, please post it in a comment, since as far as I can tell none exist. Thanks are due to Eugen Paraschiv, one of whose characteristically laconic articles I referenced.
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
// non-static imports omitted for brevity
#RestClientTest
class SampleApplicationTests {
#Autowired MockRestServiceServer server;
#Autowired RestTemplate template;
#TestConfiguration static class Config {
#Bean RestTemplate template(#Autowired RestTemplateBuilder builder) { return builder.build(); }
}
#Data #EqualsAndHashCode #AllArgsConstructor #NoArgsConstructor static class ElementEntity {
String key;
}
#Data static class NiceEntityWithList { List<ElementEntity> list; }
#SuppressWarnings("serial") static class WeirdEntityDeserializer extends StdDeserializer<ElementEntity> {
protected WeirdEntityDeserializer() { this(null); }
protected WeirdEntityDeserializer(Class<?> vc) { super(vc); }
#Override public ElementEntity deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec codec = p.getCodec();
JsonNode weirdElementNode = codec.readTree(p);
JsonNode realElementNode = weirdElementNode.get("common");
// in a real app, handle the case where realElementNode turns out to be null
// we punt to a Jackson method here so this deserializer uses as much of the rest of
// your Jackson configuration as possible
return codec.treeToValue(realElementNode, ElementEntity.class);
// in a real app, handle the case where realElementNode.get("key") is null
// (you may also want to do some sort of validation here)
}
}
#Data static class WeirdEntityWithList {
#JsonDeserialize(contentUsing = WeirdEntityDeserializer.class) List<ElementEntity> list;
}
#Test void niceListDeserializes() {
final String niceJson = "{\"list\": [{\"key\": \"value\"}, {\"key\": \"value2\"}]}";
this.server.expect(requestTo("/nicelist")).andRespond(withSuccess(niceJson, MediaType.APPLICATION_JSON));
NiceEntityWithList nice = template.getForEntity("/nicelist", NiceEntityWithList.class).getBody();
assertEquals(new ElementEntity("value"), nice.getList().get(0));
// could just use nice.list, but let's pretend we're writing
// code for real and the class is in another package
assertEquals(new ElementEntity("value2"), nice.getList().get(1));
}
#Test void weirdListDeserializes() {
final String weirdJson = "{\"list\": [{\"common\": {\"key\": \"value\"}}, {\"common\": {\"key\": \"value2\"}}]}";
server.expect(requestTo("/weirdlist")).andRespond(withSuccess(weirdJson, MediaType.APPLICATION_JSON));
WeirdEntityWithList weird = template.getForEntity("/weirdlist", WeirdEntityWithList.class).getBody();
assertEquals(new ElementEntity("value"), weird.getList().get(0));
assertEquals(new ElementEntity("value2"), weird.getList().get(1));
}
}
This should work in a project downloaded from start.spring.io; you'll need to add spring-starter-web and lombok as dependencies, and put spring.main.web-application-type: none into the application.properties.
Note: If I remove the #JsonDeserialize from the WeirdEntityWithList definition above, the tests do fail, but they don't fail like your application fails -- there's no exception; the fields of the list's elements just get set to null. I suspect this is related to some difference between Spring Boot's default Jackson configuration and yours. (You may also be using a different Spring Boot version, etc.) I hope whatever's causing the difference doesn't make the code useless to you.
I have json like:
{"avatars": {
"1": "value",
"2":"value",
"900":"value"
}
}
And my model:
class Response{
List<Avatar> avatars;
}
class Avatar{
String id;
String value;
}
How do I properly parse the Json using Jackson
You should use json like this to automaticaly parse:
{"avatars": [
{"id": "1", "value": "someValue1"},
{"id": "2", "value": "someValue2"},
{"id": "300", "value": "someValue300"},
]
}
or write custom parser for Jackson.
Try this:
Using Java JSON library
public class Test {
public static void main(String[] args) {
Response response = new Response();
Serializer.serialize("{\"avatars\": { \"1\": \"value\", \"2\":\"value\", \"900\":\"value\" }}", response);
System.out.println(response.toString());
}
}
class Serializer {
public static void serialize(String j, Response response) {
try {
JSONObject json = new JSONObject(j).getJSONObject("avatars");
Iterator keys = json.keys();
while (keys.hasNext()) {
String id = keys.next().toString();
String value = json.getString(id);
response.addAvatar(id, value);
}
} catch (JSONException ignore) {
}
}
}
/**
* This is a response class
*/
class Response {
List<Avatar> avatars;
public Response() {
/**
* You can use LinkedList, I think it's the best way.
*/
this.avatars = new LinkedList<Avatar>();
}
public void addAvatar(String id, String value) {
this.avatars.add(new Avatar(id, value));
}
public String toString() {
String result = "";
for (Avatar avatar : this.avatars) {
result += (result.length() == 0 ? "" : ", ") + "[" + avatar.getId() + "=" + avatar.getValue() + "]";
}
return result;
}
}
/**
* This is an avatar class
*/
class Avatar {
private String id;
private String value;
public Avatar(String id, String value) {
this.id = id;
this.value = value;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Hope this helps!
You can just use a converter, which avoids the complexity of a full custom deserializer:
#JsonDeserialize(converter = AvatarMapConverter.class)
public List<Avatar> avatars;
The converter needs to declare that it can accept some other type that Jackson can deserialize to, and produce a List<Avatar>. Extending StdConverter will do the plumbing for you:
public class AvatarMapConverter extends StdConverter<Map<String, String>, List<Avatar>> {
#Override
public List<Avatar> convert(Map<String, String> input) {
List<Avatar> output = new ArrayList<>(input.size());
input.forEach((id, value) -> output.add(new Avatar(id, value)));
return output;
}
}
If you need to serialize too, you can write a converter to go the other way and reference that from a #JsonSerialize annotation.
I'm trying to move from default Json API in Android to GSON (or Jackson). But I'm stuck at trying to convert JSONObject to Java object. I've read many tutorials, but found nothing helpful.
I have these two classes (these are just for simplicity):
public class Animal {
#SerializedName("id")
private int id;
//getters and setters
}
public class Dog extends Animal{
#SerializedName("Name")
private String name;
//getters and setters
}
The JSON that I'm trying to map to Dog class is this:
{
"id" : "1",
"Name" : "Fluffy"
}
I'm using this code:
Gson gson = new Gson();
Dog dog = gson.fromJson(jsonObject.toString(), Dog.class);
Name is being mapped ok, but id is not.
How can I achieve this with GSON (or Jackson) libraries, if it's simpler?
Your code should work fine. Try checking what jsonObject.toString() returns. Whether that matches the actual json or not. Example
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
class Animal {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public String toString() {
return "Animal [id=" + id + "]";
}
}
class Dog extends Animal{
#SerializedName("Name")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Dog [name=" + name + ", Id=" + getId() + "]";
}
}
public class GSonParser {
public static void main(String[] args) throws Exception {
String json = "{\"id\" : \"1\", \"Name\" : \"Fluffy\"}";
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(json);
Gson gson = new Gson();
Dog dog = gson.fromJson(jsonObject.toString(), Dog.class);
System.out.println(dog); // Prints "Dog [name=Fluffy, Id=1]"
}
}
For Jackson I use this code
private static ObjectMapper configMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withSetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withCreatorVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY));
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
private Dog readDog(String json) {
Dog ret = null;
if (json != null) {
ObjectMapper mapper = configMapper();
try {
ret = mapper.readValue(json, Dog.class);
} catch (Exception e) {
Log.e("tag", Log.getStackTraceString(e));
return null;
}
}
return ret;
}
Hope it works for you as well.
I'm trying deserializes a JSONArray to List. To do it I'm trying use Gson but I can't understand why doesn't works and all values of JSON are null.
How could I do this ?
JSON
{ "result" : [
{ "Noticia" : {
"created" : "2015-08-20 19:58:49",
"descricao" : "tttttt",
"id" : "19",
"image" : null,
"titulo" : "ddddd",
"usuario" : "FERNANDO PAIVA"
} },
{ "Noticia" : {
"created" : "2015-08-20 19:59:57",
"descricao" : "hhhhhhhh",
"id" : "20",
"image" : "logo.png",
"titulo" : "TITULO DA NOTICIA",
"usuario" : "FERNANDO PAIVA"
} }
] }
Deserializes
List<Noticia> lista = new ArrayList<Noticia>();
Gson gson = new Gson();
JSONArray array = obj.getJSONArray("result");
Type listType = new TypeToken<List<Noticia>>() {}.getType();
lista = gson.fromJson(array.toString(), listType);
//testing - size = 2 but value Titulo is null
Log.i("LISTSIZE->", lista.size() +"");
for(Noticia n:lista){
Log.i("TITULO", n.getTitulo());
}
Class Noticia
public class Noticia implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String titulo;
private String descricao;
private String usuario;
private Date created;
private String image;
There are two problems with your code :
First is that you are using a getJsonArray() to get the array,
which isn't part of Gson library, you need to use
getAsJsonArray() method instead.
Second is that you are using array.toString() which isn't obvious
because for the fromJson method you need a jsonArray as
parameter and not String and that will cause you parse problems, just remove it.
And use the following code to convert your jsonArray to List<Noticia> :
Type type = new TypeToken<List<Noticia>>() {}.getType();
List<Noticia> lista = gson.fromJson(array, type);
And your whole code will be:
Gson gson = new Gson();
JSONArray array = obj.getAsJsonArray("result");
Type type = new TypeToken<List<Noticia>>() {}.getType();
List<Noticia> lista = gson.fromJson(array, type);
//testing - size = 2 but value Titulo is null
Log.i("LISTSIZE->", lista.size() +"");
for(Noticia n:lista){
Log.i("TITULO", n.getTitulo());
}
I think the problem could be something to do with toString() on JSONArray. But are you using obj.getAsJsonArray method?
Try this:
JSONArray arr = obj.getAsJsonArray("result");
Type listType = new TypeToken<List<Noticia>>() {
}.getType();
return new Gson().fromJson(arr , listType);
Noticia.java
public class Noticia {
private String created;
private String descricao;
private String id;
private String image;
private String titulo;
private String usuario;
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getUsuario() {
return usuario;
}
public void setUsuario(String usuario) {
this.usuario = usuario;
}
#Override
public String toString() {
return "Noticia [created=" + created + ", descricao=" + descricao
+ ", id=" + id + ", image=" + image + ", titulo=" + titulo
+ ", usuario=" + usuario + "]";
}
}
Result.java
public class Result {
private Noticia Noticia;
public Noticia getNoticia() {
return Noticia;
}
public void setNoticia(Noticia noticia) {
Noticia = noticia;
}
#Override
public String toString() {
return "Result [Noticia=" + Noticia + "]";
}
}
Item.java
import java.util.List;
public class Item {
private List<Result> result;
public List<Result> getResult() {
return result;
}
public void setResult(List<Result> result) {
this.result = result;
}
#Override
public String toString() {
return "Item [result=" + result + "]";
}
}
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Item;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
public static void main(String[] args) {
String j = "{\"result\":[{\"Noticia\":{\"created\":\"2015-08-20 19:58:49\",\"descricao\":\"tttttt\",\"id\":\"19\",\"image\":null,\"titulo\":\"ddddd\",\"usuario\":\"FERNANDO PAIVA\"}},{\"Noticia\":{\"created\":\"2015-08-20 19:59:57\",\"descricao\":\"hhhhhhhh\",\"id\":\"20\",\"image\":\"logo.png\",\"titulo\":\"TITULO DA NOTICIA\",\"usuario\":\"FERNANDO PAIVA\"}}]}";
Item r = gson.fromJson(j, Item.class);
System.out.println(r);
}
}
Final result
Item [result=[Result [Noticia=Noticia [created=2015-08-20 19:58:49, descricao=tttttt, id=19, image=null, titulo=ddddd, usuario=FERNANDO PAIVA]], Result [Noticia=Noticia [created=2015-08-20 19:59:57, descricao=hhhhhhhh, id=20, image=logo.png, titulo=TITULO DA NOTICIA, usuario=FERNANDO PAIVA]]]]
You parse json, that looks like
{ "result" : [
{
"created" : "2015-08-20 19:58:49",
"descricao" : "tttttt",
"id" : "19",
"image" : null,
"titulo" : "ddddd",
"usuario" : "FERNANDO PAIVA"
},
{
"created" : "2015-08-20 19:59:57",
"descricao" : "hhhhhhhh",
"id" : "20",
"image" : "logo.png",
"titulo" : "TITULO DA NOTICIA",
"usuario" : "FERNANDO PAIVA"
}
] }
You need to make another object Item and parse a list of them.
public class Item{
Noticia noticia;
}
Or you can interate through JSONArray, get field "noticia" from each then parse Noticia object from given JSONObject.
Kotlin Ex :
we getting response in form of JSONArry
call.enqueue(object : Callback<JsonArray> {
override fun onResponse(call: Call<JsonArray>, response: Response<JsonArray>) {
val list = response.body().toString()
val gson = Gson()
val obj: CitiesList? = gson.fromJson(list, CitiesList::class.java)
cityLiveData.value = obj!!
}
override fun onFailure(call: Call<JsonArray>, t: Throwable) {
}
})
Here CitiesList CitiesList::class.java is the ArrayList of Cities object
class CitiesList : ArrayList<CitiesListItem>()
Before using GSON add dependancey in Gradle
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
}
Given I have the following json:
{
"Company": {
"name": "cookieltd",
"type": "food",
"franchise_location": [
{
"location_type": "town",
"address_1": "5street"
},
{
"location_type": "village",
"address_1": "2road"
}
]
}
}
How can it be binded to the following object classes using Jackson?:
1) Company class
public class Company
{
String name, type;
List<Location> franchise_location = new ArrayList<Location>();
[getters and setters]
}
2) Location class
public class Location
{
String location_type, address_1;
[getters and setters]
}
I have done:
String content = [json above];
ObjectReader reader = mapper.reader(Company.class).withRootName("Company"); //read after the root name
Company company = reader.readValue(content);
but I am getting:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "franchise_location"
As far as I can tell, you are simply missing an appropriately named getter for the field franchise_location. It should be
public List<Location> getFranchise_location() {
return franchise_location;
}
(and the setter)
public void setFranchise_location(List<Location> franchise_location) {
this.franchise_location = franchise_location;
}
Alternatively, you can annotate your current getter or field with
#JsonProperty("franchise_location")
private List<Location> franchiseLocation = ...;
which helps to map JSON element names that don't really work with Java field name conventions.
The following works for me
public static void main(String[] args) throws Exception {
String json = "{ \"Company\": { \"name\": \"cookieltd\", \"type\": \"food\", \"franchise_location\": [ { \"location_type\": \"town\", \"address_1\": \"5street\" }, { \"location_type\": \"village\", \"address_1\": \"2road\" } ] } }";
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(Company.class).withRootName(
"Company"); // read after the root name
Company company = reader.readValue(json);
System.out.println(company.getFranchise_location().get(0).getAddress_1());
}
public static class Company {
private String name;
private String type;
private List<Location> franchise_location = new ArrayList<Location>();
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 List<Location> getFranchise_location() {
return franchise_location;
}
public void setFranchise_location(List<Location> franchise_location) {
this.franchise_location = franchise_location;
}
}
public static class Location {
private String location_type;
private String address_1;
public String getLocation_type() {
return location_type;
}
public void setLocation_type(String location_type) {
this.location_type = location_type;
}
public String getAddress_1() {
return address_1;
}
public void setAddress_1(String address_1) {
this.address_1 = address_1;
}
}
and prints
5street
my solution for JSON is always GSON, you can do some research on that, as long as you have the correct structure of class according to the JSON, it can automatically transfer from JSON to object:
Company company = gson.fromJson(json, Company.class);
GSON is so smart to do the convertion thing!
enjoy GSON !