I am deserializing a JSON into a Map<Integer, String>.
But I am getting the above classCastException if I try to assign a key to primitive int .
ObjectReader reader = new ObjectMapper().reader(Map.class);
String patternMetadata = "{\"1\":\"name\", \"2\":\"phone\", \"3\":\"query\"}";
Map<Integer, String> map = reader.readValue(patternMetadata);
System.out.println("map: " + map);
for (Map.Entry<Integer, String> entry : map.entrySet())
{
try
{
System.out.println("map: " + entry.getKey());
int index = entry.getKey();
System.out.println("map**: " + index);
}
catch (Exception e)
{
e.printStackTrace();
}
}
I am getting this java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer exception on second line in try block.
I even tried changing int index = enty.getKey().intValue(). But still the same exception occurs.
P.S.: I am running it in an Android studio using Robolectric framework.
Those keys aren't integers, they're strings. Note the quotes on them:
String patternMetadata = "{\"1\":\"name\", \"2\":\"phone\", \"3\":\"query\"}";
// ------------------------^^-^^-----------^^-^^------------^^-^^
If this is JSON (it seems to be), object property names are always strings.
You'll need a Map<String, String> and then you'll need to parse the keys to int explicitly (if needed).
Jackson can deserialize keys into some default types (or custom types with some extra configuration) if you tell it to.
Since Map is a generic type, you'll need to use a TypeReference to describe the parameterization you want.
reader is deprecated since 2.5. You should use readerFor instead. Construct your ObjectReader by providing an appropriate TypeReference with Integer keys for the Map. Jackson will then know you expect Integer values as the keys to your map.
ObjectReader reader = new ObjectMapper().readerFor(new TypeReference<Map<Integer, String>>() {
});
Full example
ObjectReader reader = new ObjectMapper().readerFor(new TypeReference<Map<Integer, String>>() {
});
String patternMetadata = "{\"1\":\"name\", \"2\":\"phone\", \"3\":\"query\"}";
Map<Integer, String> map = reader.readValue(patternMetadata);
System.out.println("map: " + map);
for (Map.Entry<Integer, String> entry : map.entrySet()) {
try {
System.out.println("map: " + entry.getKey());
int index = entry.getKey();
System.out.println("map**: " + index);
} catch (Exception e) {
e.printStackTrace();
}
}
prints
map: {1=name, 2=phone, 3=query}
map: 1
map**: 1
map: 2
map**: 2
map: 3
map**: 3
Related
I'm receiving the following JSON object and I'm only interested in the errors. I can log to the console each key and value. The issue is for example 'Email' key has 2 x values, how can i create a map or list so every value has its own key and remove the JSON formatting?
{
"errors":
{
"Email":["'Email' must not be empty.","'Email' is not a valid email address."],
"Company":["'Company' must not be empty."],
"LastName":["'Last Name' must not be empty."],
"Password":["'Password' must not be empty."],
"FirstName":["'First Name' must not be empty."],
"Telephone":["'Telephone' must not be empty."]
},
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"80005307-0001-5d00-b63f-84710c7967bb"
}
In codenameone i'm parsing using JSON parser in to a map of string, object:
Map<String,Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
Map<String,Object> value = (Map<String,Object>) result.get("errors");
for (Map.Entry<String, Object> entry : value.entrySet()) {
Log.p(entry.getKey());
Log.p(entry.getValue().toString())
}
The value of the email field is a list, as indicated by the [] square brackets.
Since it appears that all the fields of errors have lists of strings, you should simple cast to Map<String, List<String>>, so you don't have to cast any further.
Map<String,Object> result = /*result of parsing JSON input*/;
#SuppressWarnings({ "rawtypes", "unchecked" })
Map<String, List<String>> errors = (Map) result.get("errors");
for (Entry<String, List<String>> error : errors.entrySet()) {
String name = error.getKey();
List<String> messages = entry.getValue();
Log.p(name);
for (String message : messages)
Log.p(" " + message);
}
That's your thing, brother, I just changes some names for better readability:
Map<String,Object> errors = (Map<String,Object>) map.get("errors");
Collection<Object> values = errors.values();
values.stream().flatMap(x->((ArrayList<String>)x).stream()).forEach(value -> {
String key = errors.entrySet()
.stream()
.filter(tempEntry -> ((ArrayList<String>)tempEntry.getValue()).contains(value))
.findAny()
.get()
.getKey();
System.out.println(key + value);
});
So ye from that you can create a Collection of entries. Currently we print them, but you can skip ".getKey()" and "System.out" and start adding them to a collection.
I'm working on some JSON converting to POJO and the server I'm getting response of is sending a JSON like this:
"Availability":{
"StatusCode":"A",
"BreakDown":{
"2017-10-27":"A"
}
}
How can I save this ( "2017-10-27":"A" )? It changes with each of my request so it should be dynamic! Is it even possible?
If you are going the value currently represented as "2017-10-27":"A", you have to know it is hold in the variable "BreakDown". So you need to query this variable with jsonPath: $.Availability.BreakDown.
it will give this JSON object:
{"2017-10-27":"A"}
Hope it answer your question
The first answer is pretty accurate but to extract the key and value without directly referencing is the target since they are dynamic.
var x = obj.Availability.Breakdown;
for(var key in x){
console.log(key);
console.log(x[key]);
}
This way you get the key and the value both and use it as you like.
Plus, if there are multiple key-value pair inside var x then they can also be reached with this loop.
Assuming that with "should be dynamic" you mean that the content that you want to save (the one inside BreakDown) could change (even the type) for each request and assuming that your example of the json is:
Test.json:
{
"StatusCode":"A",
"BreakDown":{
"2017-10-27":"A"
}
}
You could use the Gson library to get the info that you want. Because every class has Object as a superclass, you could deserialize your json as a Map<Object, Object>.
public static void main(String args[]) {
Gson gson = new Gson();
Map<Object, Object> breakDown=null;
String filename="/.../Test.json";
JsonReader reader = null;
try {
reader = new JsonReader(new FileReader(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final Type type = new TypeToken<Map<Object,Object>>() {}.getType();
Map <Object,Object> conv= gson.fromJson(reader, type);
for (Map.Entry<Object, Object> entry : conv.entrySet())
{
System.out.println(entry.getKey() + "/" + entry.getValue());
if(entry.getKey().equals("BreakDown"))
{
breakDown= (Map<Object, Object>) entry.getValue();
}
}
if(breakDown!=null){
Map.Entry first= breakDown.entrySet().iterator().next();
System.out.println(first.getKey());
System.out.println(first.getValue());
}
}
The Map<Object, Object> breakDown map is also of Objects because I'm assuming that the key and the value could be different of the example that you posted. Otherwise, if the key is always a date and the value a string, can be defined as Map<Date, String> breakDown.
I am trying to receive message attributes from Amazon SQS with the following code :
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
}
and it returns the output:
project - {StringValue: 25,StringListValues: [],BinaryListValues: [],DataType: String}
I want to get only the value 25. How do I do that?
Try this:
attributes.get("project").getStringValue()
References:
How to extract from a Map the value of a given key?
How to extract a String Value of a given MessageAttributeValue?
Because that's the object of value type com.amazonaws.services.sqs.model.MessageAttributeValue declared in your Map .
You need to get the value out of that object like the way you would normally do :
for(String key: attributes.keySet()){
com.amazonaws.services.sqs.model.MessageAttributeValue object = attributes.get(key);
//some method to get that 25 value
System.out.println(key + " - "+ object.getStringValue());
}
You need to loop on your map here is an example to show you how to get the values of the map:
I have a : Map<String, Object> map = new HashMap<String, Object>();
for (Entry<String, Object> entry : map.entrySet()) {
System.out.println("entry key : "+entry.getKey());
System.out.println("Object value :"+entry.getValue());
}
use this (library org.json.JSONObject; [java-json.jar])
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
try {
JSONObject json = new JSONObject(attributes.get(key));
System.out.println(json.get("StringValue"));
} catch (JSONException e) {
e.printStackTrace();
}
}
I'm looking for good way or complete API to create a hierarchical JSON from plain java.util.Properties object.
Exist java.util.Properties object, e.g.:
car.color=blue
car.places=4
car.motor.dimension=2L
car.motor.ps=120
and the target json structur should be:
{
"car":
{"color":"blue",
"places":4,
"motor":
{"dimension":"2L",
"ps":120
}
}
}
public void run() throws IOException {
Properties properties = ...;
Map<String, Object> map = new TreeMap<>();
for (Object key : properties.keySet()) {
List<String> keyList = Arrays.asList(((String) key).split("\\."));
Map<String, Object> valueMap = createTree(keyList, map);
String value = properties.getProperty((String) key);
value = StringEscapeUtils.unescapeHtml(value);
valueMap.put(keyList.get(keyList.size() - 1), value);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(map);
System.out.println("Ready, converts " + properties.size() + " entries.");
}
#SuppressWarnings("unchecked")
private Map<String, Object> createTree(List<String> keys, Map<String, Object> map) {
Map<String, Object> valueMap = (Map<String, Object>) map.get(keys.get(0));
if (valueMap == null) {
valueMap = new HashMap<String, Object>();
}
map.put(keys.get(0), valueMap);
Map<String, Object> out = valueMap;
if (keys.size() > 2) {
out = createTree(keys.subList(1, keys.size()), valueMap);
}
return out;
}
The following project 'Java Properties to JSON' achieves exactly what you seek.
However, it has a restriction on Java 8.
Would be great if someone actually provides changes to make it Java 7 compatible.
You will need to parse your properties to Map<String, Object> where your Object will be either another Map<String, Object> or a String. For this you will have to write your own code. I suppose you will need to take your properties keys and split them over "." using method String.split(). Note that in your code you will need to use "\\." as a parameter as "." is a regular expression. Once you build your Map it is very easy to convert it to JSON using Jackson library or any available JSON library.
i want to retrieve all data that are present in my data structure, which is of type Map of Maps.The data structure is mentioned below.
public static Map<String, Map<String, String>> hourlyMap = new HashMap<String, Map<String, String>>();
i need all the data that are stored in the map irrespective of key.
This may help you
Map<String,Map<String,String>> hourlyMap = new HashMap<String,Map<String,String>>();
for(Map<String,String> i:hourlyMap.values()){
// now i is a Map<String,String>
for(String str:i.values()){
// now str is a value of map i
System.out.println(str);
}
}
Try:
Set<String> allData = new HashSet<>(); // will contain all the values
for(Map<String, String> map : hourlyMap.values()) {
allData.addAll(map.values());
}
for (String outerKey: hourlyMap.keySet()) {
// outerKey holds the Key of the outer map
// the value will be the inner map - hourlyMap.get(outerKey)
System.out.println("Outer key: " + outerKey);
for (String innerKey: hourlyMap.get(outerKey).keySet()) {
// innerKey holds the Key of the inner map
System.out.println("Inner key: " + innerKey);
System.out.println("Inner value:" + hourlyMap.get(outerKey).get(innerKey));
}
}