I'm using Java.
I have a JSON string like this given below :
{
"4562": {
"a": "foo1",
"b": "56",
"c": "1342"
},
"4563": {
"a": "foo2",
"b": "57",
"c": "1343"
}
}
I want to store all the data from the JSON string into Map.
How to do that ?
You need to use Jackson Library (jackson-databind).
Code :
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Example {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
String inputJson = "{ \n" +
" \"4562\": { \n" +
" \"a\": \"foo1\", \n" +
" \"b\": \"56\", \n" +
" \"c\": \"1342\" \n" +
" },\n" +
" \"4563\": { \n" +
" \"a\": \"foo2\", \n" +
" \"b\": \"57\", \n" +
" \"c\": \"1343\" \n" +
" }\n" +
"}";
Map<String, Map<String, String>> map = mapper.readValue(inputJson, Map.class);
System.out.println(map);
}
}
Output :
{4562={a=foo1, b=56, c=1342}, 4563={a=foo2, b=57, c=1343}}
Download jar from here : https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.1/
Use Gson:
String json = ...;
Gson gson = new GsonBuilder.setPrettyPrinting().create();
Map<String, Map<String, String>> map = gson.<Map<String, Map<String, String>>>fromJson(json, Map.class);
System.out.println(map);
Related
The goal is replace a value in a nested JSON.
Original JSON :
{
"data": {
"car": {
"xia": [
"a0.c904.b0"
]
}
}
}
Expected JSON:
{
"data": {
"car": {
"xia": [
"a0.c234.b0"
]
}
}
}
My code below gives me the JSONElement but I don't know how to put it back to the json object?
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
String inputJson = "{\n"
+ " \"data\": {\n"
+ " \"car\": {\n"
+ " \"xia\": [\n"
+ " \"a0.c904.b0\"\n"
+ " ]\n"
+ " }\n"
+ " }\n"
+ "}";
JsonObject jsonObject = new JsonParser().parse(inputJson).getAsJsonObject();
JsonElement jsonElement = jsonObject.get("data").getAsJsonObject().get("car").getAsJsonObject().get("xia");
String str = jsonElement.getAsString();
System.out.println(str);
String[] strs = str.split("\\.");
String replaced = strs[0] + "." + strs[1].replaceAll("\\d+", "234") + "." + strs[2];
System.out.println(replaced);
JsonElement jsonElementReplaced = new JsonParser().parse(replaced);
I just had to do :
jsonObject.get("data").getAsJsonObject().get("car").getAsJsonObject().add("xia", jsonElementReplaced);
how can i create a JSON string from Json array of objects like below in Java using JSON object
{
header: [
{
"key" : "numberOfRecords",
"value" : "122"
"valueDataType" : "string"
},
{
"key" : "g_udit"
"value" : "1"
"valueDataType" : "string"
},
{
"key": "userNameId"
"value" : "155"
"valueDataType : "string"
}
]
}
expected JSON output requires only values
{
header :
{
"numberOfRecords" : "122",
"g_udit" : "1",
"userNameId" : "155"
}
}
Use JSON query language to transform the JSON structure. A single Josson query statement can do the job.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(
"{" +
" \"header\": [" +
" {" +
" \"key\" : \"numberOfRecords\"," +
" \"value\" : \"122\"," +
" \"valueDataType\" : \"string\"" +
" }," +
" { " +
" \"key\" : \"g_udit\"," +
" \"value\" : \"1\"," +
" \"valueDataType\" : \"string\"" +
" }," +
" {" +
" \"key\": \"userNameId\"," +
" \"value\" : \"155\"," +
" \"valueDataType\" : \"string\"" +
" }" +
" ]" +
"}");
JsonNode node = josson.getNode("map(header.map(key::value).mergeObjects())");
Output
{
"header" : {
"numberOfRecords" : "122",
"g_udit" : "1",
"userNameId" : "155"
}
}
First of all you should use any json framework to read and write files. You can use jacskon-utils to use Jackson and make it much simpler to use.
Then you have to define the data classes for input and output types. And finally, convert the data.
#Getter
class InputData {
#JsonProperty("header")
private List<Header> headers;
#Getter
public static class Header {
private String key;
private String value;
private String valueDataType;
}
}
#Setter
class OutputData {
#JsonProperty("header")
private Map<String, String> headers;
}
public static void main(String... args) throws Exception {
InputData inputData = readData(new File("c:/in.json"));
OutputData outputData = createOutputData(inputData);
writeData(new File("c:/out.json"), outputData);
}
private static InputData readData(File file) throws Exception {
try (InputStream in = new FileInputStream(file)) {
return JacksonUtils.readValue(in, InputData.class);
}
}
private static void writeData(File file, OutputData outputData) throws Exception {
try (OutputStream out = new FileOutputStream(file)) {
JacksonUtils.prettyPrint().writeValue(outputData, out);
}
}
private static OutputData createOutputData(InputData inputData) {
Map<String, String> headers = new LinkedHashMap<>();
inputData.getHeaders().forEach(header -> headers.put(header.getKey(), header.getValue()));
OutputData outputData = new OutputData();
outputData.setHeaders(headers);
return outputData;
}
I am getting a JSON object which looks like:
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
{
"items": [{
"id": "1"
}]
}
}
I want to represent this as flat map, but I want to represent the array of items as a list.
My output should look like:
{
"id": "1",
"name":"Hw",
"price":"10",
"items": ["1"]
}
Can anybody suggest me how I can achieve this? I tried this approach:
How to deserialize JSON into flat, Map-like structure?
Output from the above tried link:
{
"id": "1",
"name":"Hw",
"price.value":"10",
"items[0].id": "1"
}
But it is representing the arrays values as array[0], array[1] which I don't need. I need this array as a list.
The JSON you've given is not valid. I assume it's:
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [{
"id": "1"
}]
}
There cannot be a generic solution to what you're asking. But for this particular JSON, this will do(using json-simple):
#SuppressWarnings("unchecked")
public Map<String, String> transform(String inputJSON) throws ParseException {
Map<String, String> result = new LinkedHashMap<>();
JSONObject inputJSONObj = (JSONObject) new JSONParser().parse(inputJSON);
String id = inputJSONObj.getOrDefault("id", "").toString();
String name = inputJSONObj.getOrDefault("name", "").toString();
String price = ((JSONObject) inputJSONObj.getOrDefault("price", new JSONObject())).getOrDefault("value", "")
.toString();
JSONArray itemsArray = (JSONArray) inputJSONObj.getOrDefault("items", new JSONArray());
int n = itemsArray.size();
String[] itemIDs = new String[n];
for (int i = 0; i < n; i++) {
JSONObject itemObj = (JSONObject) itemsArray.get(i);
String itemId = itemObj.getOrDefault("id", "").toString();
itemIDs[i] = itemId;
}
result.put("id", id);
result.put("name", name);
result.put("price", price);
result.put("items", Arrays.toString(itemIDs));
return result;
}
An approach for you with Gson. This do exactly what you want " represent this as flat map, but I want to represent the array of items as a list"
public class ParseJson1 {
public static void main (String[] args){
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
Gson gson = new Gson();
String json = "{\n" +
" \"id\": \"1\",\n" +
" \"name\": \"Hw\", \n" +
" \"price\": {\n" +
" \"value\": \"10\"\n" +
" },\n" +
" \"items\": [{\n" +
" \"id\": \"1\"\n" +
" }]\n" +
" }\n";
HashMap<String, Object> map = gson.fromJson(json, type);
Object val = null;
for(String key : map.keySet()){
val = map.get(key);
if(val instanceof List){
for(Object s : (List)val){
System.out.println(key + ":" + s);
}
} else
System.out.println(key + ":" + map.get(key));
}
}
}
you have to convert your String in Map collection Map<String, String> which will help you to convert your Map Array to JSON format.
JSONObject jsonObject = new JSONObject();
Map<String, String> mapObject = new HashMap<String, String>();
mapObject.put("id", "1");
mapObject.put("name", "VBage");
mapObject.put("mobile", "654321");
jsonObject.put("myJSON", mapObject);
System.out.println(jsonObject.toString());
First, the JSON does not seems to have a correct format. Do you mean this?
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [{
"id": "1"
}]
}
In addition, since you were attaching the link of (How to deserialize JSON into flat, Map-like structure?), I assume you wants to flatten the JSON in the same manner, in which the result should be
{
id=1,
name=Hw,
price.value=10,
items[0]=1,
}
Also, if you just want the item to return a list of id (i.e. "items": ["1"]), then it is more logical to get a JSON of
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [ "1" ] // instead of "items": [{"id": "1"}]
}
The link that you have attached (How to deserialize JSON into flat, Map-like structure?) provides a general solution without any customization. It shouldn't know that "id" is the value you want to append on items.
Therefore, my first suggestion is to change the JSON to be "items": [ "1" ]
If for any reasons the JSON cannot be changed, then you will need to do some customization, which will be like this:
import org.codehaus.jackson.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.ValueNode;
import org.junit.Test;
public class Main {
String json = "{\n" +
" \"id\": \"1\",\n" +
" \"name\": \"Hw\", \n" +
" \"price\": {\n" +
" \"value\": \"10\"\n" +
" },\n" +
" \"items\": [{\n" +
" \"id\": \"1\"\n" +
" }]\n" +
" }\n";
#Test
public void testCreatingKeyValues() {
Map<String, String> map = new HashMap<String, String>();
try {
addKeys("", new ObjectMapper().readTree(json), map);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(map);
}
private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map) {
if (jsonNode.isObject()) {
ObjectNode objectNode = (ObjectNode) jsonNode;
Iterator<Map.Entry<String, JsonNode>> iter = objectNode.getFields();
String pathPrefix = currentPath.isEmpty() ? "" : currentPath + ".";
while (iter.hasNext()) {
Map.Entry<String, JsonNode> entry = iter.next();
// Customization here
if (entry.getKey().equals("items")) {
ArrayNode arrayNode = (ArrayNode) entry.getValue();
for (int i = 0; i < arrayNode.size(); i++) {
addKeys(currentPath + entry.getKey() + "[" + i + "]", arrayNode.get(i).get("id"), map);
}
} else {
addKeys(pathPrefix + entry.getKey(), entry.getValue(), map);
}
}
} else if (jsonNode.isArray()) {
ArrayNode arrayNode = (ArrayNode) jsonNode;
for (int i = 0; i < arrayNode.size(); i++) {
addKeys(currentPath + "[" + i + "]", arrayNode.get(i), map);
}
} else if (jsonNode.isValueNode()) {
ValueNode valueNode = (ValueNode) jsonNode;
map.put(currentPath, valueNode.asText());
}
}
}
Try understanding the format that you need, and then study the above code. It should give you the answer.
I want to parse the json string in java class (.java) created by stringify() function in javascript. I know to parse the string like:
String JSON_DATA
= "{"
+ " \"geodata\": ["
+ " {"
+ " \"id\": \"1\","
+ " \"name\": \"Julie Sherman\","
+ " \"gender\" : \"female\","
+ " \"latitude\" : \"37.33774833333334\","
+ " \"longitude\" : \"-121.88670166666667\""
+ " },"
+ " {"
+ " \"id\": \"2\","
+ " \"name\": \"Johnny Depp\","
+ " \"gender\" : \"male\","
+ " \"latitude\" : \"37.336453\","
+ " \"longitude\" : \"-121.884985\""
+ " }"
+ " ]"
+ "}";
but how to parse this string?
var IO = {
//returns array with storable google.maps.Overlay-definitions
IN: function(arr, //array with google.maps.Overlays
encoded//boolean indicating whether pathes should be stored encoded
) {
var shapes = [],
goo = google.maps,
shape, tmp;
for (var i = 0; i < arr.length; i++)
{
shape = arr[i];
tmp = {type: this.t_(shape.type), id: shape.id || null};
switch (tmp.type) {
case 'CIRCLE':
tmp.radius = shape.getRadius();
tmp.geometry = this.p_(shape.getCenter());
break;
case 'MARKER':
tmp.geometry = this.p_(shape.getPosition());
break;
case 'RECTANGLE':
tmp.geometry = this.b_(shape.getBounds());
break;
case 'POLYLINE':
tmp.geometry = this.l_(shape.getPath(), encoded);
break;
case 'POLYGON':
tmp.geometry = this.m_(shape.getPaths(), encoded);
break;
}
shapes.push(tmp);
}
return shapes;
}
and the string formed to be parsed is:
[{"type":"CIRCLE","id":null,"radius":1730.4622192451884,"geometry":[32.3610810916614,50.91339111328125]},{"type":"CIRCLE","id":null,"radius":1831.5495077322266,"geometry":[32.35528086804335,50.997161865234375]},{"type":"CIRCLE","id":null,"radius":1612.2461023303567,"geometry":[32.34454947365649,51.011924743652344]}]
You can use Gson or Jackson for this. Create a POJO that hold the data and use these libs. An eg with Gson
import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
class JsonData {
private String type;
private String id;
private double radius;
private List<Double> geometry;
//Getters & Setters
}
public class JsonParser {
public static void main(String[] args) {
String json = "[{\"type\":\"CIRCLE\",\"id\":null,\"radius\":1730.4622192451884,\"geometry\":[32.3610810916614,50.91339111328125]},{\"type\":\"CIRCLE\",\"id\":null,\"radius\":1831.5495077322266,\"geometry\":[32.35528086804335,50.997161865234375]},{\"type\":\"CIRCLE\",\"id\":null,\"radius\":1612.2461023303567,\"geometry\":[32.34454947365649,51.011924743652344]}]";
Type listType = new TypeToken<List<JsonData>>() {}.getType();
List<JsonData> disputeSummaryArraylistobjectList = new Gson().fromJson(json, listType);
System.out.println(disputeSummaryArraylistobjectList);
}
}
You will need a JSON parser for Java like GSON or Jackson.
There are two strategies for parsing:
Creating Java objects and let the JSON parsers map elements in the input to fields
Iterating over the generic JSON data structure which the parser returns
The documentation of both projects contain lots of examples how to achieve either.
Given the following JSON response:
{
"status": "OK",
"regions": [
{
"id": "69",
"name": "North Carolina Coast",
"color": "#01162c",
"hasResorts": 1
},
{
"id": "242",
"name": "North Carolina Inland",
"color": "#01162c",
"hasResorts": 0
},
{
"id": "17",
"name": "North Carolina Mountains",
"color": "#01162c",
"hasResorts": 1
},
{
"id": "126",
"name": "Outer Banks",
"color": "#01162c",
"hasResorts": 1
}
]
}
I'm trying to create a List of Region objects. Here's a very abridged version of my current code:
JSONObject jsonObject = new JSONObject(response);
String regionsString = jsonObject.getString("regions");
Type listType = new TypeToken<ArrayList<Region>>() {}.getType();
List<Region> regions = new Gson().fromJson(regionsString, listType);
This is all working fine. However, I'd like to exclude the regions in the final List that hasResorts == 0. I realize I can loop through the actual JSONObjects and check them before calling fromJSON on each region. But I'm assuming there is a GSON specific way of doing this.
I was looking at the ExclusionStrategy(). Is there a simple way to implement this to JSON deserialization?
ExclusionStrategy won't help you since it works without the context of deserialization. Indeed, you can exclude only a specific kind of class. I think that best way of doing it is through custom deserialization. Here is what I mean (you can copy&paste&try immediately):
package stackoverflow.questions.q19912055;
import java.lang.reflect.Type;
import java.util.*;
import stackoverflow.questions.q17853533.*;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
public class Q19912055 {
class Region {
String id;
String name;
String color;
Integer hasResorts;
#Override
public String toString() {
return "Region [id=" + id + ", name=" + name + ", color=" + color
+ ", hasResorts=" + hasResorts + "]";
}
}
static class RegionDeserializer implements JsonDeserializer<List<Region>> {
public List<Region> deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
if (json == null)
return null;
ArrayList<Region> al = new ArrayList<Region>();
for (JsonElement e : json.getAsJsonArray()) {
boolean deserialize = e.getAsJsonObject().get("hasResorts")
.getAsInt() > 0;
if (deserialize)
al.add((Region) context.deserialize(e, Region.class));
}
return al;
}
}
/**
* #param args
*/
public static void main(String[] args) {
String json =
" [ "+
" { "+
" \"id\": \"69\", "+
" \"name\": \"North Carolina Coast\", "+
" \"color\": \"#01162c\", "+
" \"hasResorts\": 1 "+
" }, "+
" { "+
" \"id\": \"242\", "+
" \"name\": \"North Carolina Inland\", "+
" \"color\": \"#01162c\", "+
" \"hasResorts\": 0 "+
" }, "+
" { "+
" \"id\": \"17\", "+
" \"name\": \"North Carolina Mountains\", "+
" \"color\": \"#01162c\", "+
" \"hasResorts\": 1 "+
" }, "+
" { "+
" \"id\": \"126\", "+
" \"name\": \"Outer Banks\", "+
" \"color\": \"#01162c\", "+
" \"hasResorts\": 1 "+
" } "+
" ] ";
Type listType = new TypeToken<ArrayList<Region>>() {}.getType();
List<Region> allRegions = new Gson().fromJson(json, listType);
System.out.println(allRegions);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(listType, new RegionDeserializer());
Gson gson2 = builder.create();
List<Region> regionsHaveResort = gson2.fromJson(json, listType);
System.out.println(regionsHaveResort);
}
}