I have few cases where I want to convert a snake_case JSON to nested JSON
e.g.
{
"snake_case": {
"test": "value"
}
}
to
{
"snake": {
"case": {
"test": "value"
}
}
}
Is there any way to do this in java other then manually parsing the strings with _ or there any libraries are there in java?
Consider your JSON data as String:
String strjson="{snake_case: {test: value}}";
then
JSONObject jj=new JSONObject(strjson);
JSONObject jfinal=new JSONObject();
Iterator<String> itr=jj.keys();
while(itr.hasNext())
{
String key=itr.next();
if(key.contains("-"))
{
JSONObject jkey=jj.getJSONObject(key);
JSONObject jnew=new JSONObject();
jnew.put(key.split("-")[1],jkey);
jfinal.put(key.split("-")[0],jnew);
}
}
you can get the output in jfinal.
You could BSON to achieve this. Here is the code you would use.
//import java.util.ArrayList;
//import org.bson.Document;
//Declare three json object
Document root= new Document();
Document rootSnake = new Document();
Document rootSnakeCase = new Document();
//Add value to the most nested object
rootSnakeCase.append("test","value");
//combine the objects together
if (!rootSnakeCase.isEmpty()){
rootSnake.append("case",rootSnakeCase);
}
if (!rootSnake.isEmpty()){
root.append("snake",rootSnake);
}
//output code
System.out.println(root.toJson());
Related
I'm learning JACKSON. To train my skills i want to get field "URL" from following JSON:
How can i do that? I don't need whole JSON-object, just one field (URL).
You don't need to convert the JSON into a Java Object for that you will need to define POJOS.
Maybe this will help :-
final ObjectNode yourNode = new ObjectMapper().readValue(<Your_JSON_Input_String>, ObjectNode.class);
if (node.has("URL")) {
System.out.println("URL :- " + node.get("URL"));
}
import org.json.JSONArray;
import org.json.JSONObject;
public class Main {
public static void main(String[] args) throws IOException {
String jsonString = "{\"data\":[{\"url\":\"http://example.com\"}]}";
JSONObject jsonObject = new JSONObject(jsonString); // 1
JSONArray data = jsonObject.getJSONArray("data"); // 2
JSONObject objectAtIndex0 = data.getJSONObject(0); // 3
String urlAtObject0 = objectAtIndex0.getString("url"); // 4
System.out.println(urlAtObject0);
}
}
Get JSON object for whole JSON string
Get data as JSON array
Get JSON object at desired index or loop on JSON array of previous step
Get url field of the JSON object
i have a json-object named jsonObject
{
"action":"Read",
"infos":[
{
"value":0.0350661,
"key":"first"
}
]
}
i wanna to print the json-object to with the following form
{"action":"Read","infos":[{"value":0.0350661,"key":"first"}]}
if i use jsonObject.toString() method i will get
{"action":"Read","infos":"[{\"value\":0.0350661,\"key\":\"first\"}]"}
if i use StringEscapeUtils.unescapeJava(jsonObject.toString()) method i will get
{"action":"Read","infos":"[{"value":0.0350661,"key":"first"}]"}
if i use jackson mapper with the following code
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
String jsonString = mapper.writeValueAsString(getDebugInfo())
i will get jsonString as
{"nameValuePairs":{"action":"Read","infos":[{"value":0.0350661,"key":"first"}]}}
is there any solution to get the desired output json-string?
JSON Structure
You have that as an object, that is why quotes are not present there.
In your example, an array object is present, at the Json structure.
Code/Java
While printing at Console, the json body's every Key & Value toString() are referred .
That is why the Double Quotes present, as Strings are getting used!
Here I have tried the below code using GSON library, and it is printing me the correct json as shown above.
public static void main ( String [] args ) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("action", "Read");
JsonArray jsonArr = new JsonArray();
JsonObject jsonObject2 = new JsonObject();
jsonObject2.addProperty("value", 0.0350661);
jsonObject2.addProperty("key", "first");
jsonArr.add(jsonObject2);
jsonObject.add("infos", jsonArr);
String jsonString = jsonObject.toString();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement json = gson.fromJson(jsonString,JsonElement.class);
String jsonInString = gson.toJson(json);
System.out.println(jsonInString);
}
OUTPUT:
{
"action": "Read",
"infos": [
{
"value": 0.0350661,
"key": "first"
}
]
}
Even if I am forming the jsonObject using org.json, and simple printing it using System.out.println(jsonObject.toString()); on console, m getting the result like this.
{"action":"Read","infos":[{"value":0.0350661,"key":"first"}]}
So here, not sure how you have formed your jsonObject.
I have simple json which looks like this :
[
{
"id":"0",
"name":"Bob",
"place":"Colorado",
},
{
"id":"1",
"name":"John",
"place":"Chicago",
},
{
"id":"2",
"name":"Marry",
"place":"Miami",
}
]
What I want is using Java to create list of strings (List<String>) that contains all 'names'. I have some experience using Gson and I think about something like:
Gson gson = new Gson();
String[] stringArray= gson.fromJson(jsonString, " ".class);
The problem with this method is that I should create some POJO class which I didn`t in this case. Is it any way I can achieve it without creating separate class with this 'name' property ?
Using Jackson to parse, and Java 8 Streams API for extracting only the name field; the following may help you:
// Your string
jsonString = "[{ \"id\":\"0\", \"name\":\"Bob\", \"place\":\"Colorado\" }, { \"id\":\"1\", \"name\":\"John\", \"place\":\"Chicago\"}, { \"id\":\"2\", \"name\":\"Marry\", \"place\":\"Miami\" }]";
// using Jackson to parse
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.getTypeFactory();
List<MyInfo> myObjectList = objectMapper.readValue(jsonString, typeFactory.constructCollectionType(List.class, MyInfo.class));
// Java 8 Collections
List<String> nameList = myObjectList.stream().map(MyInfo::getName).collect(Collectors.toList());
Beware, it implies the usage of a MyInfo class representing your a Java class in which Json objects of yours would fit in.
You can use JSONArray to get value from key 'name'. Like this:
JSONArray jSONArray = new JSONArray(yourJson);
List<String> list = new ArrayList<>();
for (int i = 0; i < jSONArray.length(); i++) {
JSONObject object = (JSONObject) jSONArray.get(i);
String value = object.getString("name");
System.out.println(value);
list.add(value);
}
You may try the following code snippet,
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
List<String> ls = new ArrayList<String>();
JSONObject jsonObj = new JSONObject();
JSONArray jsonArr = new JSONArray();
JSONParser jsonParse = new JSONParser();
String str = "[{\"id\": \"0\",\"name\": \"Bob\",\"place\": \"Colorado\"},"
+ "{\"id\": \"1\",\"name\": \"John\",\"place\": \"Chicago\"},"
+ "{\"id\": \"2\",\"name\": \"Marry\",\"place\": \"Miami\"}]";
try {
jsonArr= (JSONArray) jsonParse.parse(str); //parsing the JSONArray
if(jsonArr!=null){
int arrayLength =jsonArr.size(); //size is 3 here
for(int i=0;i<arrayLength;i++){
jsonObj = (JSONObject) jsonParse.parse(jsonArr.get(i).toString());
ls.add(jsonObj.get("name").toString()); //as we need only value of name into the list
}
System.out.println(ls);
}
} catch (ParseException e) {
e.printStackTrace();
}catch(Exception e1){
e1.printStackTrace();
}
As you have array, use JSONArray and used jsonParse to avoid any parsing error.
I have used json-simple API to acheive the above.
Is there a way to just one field from the JSON string? My code is as follows:
Object obj = parser.parse(resp);
System.out.println(obj);
JSONArray array = new JSONArray();
array.add(obj);
JSONObject obj2 = (JSONObject)array.get(0); //Getting NPE here
//Object obj3 = obj2.get("data");
System.out.println("Data: " + obj2.get("data"));
//System.out.println("Email: " + obj3.get("email_address"));
I'm using the following libraries
import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.parser.ParseException;
import org.json.simple.parser.JSONParser;
From the response string resp, I just need data.email_address. I am unable to find a way to do it.
So if this is your input:
{
"data": {
"email_address": "example#example.com"
}
}
You first will need to make it a JSONObject:
JSONObject object = (JSONObject) new JSONParser().parse(json);
And then you can get data, another JSONObject:
JSONObject data = (JSONObject) object.get("data")
And from your data Object you can get email_address:
String email = data.get("email_address").toString();
If your input is an array of users, like this:
{
"users": [
{
"data": {
"email_address": "example#example.com"
}
},
{
"data": {
"email_address": "exapmle2#example2.com"
}
}
]
}
You can get it the same way:
JSONObject object = (JSONObject) new JSONParser().parse(json);
JSONArray users = (JSONArray) object.get("users");
JSONObject user0 = (JSONObject) users.get(0);
JSONObject user0data = (JSONObject) user0.get("data");
String email = user0data.get("email_address").toString();
First parse the whole JSON into an Object. Then get an array called users, from that array, get index 0. From that Object, get data, and then email_address
The other option is to use jsonpath.
Using the same Json blob as Lorant:
{
"data": {
"email_address": "example#example.com"
}
}
You would use the following expression.
$.data.email_address
Or if it was an array, simply.
$.users.[data].email_address
An online tool can be used to experiment and learn the syntax, but if you know xpath it should be somewhat familiar already.
import org.json.JSONObject;
JSONObject json = new JSONObject(record);
json.getString("fieldName"));
I have an example nested json object like below :
{
"payload": {
"id": "1",
"apiResp": {
"apiRespDetails": {
"report": {
"reportId": "reportid1",
"reportDetails": [
{
"code": "1",
"rating": "good"
},
{
"code": "2",
"rating": "bad"
},
{
"code": "3",
"rating": "fair"
}
]
}
}
}
}
}
I only need the report object, I do not need any of its parent object details. What would be the best way to get just that using the Jackson API ?
I have created a Java Class called Report.java with fields reportId (String) and reportDetails(List of ReportDetail ) where ReportDetail is another class with String fields code , rating etc. Do I need to use some Deserializer, JsonTreeParser mechanism?Thanks.
The solution for this is jayway Java implementation for JsonPath.
JsonPath is the json equivalent for the XPath query language for XML.
the query langauge is quite powerful, as can be seen in the examples on the github readme.
Here is a quick demo to get you started:
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import com.jayway.jsonpath.*;
import net.minidev.json.JSONArray;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.*;
public class JsonPathDemo2
{
public static void main(String[] args)
{
// query: search for any report property below root
String jsonPathQuery = "$..report";
try (InputStream is = Files.newInputStream(Paths.get("C://temp/xx.json"))) {
Object parsedContent =
Configuration.defaultConfiguration().jsonProvider().parse(is, StandardCharsets.UTF_8.name());
System.out.println("hasJsonPath? " + hasJsonPath(jsonPathQuery).matches(parsedContent));
Object obj = JsonPath.read(parsedContent, jsonPathQuery);
System.out.println("parsed object is of type " + obj.getClass());
System.out.println("parsed object to-string " + obj);
JSONArray arr = (JSONArray)obj;
System.out.println("first array item is of type " + arr.get(0).getClass());
System.out.println("first array item to-string " + arr.get(0));
} catch (Exception e) {
e.printStackTrace();
}
}
}
output:
hasJsonPath? true
parsed object is of type class net.minidev.json.JSONArray
parsed object to-string [{"reportId":"reportid1","reportDetails":[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]}]
first array item is of type class java.util.LinkedHashMap
first array item to-string {reportId=reportid1, reportDetails=[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]}
Hi found two solutions using jackson fasterxml api.
In the first one you can just use the findValue method on the jsonNode and pass in the string value of property/object you are looking for
String jsonresponse = "above json string";
JsonFactory jsonFactory = new JsonFactory();
JsonParser jp = jsonFactory.createParser(jsonresponse);
jp.setCodec(new ObjectMapper());
JsonNode jsonNode = jp.readValueAsTree();
JsonNode reportNode = jsonNode.findValue("report");
ObjectMapper mapper = new ObjectMapper();
Report report = mapper.convertValue(reportNode, Report.class);
This other solution use JsonToken which travels the json response till you find what you are looking for
JsonFactory factory = new JsonFactory();
factory.setCodec(new ObjectMapper());
JsonParser parser = factory.createParser(jsonresponse);
while(!parser.isClosed()){
JsonToken jsonToken = parser.nextToken();
if(JsonToken.FIELD_NAME.equals(jsonToken)){
String fieldName = parser.getCurrentName();
if("report".equals(fieldName)) {
jsonToken = parser.nextToken();
Report report = parser.readValueAs(Report.class);
} else {
jsonToken = parser.nextToken();
}
}
}