We are deserializing top-level RefundAttrs attribute while fetching transaction object from DB. I cannot change this part.
How can I deserialize RefundAttrs.metadata field into RefundEventData? I am getting com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 52 path $.reason
class RefundAttrs {
private String instrumentTxnId;
private Object metadata;
public String instrumentTxnId() {
return instrumentTxnId;
}
public Object metadata() {
return metadata;
}
#Override
public String toString() {
return String.format("{ instrumentTxnId=%s, metadata=%s }", this.instrumentTxnId, this.metadata);
}
}
class RefundEventData {
private String orderId;
private Double refundAmount;
private String reason;
#Override
public String toString() {
return String.format("{ orderId=%s, refundAmount=%s, reason=%s }", this.orderId, this.refundAmount, this.reason);
}
}
public static void main(String[] args) throws IOException {
Gson gson = new Gson();
String json = "{\n" +
" \"instrumentTxnId\": \"refund-101\",\n" +
" \"metadata\": {\n" +
" \"orderId\": \"011-acf\",\n" +
" \"refundAmount\": 100.0,\n" +
" \"reason\": \"User left\"\n" +
" }\n" +
"}";
RefundAttrs attrs = gson.fromJson(json, RefundAttrs.class);
System.out.println(attrs.metadata());
// {orderId=011-acf, refundAmount=100.0, reason=User left}
RefundEventData eventData = gson.fromJson(attrs.metadata().toString(), RefundEventData.class);
}
attrs.metadata().toString() generates invalid JSON text.
Convert the metadata to JSON:
RefundEventData eventData = gson.fromJson(gson.toJson(attrs.metadata()), RefundEventData.class);
Related
I have happily been using Google Gson to parse extract some JSON metadata of the form
{
"lowlevel": {
"average_loudness": 0.570070445538
},
"rhythm": {
"beats_count": 502,
"bpm": 128.347702026
},
"tonal": {
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715
}
}
Using this
public class AcousticBrainzLowlevelWrapper
{
private AcousticBrainzLowLevelRhythm rhythm;
private AcousticBrainzLowLevelTonal tonal;
public AcousticBrainzLowLevelRhythm getRhythm()
{
return rhythm;
}
public void setRhythm(AcousticBrainzLowLevelRhythm rhythm)
{
this.rhythm = rhythm;
}
public AcousticBrainzLowLevelTonal getTonal()
{
return tonal;
}
public void setTonal(AcousticBrainzLowLevelTonal tonal)
{
this.tonal = tonal;
}
}
and
AcousticBrainzLowlevelWrapper low = gson.fromJson(result, AcousticBrainzLowlevelWrapper.class) ;
(Full JSON can be seen here)
but now the API has been extended to allow multiple lookups such as this url
which now returns
{
"96685213-a25c-4678-9a13-abd9ec81cf35": {
"0": {
"lowlevel": {
"average_loudness": 0.570070445538
},
"rhythm": {
"beats_count": 502,
"bpm": 128.347702026
},
"tonal": {
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715
}
}
.....
"78787888-a25c-4678-9a13-abd9ec81cf35": {
"0": {
"lowlevel": {
......
..
The difference being that the json doesn't define what "96685213-a25c-4678-9a13-abd9ec81cf35" and "78787888-a25c-4678-9a13-abd9ec81cf35" are, or what "0" is.
So I know what they represent (MusicBrainzRecording and offset) but I cannot create a class like AcousticBrainzLowlevelWrapper to represent this, so how do I parse this new api.
Update
I tried creating
public class AcousticBrainzLowLevelList
{
private Map<String, AcousticBrainzLowlevelWrapper> data = new HashMap<>();
public Map<String, AcousticBrainzLowlevelWrapper> getData()
{
return data;
}
public void setData(Map<String, AcousticBrainzLowlevelWrapper> data)
{
this.data = data;
}
}
and then calling
AcousticBrainzLowLevelList lowMap = gson.fromJson(result, AcousticBrainzLowLevelList.class) ;
but nothing get added to the map. Unsuprisingly because data I dont' see how can i give a name since there is no consistent name at the top level.
It seems to me that your input JSON could be parsed to produce a Java class of type Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> :
Type type = new TypeToken<Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>>(){}.getType();
Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> result = gson.fromJson(json, type);
As I wrote it, I might as well post it:
Similar to Maurice's answer
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;
public class Main {
private final static String jsonSingle =
"{ \"attribute1\": \"value1\", \"attribute2\": \"value2\" }";
private final static String jsonMultiple =
"{\n" +
" \"96685213-a25c-4678-9a13-abd9ec81cf35\": {\n" +
" \"0\": { \"attribute1\": \"value1\", \"attribute2\": \"value2\" }\n" +
" },\n" +
" \"78787888-a25c-4678-9a13-abd9ec81cf35\": {\n" +
" \"0\": { \"attribute1\": \"value3\", \"attribute2\": \"value4\" }\n" +
"}}";
public static void main(String[] args) {
MyBean bean = new Gson().fromJson(jsonSingle, MyBean.class);
System.out.println(bean);
Type type = new TypeToken<Map<String, Map<String, MyBean>>>(){}.getType();
Map<String, String> myMap = new Gson().fromJson(jsonMultiple, type);
System.out.println(myMap);
}
}
MyBean class:
class MyBean {
String attribute1;
String attribute2;
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String attribute1) {
this.attribute1 = attribute1;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String attribute2) {
this.attribute2 = attribute2;
}
#Override
public String toString() {
return "MyBean: <attribute1: " + attribute1 + " | " + "attribute2: " + attribute2 + ">";
}
}
Outputs:
MyBean: <attribute1: value1 | attribute2: value2>
and
{96685213-a25c-4678-9a13-abd9ec81cf35={0=MyBean: <attribute1: value1 | attribute2: value2>}, 78787888-a25c-4678-9a13-abd9ec81cf35={0=MyBean: <attribute1: value3 | attribute2: value4>}}
I have these JSON String:
{
"Results": {
"output1": {
"type": "table",
"value": {
"ColumnNames": ["userId", "documentId", "Scored Labels", "Scored Probabilities"],
"ColumnTypes": ["String", "String", "Boolean", "Double"],
"Values": [["100213199594809000000", "1Ktol-SWvAh8pnHG2O7HdPrfbEVZWX3Vf2YIPYXA_8gI", "False", "0.375048756599426"], ["103097844766994000000", "1jYsTPJH8gaIiATix9x34Ekcj31ifJMkPNb0RmxnuGxs", "True", "0.753859758377075"]]
}
}
}
}
And I want to have only the ColumnNames and the Values. I have tried it with something like this:
Map<String,Object> map = mapper.readValue(filename, Map.class);
String CN = (String) map.get("ColumnNames");
But then I get the following error:
Exception in thread "main" org.codehaus.jackson.JsonParseException: Unexpected character ('A' (code 65)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: java.io.StringReader#64232b15; line: 1, column: 2]`
I've worked only few times with JSON. Can anybody help me here?
The best case for me would be something like this, which I've done in another case:
String uId = (String) attr.get("userId");
Is it possible?
So now I've done this:
I try it like this:
public class ClientPOJO {
private String userId;
private String documentId;
public String getuserId() {
return userId;
}
public void setuserId(String userId) {
this.userId = userId;
}
public String getdocumentId() {
return documentId;
}
public void setdocumentId(String documentId) {
this.documentId = documentId;
}
}
and then:
ObjectMapper mapper = new ObjectMapper();
ClientPOJO clientes= mapper.readValue(filename, ClientPOJO.class);
String uid = clientes.getuserId();
But now when I make a Prtinout I'll get the same error like before:
Exception in thread "main" org.codehaus.jackson.JsonParseException: Unexpected character ('A' (code 65)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: java.io.StringReader#7a6eb29d; line: 1, column: 2]
Java- Convert JSON string into string / integer / Object
String jsonString = "{"username":"Gajender"}";
org.json.JSONObject jsonObj =new JSONObject(jsonString);
String name = (String) jsonObj.get("username").toString();
Below is an example to illustrate a generic approach to solve your problem ( based on Jackson library). You may like to enhance the solution to meet your all requirements.
Comments inlined.
package com.stackoverflow;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
// Junit class
public class TableDeserExample {
// sample input
String inputJson = "{\n" +
" \"Results\": {\n" +
" \"output1\": {\n" +
" \"type\": \"table\",\n" +
" \"value\": {\n" +
" \"ColumnNames\": [\"userId\", \"documentId\", \"Scored Labels\", \"Scored Probabilities\"],\n" +
" \"ColumnTypes\": [\"String\", \"String\", \"Boolean\", \"Double\"],\n" +
" \"Values\": [[\"100213199594809000000\", \"1Ktol-SWvAh8pnHG2O7HdPrfbEVZWX3Vf2YIPYXA_8gI\", \"False\", \"0.375048756599426\"], [\"103097844766994000000\", \"1jYsTPJH8gaIiATix9x34Ekcj31ifJMkPNb0RmxnuGxs\", \"True\", \"0.753859758377075\"]]\n"
+
" }\n" +
" }\n" +
" }\n" +
"}";
// POJO to map the Json structure. You may want to make it generalize based
// on field "type"
// (https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization)
public static class Result {
private String type;
private TableResult value;
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public void setValue(TableResult value) {
this.value = value;
}
public TableResult getValue() {
return this.value;
}
}
// Pojo for table result
public static class TableResult {
private List<String> columnNames;
private List<String> columnTypes;
private List<Object[]> values;
#JsonProperty("ColumnNames")
public List<String> getColumnNames() {
return this.columnNames;
}
public void setColumnNames(List<String> columnNames) {
this.columnNames = columnNames;
}
#JsonProperty("ColumnTypes")
public List<String> getColumnTypes() {
return this.columnTypes;
}
public void setColumnTypes(List<String> columnTypes) {
this.columnTypes = columnTypes;
}
#JsonProperty("Values")
public List<Object[]> getValues() {
return this.values;
}
public void setValues(List<Object[]> values) {
this.values = values;
}
}
// Top level Json POJO
public static class ResultContainer {
private Map<String, Result> results;
#JsonProperty("Results")
public Map<String, Result> getResults() {
return this.results;
}
public void setResults(Map<String, Result> results) {
this.results = results;
}
}
// A contract to map the result "values" to the expected object
public static interface ResultMapper<T> {
T map(TableResult map, Object[] row);
}
// Basic implementation for mapping user object from json "values[i]" array
public static class UserTableResultMapper implements ResultMapper<User> {
#Override
public User map(TableResult result, Object[] row) {
User user = new User();
// Here use any mapper logic based on column name
// Retrieved from result object.
// Below are for illustration only
user.setId(String.valueOf(row[0]));
user.setDocumentId(String.valueOf(row[1]));
return user;
}
}
// A result reader class
public static class ResultReader<T> implements Iterable<T> {
private TableResult result;
private ResultMapper<T> mapper;
public ResultReader(TableResult result, ResultMapper<T> mapper) {
this.result = result;
this.mapper = mapper;
}
#Override
public Iterator<T> iterator() {
final Iterator<Object[]> itr = result.getValues().iterator();
return new Iterator<T>() {
#Override
public void remove() {
throw new UnsupportedOperationException();
}
#Override
public T next() {
Object[] values = itr.next();
return mapper.map(result, values);
}
#Override
public boolean hasNext() {
return itr.hasNext();
}
};
};
}
public static class User {
private String id;
private String documentId;
// and others
public String getId() {
return this.id;
}
public void setDocumentId(String documentId) {
this.documentId = documentId;
}
public void setId(String id) {
this.id = id;
}
public String getDocumentId() {
return this.documentId;
}
}
#Test
public void simpleTest() throws Exception {
ObjectMapper mapper = new ObjectMapper();
ResultContainer file = mapper.readValue(inputJson, ResultContainer.class);
Result result = file.getResults().get("output1");
ResultReader<User> userResultReader = new ResultReader<>(result.getValue(), new UserTableResultMapper());
for (User user : userResultReader) {
System.out.println(user.getId() + " : " + user.getDocumentId());
}
}
}
If you know exactly the structure of your json (like the json you have post) then you can using Gson to get your object like this:
JsonParser parser = new JsonParser();
JsonObject json = (JsonObject) parser.parse("your_json_string_here");
String column = json.get("Results").getAsJsonObject().get("output1").getAsJsonObject().get("value").getAsJsonObject().get("ColumnNames").getAsJsonArray().toString();
String value = json.get("Results").getAsJsonObject().get("output1").getAsJsonObject().get("value").getAsJsonObject().get("Values").getAsJsonArray().toString();
System.out.println(column);
System.out.println(value);
If you need some things more generic then you can parse your json string to a HashMap<String, Object> then using recursion to read the HashMap and get the value you want.
Example (in my code, the type of Map will corresponding to a Json Object, type of List will corresponding to the Array in Json string):
Type type = new TypeToken<HashMap<String, Object>>() {}.getType();
Gson gson = new Gson();
HashMap<String, Object> map = gson.fromJson("your_json_string_here", type);
for (String key : map.keySet()) {
Object obj = map.get(key);
if (obj instanceof List) {
for (Object o : (List) obj) {
if (o instanceof Map) {
loop((Map) o);
} else {
System.out.println(key + " : " + o);
}
}
} else if (obj instanceof Map) {
loop((Map) obj);
} else {
System.out.println(key + " : " + obj);
}
}
}
private static void loop(Map<String, Object> map) {
for (String key : map.keySet()) {
Object obj = map.get(key);
if (obj instanceof List) {
for (Object o : (List) obj) {
if (o instanceof Map) {
loop((Map) o);
} else {
System.out.println(key + " : " + o);
}
}
} else if (obj instanceof Map) {
loop((Map) obj);
} else {
System.out.println(key + " : " + obj);
}
}
}
Neither Jackson nor any other library will parse the Values array into objects with client data like your POJO. You can achieve this by getting the raw tree of data in this JSON and constructing objects by iterating over the Values array inside this tree. Assuming the order of ColumnNames is fixed then you can parse with Jackson like this:
final ObjectMapper mapper = new ObjectMapper();
final JsonNode tree = mapper.readTree(json);
final JsonNode values = tree.findValue("Values");
final List<ClientPOJO> clients = new ArrayList<>();
for (JsonNode node : values) {
final ClientPOJO client = new ClientPOJO();
client.setUserId(node.get(0).asText());
client.setDocumentId(node.get(1).asText());
client.setScoredLabels(node.get(2).asBoolean());
client.setScoredProbabilities(node.get(3).asDouble());
clients.add(client);
}
Docs for JsonNode. Basically with findValue you can get another node deep into the tree, with get you can get array elements by index and with asText etc you parse a value in JSON into the appropriate type in Java.
Since you seem to be flexible in choice of JSON parsing library I would suggest Jackson 2 from com.fasterxml instead of Jackson 1 from org.codehaus that you tried.
How should I deserialize following JSON to skip root element and parse just the inner part of this JSON. I'd like to avoid creating additional, 3rd class Root, which would include only MapWrapper field.
{
"root": {
"language": "en",
"map": {
"k1": {
"name": "n1",
},
"k2": {
"name": "n2",
}
}
}
}
So I'd like to have only these two classes:
class MapWrapper {
private String language;
private Map<String, MyMapEntry> map;
}
class MyMapEntry {
String name;
}
you can use GSON Library for this.
Below code will solve your problem.
public class ConvertJsonToObject {
private static Gson gson = new GsonBuilder().create();
public static final <T> T getFromJSON(String json, Class<T> clazz) {
return gson.fromJson(json, clazz);
}
public static final <T> String toJSON(T clazz) {
return gson.toJson(clazz);
}
}
String json; // your jsonString
Map<String,Object> r = ConvertJsonToObject.getFromJSON(json,Map.class);
String innerJson = ConvertJsonToObject.toJson(r.get("root"));
MapWrapper _r = ConvertJsonToObject.getFromJSON(innerJson,MapWrapper.class);
Consider the following JSON:
{"authorization":{"username":"userabc", "password":"passabc"}}
The DTO for this JSON without the root element
public class Authorization {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// Add a container for the root element
public static class Container {
public Authorization authorization;
}
}
Convert from/to JSON using the following methods (you can either keep this within DTO or some other help class)
public String toJson(Authorization authorization) {
Gson gson = new Gson();
Authorization.Container container = new Authorization.Container();
container.authorization = authorization;
return gson.toJson(container);
}
public Authorization fromJson(String json) {
Gson gson = new Gson();
Authorization.Container container = gson.fromJson(json, Authorization.Container.class);
return container.authorization;
}
This is the optimal code to do it in one pass.
MapWrapper class
public class MapWrapper {
private String language;
private Map<String, MyMapEntry> map;
public MapWrapper(String language, Map<String, MyMapEntry> map) {
this.language = language;
this.map = map;
}
}
MyMapEntry class
public class MyMapEntry {
String name;
public MyMapEntry(String name) {
this.name = name;
}
}
The Custom Deserializer
public class MyDeserialiser implements JsonDeserializer<MapWrapper>
{
#Override
public MapWrapper deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext ctx) throws JsonParseException {
JsonObject _global = json.getAsJsonObject();
_global = _global.get("root").getAsJsonObject();
JsonPrimitive lang = (JsonPrimitive) _global.get("language");
JsonElement map = _global.get("map");
Map<String, MyMapEntry> inMap = new LinkedHashMap<String, MyMapEntry>();
for (Entry<String, JsonElement> entry : map.getAsJsonObject()
.entrySet()) {
MyMapEntry _m = new MyMapEntry(entry.getValue().toString());
inMap.put(entry.getKey(), _m);
}
return new MapWrapper(lang.getAsString(), inMap);
}
}
Register it with GSON
new GsonBuilder().registerTypeAdapter(MapWrapper.class,new MyDeserialiser()).create()
Now deserialise with following code
String json; // your jsonString
MapWrapper result = ConvertJsonToObject.getFromJSON(json,MapWrapper.class);
My answer is late to this party.
Once we parse the Json, the container is always going to be a JsonObject subclass of JsonElement. Thus, if we want to skip it, we just need to cast it to its subclass and grab the field holding our inner class.
String response = ....;
Gson gson = new Gson();
JsonParser p = new JsonParser();
JsonElement jsonContainer = p.parse(response);
JsonElement jsonQuery = ((JsonObject) jsonContainer).get("query");
MyQuery query = gson.fromJson(jsonQuery, MyQuery.class);
Note: JsonObject and JSONObject are different classes (use the com.google.Json import).
You could generalize this answer more such that you wouldn't need to know the name of the inner class. You would do this by simply getting the one-and-only field of the container object. However, I see no way to do this other than starting up the iterator, there is no getValue(atIndex) method I can see, and I think starting an iterator is probably less efficient than simply looking up the field by name (but could be wrong).
The iterator method looks like:
JsonElement jsonQuery = ((JsonObject) jsonContainer).entrySet().iterator()
.next().getValue();
You could deserialize it into a Map<String, MapWrapper>.
Inspired by Gustav Carlson's idea I decided to expand it to a concrete sample. Here's a junit test that tests parsing this JSON as Map.
public static class MapWrapper {
private String language;
private Map<String, MyMapEntry> map;
}
public static class MyMapEntry {
String name;
}
#Test
public void testParsing() {
String json = "{\n" +
" \"root\": {\n" +
" \"language\": \"en\",\n" +
" \"map\": {\n" +
" \"k1\": {\n" +
" \"name\": \"n1\"\n" +
" },\n" +
" \"k2\": {\n" +
" \"name\": \"n2\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Type type = new TypeToken<Map<String, MapWrapper>>(){}.getType();
Map<String, MapWrapper> parsed = gson.fromJson(json, type);
MapWrapper mapWrapper = parsed.get("root");
Assert.assertEquals("en", mapWrapper.language);
Assert.assertEquals("n2", mapWrapper.map.get("k2").name);
}
I have a JSON response that I try to parse with Jackson, and type of one of fields is unknown.
Exapmle:
{"name" : "Catalina"}
OR
{"name" : {"First" : "Catalina", "Last" : "Kyle"}}
How I can deserialize that object into POJO:
class NamesHolder {
public String singleName;
public Map<String, String> nameMap;
}
This is synthetic example but I hope it clear for understanding.
In first case I want to have object with singleName == "Catalina" and nameMap == null, and vice versa in other case.
UPDATE
I am really sorry, at the end of day I misspelled the property name. In both cases they are the same: name.
Try making your name field an object:
class MyPojo {
public Object name;
}
The you'll have to check at runtime to see if it deserialized as a String or as a Map.
The easiest way is to rename your POJO properties to the same which you have in JSON. See below example:
class NamesHolder {
public String name;
public Map<String, String> names;
#Override
public String toString() {
return "NamesHolder{" +
"name='" + name + '\'' +
", names=" + names +
'}';
}
}
If you do not want to rename properties you can use #JsonProperty annotation. See below example:
class NamesHolder {
#JsonProperty("name")
public String singleName;
#JsonProperty("names")
public Map<String, String> nameMap;
#Override
public String toString() {
return "NamesHolder{" +
"name='" + singleName + '\'' +
", names=" + nameMap +
'}';
}
}
Two above classes work for your JSON examples. See below program:
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue("{\"names\" : {\"First\" : \"Catalina\", \"Last\" : \"Kyle\"}}", NamesHolder.class));
System.out.println(mapper.readValue("{\"name\" : \"Catalina\"}", NamesHolder.class));
which prints:
NamesHolder{name='null', names={First=Catalina, Last=Kyle}}
NamesHolder{name='Catalina', names=null}
EDIT 1
In this case you have to handle it manually using Object type. See below example:
public class JacksonTest {
public static void main(String[] args) throws Exception {
String json = "{\"name\" : \"Catalina\"}";
ObjectMapper deserializerMapper = new ObjectMapper();
NamesHolder namesHolder = deserializerMapper.readValue(json, NamesHolder.class);
System.out.println(toString(namesHolder));
json = "{\"name\" : {\"First\" : \"Catalina\", \"Last\" : \"Kyle\"}}";
namesHolder = deserializerMapper.readValue(json, NamesHolder.class);
System.out.println(toString(namesHolder));
}
private static String toString(NamesHolder namesHolder) {
if (namesHolder.hasStringName()) {
return "Type: String, Value: " + namesHolder.getStringName();
} else if (namesHolder.hasMapNames()) {
return "Type: Map, Value: " + namesHolder.getMapNames();
}
return "Type: Unknown, Value: " + namesHolder;
}
}
class NamesHolder {
public Object name;
public boolean hasStringName() {
return name instanceof String;
}
public String getStringName() {
return name.toString();
}
public boolean hasMapNames() {
return name instanceof Map;
}
public Map<String, String> getMapNames() {
return (Map<String, String>) name;
}
#Override
public String toString() {
return String.valueOf(name);
}
}
Above example prints:
Type: String, Value: Catalina
Type: Map, Value: {First=Catalina, Last=Kyle}
How can I parse the JSON below with Gson?
Now I use:
private AttachChildDataModel parseSuccess(String content){
Gson gson = new Gson();
return gson.fromJson(content, AttachChildDataModel.class);
}
Where AttachChildDataModel has these member variables:
private Integer adultId;
private Integer childId;
private PlatformEnum platform;
private String regId;
private Date loginDate;
private Date logoutDate;
private ClientApp clientApp;
The Json string I'm trying to parse is:
{"log":
{
"childId":2,
"adultId":1,
"logoutDate":null,
"platform":"IPHONE",
"regId":null,
"loginDate":1325419200000,
"clientApp":"CHILD_APP"
}
}
When I put the object into the Spring ModelView, I add it under name log. The problematic thing is when I try to parse it with Gson. Right now, I manually remove the "log" prefix and the "}" postfix with String#substring, but I think there's a better solution.
To solve your problem, just create a "foo" class like this:
package stackoverflow.questions.q15614008;
public class Foo {
public AttachChildDataModel log;
}
and use it as base class for parsing in Gson:
package stackoverflow.questions.q15614008;
import com.google.gson.*;
public class Q15614008 {
public static void main(String[] arg) {
String testString = "{\"log\": "
+ " {"
+ "\"childId\":2," + "\"adultId\":1,"
+ "\"logoutDate\":null,"
+ "\"platform\":\"IPHONE\","
+ "\"regId\":null,"
+ "\"loginDate\":1325419200000,"
+ "\"clientApp\":\"CHILD_APP\"}"
+ "}";
Gson gson = new Gson();
Foo foo = gson.fromJson(
testString, Foo.class);
System.out.println("Result: " + foo.log.toString());
}
}
Then use only the log member variable of the Foo class.