If I can get either of the following JSON bodies as responses:
{
"error" : "some error",
"code": 123
}
or
[
{
"name" : "name",
"value" : "value"
},
{
"name" : "name",
"value" : "value"
}
]
Is there a way to map either of these response to below Java POJO using annotations ?
public class Response {
String error;
int code;
List<NameValuePair> nameValuePairs;
}
Out of the box, only the error response will deserialise. The issue is they are fundamentally different types - an object vs an array.
You can make it work with a custom module for jackson, as described here
One possible response is a JSON Object and other is a JSON Array. In that case it is not possible to create one POJO class to handle it. Also, these two payloads means to different things: one is SUCCESS and other is ERROR payloads. In that case I would use Facade design pattern to create extra layer and hide this complex logic there. It could look like below:
class ResponseDeserialiserFacade {
private final ObjectMapper mapper = new ObjectMapper();
public List<NameValuePair> deserialisePairs(String json) {
try {
return mapper.readValue(json, new TypeReference<List<NameValuePair>>() {
});
} catch (IOException e) {
try {
Error error = mapper.readValue(json, Error.class);
throw new RequestApiException(error, e);
} catch (IOException e1) {
throw new RequestApiException(Error.from("Can not parse: " + json), e1);
}
}
}
}
As you noticed I introduced new exception:
class RequestApiException extends RuntimeException {
private final Error error;
RequestApiException(Error error, Exception base) {
super(base);
this.error = error;
}
public Error getError() {
return error;
}
}
with Error class:
class Error {
private String error;
private String code;
public static Error from(String message) {
Error e = new Error();
e.error = message;
return e;
}
// getters, setters, toString
}
Now we can test it for SUCCESS and ERROR payloads:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
public class JsonApp {
public static void main(String[] args) {
String success = "[\n" +
" {\n" +
" \"name\" : \"name\",\n" +
" \"value\" : \"value\"\n" +
" },\n" +
" {\n" +
" \"name\" : \"name\",\n" +
" \"value\" : \"value\"\n" +
" }\n" +
"]\n";
tryToParse(success);
String error = "{\n" +
" \"error\" : \"some error\",\n" +
" \"code\": 123\n" +
"}";
tryToParse(error);
}
private static void tryToParse(String json) {
ResponseDeserialiserFacade deserialiser = new ResponseDeserialiserFacade();
try {
List<NameValuePair> pairs = deserialiser.deserialisePairs(json);
System.out.println("SUCCESS: " + pairs);
} catch (RequestApiException e) {
System.out.println("ERROR: " + e.getError());
}
}
}
class NameValuePair {
private String name;
private String value;
// getters, setters, toString
}
Above code prints:
SUCCESS: [NameValuePair{name='name', value='value'}, NameValuePair{name='name', value='value'}]
ERROR: Error{error='some error', code='123'}
As you can see, we treated error message like as exception.
Related
Hey I have also problem here is my Json
[
{
"aimid": "12345"
},
{
"aimid": "333674"
},
{
"aimid": [
"4568999",
"6789345"
]
}]
and This is my Pojo class:-
#JsonProperty("aimid")
private String aimid;
public String getAimid() {
return aimid;
}
public void setAimid(String aimid) {
this.aimid = aimid;
}
I want to store aimid in pojo . When i am writing like above in my application i am getting error.
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token.
From my understanding i am getting error because of Array element so anyone can suggest me how i can capture both thing if it is coming as String or It is coming as a Array String
The challenge is that in some cases "aimid" is a string value but in another case it is an array.
If you have control over the structure of the JSON then update the structure so that each element of the root array has ONE of the following structures:
String
{
"aimid": "333674"
}
OR array
{
"aimid": [
"4568999",
"6789345"
]
}
If you do not have control of the structure of the data you will need to parse it yourself and process it into your POJO.
Please see these 3 code examples that should illustrate how you can go about this approaches. :
public class MyPojo {
private List<String> aimid;
#JsonProperty("aimid")
public List<String> getAimid() {
return aimid;
}
#JsonProperty("aimid_array")
public void setAimid(final List<String> aimid) {
this.aimid = aimid;
}
#JsonProperty("aimid")
public void setAimid(final String aimid) {
this.aimid = Arrays.asList(aimid);
}
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.*;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;
public class UnitTest {
private static final Logger LOGGER = Logger.getLogger(UnitTest.class.getName());
public UnitTest() {
}
#Test
public void testOneAimId() throws IOException {
final String json = "[\n"
+ "{\n"
+ " \"aimid\": \"12345\"\n"
+ "},\n"
+ "{\n"
+ " \"aimid\": \"333674\"\n"
+ "}]";
final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
});
log(Level.SEVERE, LOGGER, "testOneAimId", result);
}
#Test
public void testListAimIds() throws IOException {
final String json = "[\n"
+ "{\n"
+ " \"aimid_array\": [\n" // HERE WE HAVE CHANGED THE JSON PROP NAME
+ " \"4568999\",\n"
+ " \"6789345\"\n"
+ " ]\n"
+ "}]";
final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
});
log(Level.SEVERE, LOGGER, "testListAimIds", result);
}
#Test
public void testMixed() throws IOException {
final String json = "[\n"
+ "{\n"
+ " \"aimid\": \"12345\"\n"
+ "},\n"
+ "{\n"
+ " \"aimid\": \"333674\"\n"
+ "},\n"
+ "{\n"
+ " \"aimid_array\": [\n" // HERE WE HAVE CHANGED THE JSON PROP NAME
+ " \"4568999\",\n"
+ " \"6789345\"\n"
+ " ]\n"
+ "}]";
final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
});
log(Level.SEVERE, LOGGER, "testMixed", result);
}
#Test
public void testMixed2() throws IOException {
final String json = "[\n"
+ "{\n"
+ " \"aimid\": \"12345\"\n"
+ "},\n"
+ "{\n"
+ " \"aimid\": \"333674\"\n"
+ "},\n"
+ "{\n"
+ " \"aimid\": [\n"
+ " \"4568999\",\n"
+ " \"6789345\"\n"
+ " ]\n"
+ "}]";
final JsonNode result = new ObjectMapper().readValue(json, JsonNode.class);
final ArrayList<String> arrayList = new ArrayList<>();
result.forEach((final JsonNode jsonNode) -> {
if (jsonNode.getNodeType() != JsonNodeType.OBJECT)
throw new IllegalArgumentException(jsonNode.toString());
final ObjectNode obj = (ObjectNode) jsonNode;
obj.forEach(o -> {
switch (o.getNodeType()) {
case ARRAY:
final ArrayNode array = (ArrayNode) o;
array.forEach(t -> arrayList.add(t.asText()));
break;
case STRING:
arrayList.add(o.asText());
break;
default:
throw new IllegalArgumentException(o.toString());
}
});
});
final MyPojo myPojo = new MyPojo();
myPojo.setAimid(arrayList);
log(Level.SEVERE, LOGGER, "myPojo", myPojo);
}
private void log(final Level level, final Logger logger, final String title, final Object obj) {
try {
if (title != null)
logger.log(level, title);
final ObjectWriter writer = new ObjectMapper().writerWithDefaultPrettyPrinter();
logger.log(level, obj == null ? "null" : writer.writeValueAsString(obj));
} catch (final JsonProcessingException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
}
}
}
I wan to return a list of errors using this Response object:
public class StringResponseDTO {
private String response;
public StringResponseDTO(String response) {
super();
this.response = response;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
}
I use this code to generate errors:
List<FieldError> errors = result.getFieldErrors();
for (FieldError error : errors ) {
System.out.println ("Validation error in field: " + error.getObjectName()
+ "! Validation error message: " + error.getDefaultMessage()
+ "! Rejected value:" + error.getRejectedValue());
return ResponseEntity.ok(new StringResponseDTO(error.getField() + " " + error.getDefaultMessage()));
}
I want to return a list like this:
response: {
errors: [
field_name: message,
second_name: second_message
]
}
Do you know how I can modify the code? Probably I need add constructor?
response: {
errors: [
field_name: message,
second_name: second_message
]
}
You need to use the following classes to model the above json:
#JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
#JsonTypeName("response")
class StringResponseDTO {
private List<String> errors;
public StringResponseDTO(final List<String> errors) {
this.errors = errors;
}
public List<String> getErrors() {
return errors;
}
public void setErrors(final List<String> errors) {
this.errors = errors;
}
}
You can construct the response as:
List<String> errorsList = new ArrayList<>();
List<FieldError> errors = result.getFieldErrors();
for (FieldError error : errors ) {
System.out.println ("Validation error in field: " + error.getObjectName()
+ "! Validation error message: " + error.getDefaultMessage()
+ "! Rejected value:" + error.getRejectedValue());
errorsList.add(error.getField() + " " + error.getDefaultMessage());
}
return ResponseEntity.badRequest().body(new StringResponseDTO(errorsList));
I have this JSON documents
1:
{
"type": "first_type",
"configs": [
{
"itemLevel": 1,
"power": {
"firstTypeParam": "xxxx"
}
},
{
"itemLevel": 2,
"power": {
"firstTypeParam": "yyy"
}
}
]
}
2:
{
"type": "second_type",
"configs": [
{
"itemLevel": 11,
"power": {
"anotherParam": true
}
},
{
"itemLevel": 12,
"power": {
"anotherParam": false
}
]
}
A couple of java classes
public class Dto {
String type;
Collection<Config>;
}
public class Config {
int itemLevel;
Collection<Power> powers;
}
public interface Power {}
public class FirstPower implements Power {
String firstTypeParam;
}
public class SecondPower implements Power {
boolean anotherParam;
}
I tried to implement custom jackson deserializer #JsonDeserialize(using = MyStdDeserializer.class" on top of Power interface but couldn't find out how to access to neighbor node of the parent with type flag.
Do you know how to fix class hierarchy and/or use jackson features/annotations to deserialize JSON with "first_type" type onto FirstPower class and "second_type" onto SecondPower?
I'm using jackson 2.9.7
It is possible to change class hierarchy and JSON format little bit and also I have ability to use annotation-based deserialization.
Since the type information is stored in Dto class, the custom JsonDeserializer should be implemented for 'Dto' class instead of 'Power' interface in order to access the type information. The crucial part of the implementation of the custom JsonDeserializer in below code is the line
config.powers.add(parser.readValueAs(getPowerClass(dto.type)));
where getPowerClass method determine the class(FirstPower or SecondPower) required by using the type of dto. Once the class is known, we can deserialize the power object simply by calling readValueAs method. Following classes(should be put in same package) demonstrate how to implement the custom JsonDeserializer.
Main class
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PolymorphicDeserialize {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
Dto type1 = mapper.readValue(getType1Json(), Dto.class);
Dto type2 = mapper.readValue(getType2Json(), Dto.class);
printDto(type1);
printDto(type2);
}
private static void printDto(Dto dto) {
System.out.println("type :" + dto.type);
for (Config config : dto.configs) {
System.out.println("itemLevel:" + config.itemLevel);
System.out.println("powers:" + config.powers);
}
}
private static String getType1Json() {
return " { "
+ " \"type\": \"first_type\", "
+ " \"configs\": [ "
+ " { "
+ " \"itemLevel\": 1, "
+ " \"power\": { "
+ " \"firstTypeParam\": \"xxxx\" "
+ " } "
+ " }, "
+ " { "
+ " \"itemLevel\": 2, "
+ " \"power\": { "
+ " \"firstTypeParam\": \"yyy\" "
+ " } "
+ " } "
+ " ] "
+ " } ";
}
private static String getType2Json() {
return " { "
+ " \"type\": \"second_type\", "
+ " \"configs\": [ "
+ " { "
+ " \"itemLevel\": 11, "
+ " \"power\": { "
+ " \"anotherParam\": true "
+ " } "
+ " }, "
+ " { "
+ " \"itemLevel\": 12, "
+ " \"power\": { "
+ " \"anotherParam\": false "
+ " } "
+ " } "
+ " ] "
+ " } ";
}
}
Dto class
import java.util.Collection;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
#JsonDeserialize(using = DtoDeserializer.class)
public class Dto {
String type;
Collection<Config> configs;
}
DtoDeserializer class
import java.io.IOException;
import java.util.ArrayList;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class DtoDeserializer extends JsonDeserializer<Dto> {
#Override
public Dto deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Dto dto = new Dto();
dto.configs = new ArrayList<Config>();
while (parser.nextToken() == JsonToken.FIELD_NAME) {
deserializeType(parser, dto);
deserializeConfigs(parser, dto);
}
return dto;
}
private void deserializeType(JsonParser parser, Dto dto) throws IOException, JsonProcessingException {
if (!"type".equals(parser.getCurrentName())) {
return;
}
parser.nextToken();
dto.type = parser.getValueAsString();
}
private void deserializeConfigs(JsonParser parser, Dto dto) throws IOException, JsonProcessingException {
if (!"configs".equals(parser.getCurrentName())) {
return;
}
if (parser.nextToken() != JsonToken.START_ARRAY) {
return;
}
while (parser.nextValue() != null) {
if (parser.getCurrentToken() != JsonToken.START_OBJECT) {
continue;
}
Config config = new Config();
config.powers = new ArrayList<Power>();
while (parser.nextToken() != JsonToken.END_OBJECT) {
if ("itemLevel".equals(parser.getCurrentName())) {
parser.nextToken();
config.itemLevel = parser.getValueAsInt();
} else if ("power".equals(parser.getCurrentName())) {
parser.nextToken();
config.powers.add(parser.readValueAs(getPowerClass(dto.type)));
}
}
dto.configs.add(config);
}
}
private Class<? extends Power> getPowerClass(String type) {
if ("first_type".equals(type)) {
return FirstPower.class;
} else if ("second_type".equals(type)) {
return SecondPower.class;
}
throw new IllegalArgumentException("Not known type" + type);
}
}
Power interface
public interface Power {}
FirstPower class
public class FirstPower implements Power {
String firstTypeParam;
String getFirstTypeParam() {
return firstTypeParam;
}
void setFirstTypeParam(String firstTypeParam) {
this.firstTypeParam = firstTypeParam;
}
#Override
public String toString() {
return "firstTypeParam:" + firstTypeParam;
}
}
SecondPower class
public class SecondPower implements Power {
boolean anotherParam;
boolean isAnotherParam() {
return anotherParam;
}
void setAnotherParam(boolean anotherParam) {
this.anotherParam = anotherParam;
}
#Override
public String toString() {
return "anotherParam:" + String.valueOf(anotherParam);
}
}
I want to know the best way to iterate this ArrayList, this ArrayList comes from a Response from an API, this is the ArrayList:
The problem is that i dont know how to get the "id" and the "value" from the loop,
i know the arraylist size but i dont have any idea how to print the "Keys" and "Values" from this Array
for(int i=1; i <= contacts.size(); i++) {
//Example System.out.print(contacts[i]->id);
//Example System.out.print(contacts[i]->contact_name) ;
//Example System.out.print(contacts[i]->numbers);
//Example System.out.print(contacts[i]->emails);
//I want to print id and value
//
}
In onResponse i call this fucntion for example:
ServerResponse resp = response.body();
functionExample((ArrayList) resp.getResponse());
The functionExample have an ArrayList as parameter.
This is my result from my resp.getResponse():
This is my json from the API:
{
"result": "success",
"message": "Lista de Contactos",
"response": [
{
"id": 1,
"contact_name": "EDIFICADORA JUANA",
"numbers": "{24602254,55655545}",
"emails": "{oipoa#gmaio.com,rst008#guan.com}"
},
{
"id": 2,
"contact_name": "LA MEJOR",
"numbers": "{25445877,25845877}",
"emails": "{AMEJOR#GMAIL.COM}"
}
]
}
I appreciate any help.
public void FunctionExample(ArrayList contacts) {
for(int i=0; i < contacts.size(); i++) {
LinkedTreeMap<String, Object> map = (LinkedTreeMap<String, Object>) contacts.get(i);
map.containsKey("id");
String id = (String) map.get("id");
map.containsKey("contact_name");
String contact_name = (String) map.get("contact_name");
map.containsKey("numbers");
String numbers = (String) map.get("numbers");
numbers.replace("{","").replace("}","");
map.containsKey("emails");
String emails = (String) map.get("emails");
emails.replace("{","").replace("}","");
Snackbar.make(getView(), id, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), contact_name, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), numbers, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), emails, Snackbar.LENGTH_LONG).show();
}
}
Try this..It will give arrayList of id's
JSONObject object=new JSONObject(response);
JSONArray array= null;
try {
array = object.getJSONArray("response");
} catch (JSONException e) {
e.printStackTrace();
}
ArrayList<String> idArray=new ArrayList<>();
for(int i=0;i< array.length();i++)
{
idArray.add(getJSONObject(i).getString("id"));
}
Try this way if you are using ArrayList<TreeMap<String, String>> contacts;
for(TreeMap<String,String> contact : contacts){
String id = contact.getValue("id");
}
I would strongly encourage you to use e.g. Jackson to map your JSON response to a proper object. Consider following example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JacksonTest {
private static final String JSON = "{\n" +
"\"result\": \"success\",\n" +
"\"message\": \"Lista de Contactos\",\n" +
"\"response\": [\n" +
" {\n" +
" \"id\": 1,\n" +
" \"contact_name\": \"EDIFICADORA JUANA\",\n" +
" \"numbers\": \"{24602254,55655545}\",\n" +
" \"emails\": \"{oipoa#gmaio.com,rst008#guan.com}\"\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"contact_name\": \"LA MEJOR\",\n" +
" \"numbers\": \"{25445877,25845877}\",\n" +
" \"emails\": \"{AMEJOR#GMAIL.COM}\"\n" +
" }\n" +
" ]\n" +
"}";
#Test
public void testParsingJSONStringWithObjectMapper() throws IOException {
//given:
final ObjectMapper objectMapper = new ObjectMapper();
//when:
final Response response = objectMapper.readValue(JSON, Response.class);
//then:
assert response.getMessage().equals("Lista de Contactos");
//and:
assert response.getResult().equals("success");
//and:
assert response.getResponse().get(0).getId().equals(1);
//and:
assert response.getResponse().get(0).getContactName().equals("EDIFICADORA JUANA");
//and:
assert response.getResponse().get(0).getEmails().equals(Arrays.asList("oipoa#gmaio.com", "rst008#guan.com"));
//and:
assert response.getResponse().get(0).getNumbers().equals(Arrays.asList(24602254, 55655545));
}
static class Response {
private String result;
private String message;
private List<Data> response = new ArrayList<>();
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Data> getResponse() {
return response;
}
public void setResponse(List<Data> response) {
this.response = response;
}
}
static class Data {
private String id;
#JsonProperty("contact_name")
private String contactName;
private String numbers;
private String emails;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public List<Integer> getNumbers() {
return Stream.of(numbers.replaceAll("\\{", "")
.replaceAll("}", "")
.split(","))
.map(Integer::valueOf)
.collect(Collectors.toList());
}
public void setNumbers(String numbers) {
this.numbers = numbers;
}
public List<String> getEmails() {
return Arrays.asList(emails.replaceAll("\\{", "")
.replaceAll("}", "")
.split(","));
}
public void setEmails(String emails) {
this.emails = emails;
}
}
}
In this example I used same JSON response you receive and jackson-core library (http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.8.9) for mapping String to a POJOs (instead of String you can use InputStream, byte[] etc.). There are two POJOs: Response and Data. Response aggregates a list of Data objects. Additionally, Data's getEmails() and getNumbers() methods parse your input String to a list of expected objects. For example if you call setNumbers("{24602254,55655545}") then getNumbers() will return a list of Integers (you can use any numeric type instead) like [24602254, 55655545].
Other suggestions are also valid, e.g. iterating over collection of TreeMaps or JSONObjects. In this example we limit our focus to deal with Java objects with specific types instead of dealing with primitives like Object class for example.
The final solution also depends on your runtime environment. In this case you will have to add jackson-core dependency - it makes more sense if your project already uses Jackson for other reasons.
If you are using Set< Map< String, String>> set;
set.stream().forEach(map -> {
System.out.print("Id:" + map.get("id") + "ContactName:" + map.get("contact_name"));
});
Try this loop to extract every value from ArrayList of yours
List<LinkedTreeMap> list = new ArrayList<LinkedTreeMap>(); //assign result from API to list
for(LinkedTreeMap<String,String> contact : list){
for(String id : contact.keySet()){
if(id.equalsIgnoreCase("id")){
System.out.println("ID: "+ contact.get(id));
}else if(id.equalsIgnoreCase("contact_name")){
System.out.println("Contact Name: "+ contact.get(id));
}else{ //if it is list of numbers or e-mails
String result = contact.get(id);
result = result.replaceAll("{|}", ""); //removing { }
String[] array = result.split(",");
System.out.println(id+": "); // this will be either numbers or e-mails
//now iterating to get each value
for(String s : array){
System.out.println(s);
}
}
}
}
I'm having a little trouble working out an appropriate java object structure for the following JSON data:
"pages": {
"181382": {
"pageid": 181382,
"ns": 0,
"title": "Anonymity"
},
"7181837": {
"pageid": 7181837,
"ns": 0,
"title": "Anonymous"
}
}
The identifiers "181382" and "7181837" change depending on the data returned so these cannot be used as a member on an object. I tried to approach it using a Map<String, Object> approach but got a little stuck.
Edit:
This is what I've tried
public class PageData {
int pageid;
String ns;
String title;
public int getPageid() {
return pageid;
}
public String getNs() {
return ns;
}
public String getTitle() {
return title;
}
}
Map<String, PageData> pages = results.getPages().getData();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
Just create some wrapper for your Object. Here is working example:
Wrapper
public class Wrapper {
Map<String, PageData> pages = null;
public Map<String, PageData> getPages() {
return pages;
}
}
Launcher
public class Launcher {
public static void main(String[] args) {
String str = "{\"pages\": {\r\n" +
" \"181382\": {\r\n" +
" \"pageid\": 181382,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymity\"\r\n" +
" },\r\n" +
" \"7181837\": {\r\n" +
" \"pageid\": 7181837,\r\n" +
" \"ns\": 0,\r\n" +
" \"title\": \"Anonymous\"\r\n" +
" }\r\n" +
" }" +
"}";
Gson gson = new Gson();
Wrapper results = gson.fromJson(str, Wrapper.class);
Map<String, PageData> pages = results.getPages();
for (PageData data : pages.values()) {
System.out.println(data.getTitle());
}
}
}
PageData
public class PageData{/* the same */}
Output:
Anonymity
Anonymous