How to use JSONDeserializer to deserialize this string? - java

I have string like follows:
{"226167":"myshow","3193":"yourshow"}
How can I use JSONDeserializer to extract (226167,3193) from the above string object?
I probably want to have a list (226167,3193,...) from the above string. I am using flexjason 1.9.2 and it doesn't have jsonObject class.

Use the jackson JSON library's ObjectMapper class to deserialize into a Map and then get the keySet():
Required Import:
import org.codehaus.jackson.map.ObjectMapper;
Example:
public void readValueAsMap() throws Exception
{
String value = "{\"226167\":\"myshow\",\"3193\":\"yourshow\"}";
ObjectMapper mapper = new ObjectMapper();
Map<String,String> valueAsMap = mapper.readValue(value, Map.class);
Collection<String> values = valueAsMap.keySet();
assertTrue(values.contains("226167"));
assertTrue(values.contains("3193"));
}

Related

How to convert a JsonNode instance to an actual pojo

At a certain point in my code, I have parse a JSON document, represented as a string, to a JsonNode, because I don't know yet the actual target pojo class type.
Now, some time later, I know the Class instance of the pojo and I want to convert this JsonNode to an actual pojo of that class (which is annotated with the proper #JsonProperty annotations). Can this be done? If so, how?
I am working with Jackson 2.10.x.
In this case you can use two methods:
treeToValue
convertValue
See below example:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.StringJoiner;
public class JsonNodeConvertApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonFile);
System.out.println(mapper.treeToValue(node, Message.class));
System.out.println(mapper.convertValue(node, Message.class));
}
}
class Message {
private int id;
private String body;
// getters, setters, toString
}
Above code for JSON payload like below:
{
"id": 1,
"body": "message body"
}
prints:
Message[id=1, body='message body']
Message[id=1, body='message body']

How to convert to json to object by passing the object type

public static Object convertToObject(String json) {
validate("json", json);
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(json, new TypeReference<Object>(){});
} catch (JsonProcessingException ex) {
throw new RuntimeException("Failed to convert json to object: "+json, ex);
}
}
//Here I'm doing type cast for the returned object
Map<String, ArrayList<Integer>> convertedMap = (Map<String, ArrayList<Integer>>) RestClient.convertToObject(json);
I tried above code
I'm using jackson and I need to pass the json with type so that I can avoid the type cast in the caller place.
Can anyone help me in this?
Thanks in advance
Object mapper requires 2nd Parameter as a Class type, so try passing:
Object.class
as below:
return mapper.readValue(json, Object.class);
First, you should use this method in common class for Mapper initialization
public static ObjectMapper getJacksonMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
mapper.setVisibility(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
return mapper;
}
Second thing, you should create POJO class for the corresponding json. Finally you can get the json string has to be converted as POJO class and you can use it very easily.
SamplePOJO poListResponse = AppUtils.getJacksonMapper().readValue(jsonString, SamplePOJO.class);

Retrieve the values from JSON String by sending keys dynamically using jackson API?

I have a json string like
{
"profile":{
"personalInfo":{
"name":"Sample",
"address":"XXX",
"town":"YYY"
}
}
}
I want retrieve data by sending keys dynamically.
I can able to retrieve by giving key directly. But i don't want that.
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree("aboveJsonString");
JsonNode subNode = jsonNode.path("profile");
But i have to give "profile" dynamically. I will get that parameter from api request. Suggest me the approach?
When you do not know name of a key in JSON Object you can iterate over all elements using elements which returns Iterator<JsonNode>. In your case you have two JSON Objects with one key-value pair and you can traverse it like below:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import java.io.File;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = JsonMapper.builder()
.build();
JsonNode root = mapper.readTree(jsonFile);
JsonNode personalInfo = root.elements().next().elements().next();
System.out.println(personalInfo);
}
}
Above code prints:
{"name":"Sample","address":"XXX","town":"YYY"}

want to map a json object unto a java object

I am using a certain API which have a json output as below. I have parsed it to String.
the json output as string: {"result":{"number":"INC0022500"}}.
As you can see it has nested object for key result.
my snippet which i am using to map the above json unto a object.
Gson gson = new Gson();
EspIncidentTrial staff = gson.fromJson(json, EspIncidentTrial.class);
ESPIncidentTrial class:
import javax.persistence.Embeddable;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
#Embeddable
#JsonIgnoreProperties(ignoreUnknown = true)
public class EspIncidentTrial {
#JsonProperty("result")
private ResultTrial result;
public ResultTrial getResult() {
return result;
}
public void setResult(ResultTrial result) {
this.result = result;
}
}
For the nested object i created another class ResultTrial. Below is the body.
ResultTrial class:
import javax.persistence.Embeddable;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
#Embeddable
#JsonIgnoreProperties(ignoreUnknown = true)
public class ResultTrial {
#JsonProperty("number")
private String incidentId;
public String getIncidentId() {
return incidentId;
}
public void setIncidentId(String incidentId) {
this.incidentId = incidentId;
}
}
What happens now is, in EspIncidentTrial class, object result is getting mapped. However, inside ResultTrial class, no mapping is being done.
I tried treating the key result in the json object as String, but the threw the below error, which was expected though.
The error occured while parsing the JSON. com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 12 path $.result
Please help!
Here you are mixing gson and Jackson.
You are using annoations of Jackson, but using GSON's method to deserailze it.
Use Jackson's objectMapper to deserialize.
E.g.:
ObjectMapper mapper = new ObjectMapper();
EspIncidentTrial staff = mapper.readValue(json, EspIncidentTrial.class);
you can try this....
String searchdata="{\"userPojo\":{\"userid\":1156}}";
JSONObject jsonObject=new JSONObject(searchdata);
SummaryPojo summaryPojo=new SummaryPojo();
if(searchdata.contains("userPojo"))
{
String jsonstring=jsonObject.getString("userPojo");
Gson gson = new Gson();
UserPojo userPojo = gson.fromJson(searchdata, UserPojo.class);
summaryPojo.setUserPojo(userPojo);
}

How to serialize a Map of a Map with GSON?

I want to serialize my Example class below into JSON using GSON.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.LinkedHashMap;
public class Example
{
private LinkedHashMap<String,Object> General;
private static final String VERSION="Version";
private static final String RANGE="Range";
private static final String START_TIME="Start_Time";
private static final String END_TIME="End_Time";
public Example() {
General = new LinkedHashMap<String,Object>();
General.put(VERSION, "0.1");
LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>();
Range.put(START_TIME, "now");
Range.put(END_TIME, "never");
General.put(RANGE, Range);
}
public String toJSON() {
Gson gson = new GsonBuilder().serializeNulls().create();
return gson.toJson(this);
}
}
I expected to get the following output:
{"General":{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}}
But calling the function toJSON() returns
{"General":{"Version":"0.1","Range":{}}}
It seems that GSON cannot serialize the Map Range inside the Map General. Is this a limitation of GSON or am I doing something wrong here?
The reason why Nishant's answer works is because Gson's default constructor enables all kind of stuff per default that you would otherwise have to manually enably using the GsonBuilder.
From the JavaDocs:
Constructs a Gson object with default configuration. The default configuration has the following settings:
The JSON generated by toJson methods is in compact representation. This means that all the unneeded white-space is removed. You can change this behavior with GsonBuilder.setPrettyPrinting().
The generated JSON omits all the fields that are null. Note that nulls in arrays are kept as is since an array is an ordered list. Moreover, if a field is not null, but its generated JSON is empty, the field is kept. You can configure Gson to serialize null values by setting GsonBuilder.serializeNulls().
Gson provides default serialization and deserialization for Enums, Map, java.net.URL, java.net.URI, java.util.Locale, java.util.Date, java.math.BigDecimal, and java.math.BigInteger classes. If you would prefer to change the default representation, you can do so by registering a type adapter through GsonBuilder.registerTypeAdapter(Type, Object).
The default Date format is same as java.text.DateFormat.DEFAULT. This format ignores the millisecond portion of the date during serialization. You can change this by invoking GsonBuilder.setDateFormat(int) or GsonBuilder.setDateFormat(String).
By default, Gson ignores the com.google.gson.annotations.Expose annotation. You can enable Gson to serialize/deserialize only those fields marked with this annotation through GsonBuilder.excludeFieldsWithoutExposeAnnotation().
By default, Gson ignores the com.google.gson.annotations.Since annotation. You can enable Gson to use this annotation through GsonBuilder.setVersion(double).
The default field naming policy for the output Json is same as in Java. So, a Java class field versionNumber will be output as "versionNumber#quot; in Json. The same rules are applied for mapping incoming Json to the Java classes. You can change this policy through GsonBuilder.setFieldNamingPolicy(FieldNamingPolicy).
By default, Gson excludes transient or static fields from consideration for serialization and deserialization. You can change this behavior through GsonBuilder.excludeFieldsWithModifiers(int).
OK, now I see what the problem is. The default Map serializer, as you expected, does not support nested maps. As you can see in this source snippet from DefaultTypeAdapters (especially if you step through with a debugger) the variable childGenericType is set to the type java.lang.Object for some mysterious reason, so the runtime type of the value is never analysed.
Two solutions, I guess:
Implement your own Map serializer / deserializer
Use a more complicated version of your method, something like this:
public String toJSON(){
final Gson gson = new Gson();
final JsonElement jsonTree = gson.toJsonTree(General, Map.class);
final JsonObject jsonObject = new JsonObject();
jsonObject.add("General", jsonTree);
return jsonObject.toString();
}
Try this:
Gson gson = new Gson();
System.out.println(gson.toJson(General));
Not sure if you're still looking for a solution, this works for me:
import java.util.LinkedHashMap;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Example {
// private static LinkedHashMap<String,Object> General;
private ImmutableMap General;
private static final String VERSION="Version";
private static final String RANGE="Range";
private static final String START_TIME="Start_Time";
private static final String END_TIME="End_Time";
public Example() {
LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>();
Range.put(START_TIME, "now");
Range.put(END_TIME, "never");
// General.put(RANGE, Range);
General = ImmutableMap.of(VERSION, "0.1", RANGE, Range);
}
public String toJSON() {
// Gson gson = new GsonBuilder().serializeNulls().create();
Gson gson = new Gson();
return gson.toJson(this);
}
}
returns: {"General":{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}}
Obviously you could use ImmutableMap.copyOf(your_hashmap)here instead
A simpler alternative would be to use Jackson instead of GSON, serialization of a nested map works out of the box:
LinkedHashMap<String, Object> general;
general = new LinkedHashMap<String, Object>();
general.put("Version", "0.1");
LinkedHashMap<String, String> Range = new LinkedHashMap<String, String>();
Range.put("Start_Time", "now");
Range.put("End_Time", "never");
general.put("Range", Range);
// Serialize the map to json using Jackson
ByteArrayOutputStream os = new ByteArrayOutputStream();
new org.codehaus.jackson.map.ObjectMapper().writer().writeValue(os,
general);
String json = os.toString();
os.close();
System.out.println(json);
Output:
{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}

Categories

Resources