Could not write JSON: Direct self-reference leading to cycle - java

Getting this error :
nested exception is
com.fasterxml.jackson.databind.JsonMappingException: Direct
self-reference leading to cycle (through reference chain:
com.google.gson.JsonObject["asJsonObject"])
when trying to do this :
restTemplate.postForObject(url_final, convertedObject, Object[].class);
where convertedObject is a JSONObject and urlfinal is a String url.
Payload is:
"data" : [
{"FILENAME":"EEC1.TXT",
"ERRORDESCRIPTION":"FTD-07-INVALID CHARACTER FOUND IN THE FILE.",
"LINENO":3},
{"FILENAME":"SEC1.TXT",
"ERRORDESCRIPTION":"26-FTD-07-INVALID CHARACTER FOUND IN THE FILE.",
"LINENO":447}]
My Code:
JSONObject output = new JSONObject(payload);
JSONArray jsonArray = output.getJSONArray("data");
JSONObject objects = jsonArray.getJSONObject(0);
String fileName = objects.getString("FILENAME");
int lineNumber = objects.getInt("LINENO");
String errordesc = objects.getString("ERRORDESCRIPTION");
String tempor = "{\"activityType\": \"trial.start\",\"aFileName\":\""
+ fileName
+ "\",\"aLINENO\": \""
+ lineNumber
+ "\",\"aREFNO\": \""
+ TxnNo
+ "\", \"aERRORDESCRIPTION\": \""+errordesc+"\"}";
JsonObject convertedObject = new Gson().fromJson(tempor, JsonObject.class);
restTemplate.postForObject(url_final, convertedObject, Object[].class);

In ten lines you mixed up 3 different JSON libraries:
JSONObject comes from org.json.
Gson comes from Google's gson.
restTemplate uses behind the scene Jackson.
You should skip first two and use only Jackson. Above code after changes could look like:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
....
ObjectMapper mapper = JsonMapper.builder().build();
JsonNode output = mapper.readTree(payload);
ArrayNode jsonArray = (ArrayNode)output.get("data");
JsonNode objects = jsonArray.get(0);
String fileName = objects.get("FILENAME").asText();
int lineNumber = objects.get("LINENO").asInt();
String errordesc = objects.get("ERRORDESCRIPTION").asText();
String tempor = "{\"activityType\": \"trial.start\",\"aFileName\":\""
+ fileName
+ "\",\"aLINENO\": \""
+ lineNumber
+ "\",\"aREFNO\": \""
+ TxnNo
+ "\", \"aERRORDESCRIPTION\": \""+errordesc+"\"}";
JsonNode convertedObject = mapper.readTree(tempor);
Since version 2.10.0 you can use JsonMapper.builder().build() but in previous versions you can just create new instance by new ObjectMapper() which is also fine.

Related

How to retrieve json array elements from JSON object in Java?

JSONObject firstObject = (JSONObject) jsonParser.parse(new FileReader(firstNamesPath));
I have this JSONObject, and I want to be able to access elements in the array inside of it. The object opens successfully, I just don't know how to access the array called "firstNames". It is in a file, and the object looks like this.
{
"firstNames": [
"Aaron",
"Abigail",
"Albert",
"Bob"
]
}
Edit: I am using org.json.simple.JSONObject . If this is not recommended, I am more than willing to change it.
There are several ways to retrieve the json array value:
Assume we have a jsonString
jsonString = "{\n" + " \"firstNames\": [ \n" + " \"Aaron\",\n" + " \"Abigail\",\n" + " \"Albert\",\n" + " \"Bob\"\n" + " ]\n" + "}";
(since many classes share similar names, I am using the groupId and artifactId for distinction.)
Simple cases: use generic JSONObjects and JSONArrays.
json-simple (which OP is using) json-simple website, maven :
org.json.simple.parser.JSONParser jsonParser = new org.json.simple.parser.JSONParser();
org.json.simple.JSONObject firstObject = (org.json.simple.JSONObject) jsonParser.parse(jsonString);
org.json.simple.JSONArray jsonArray = (org.json.simple.JSONArray) firstObject.get("firstNames");
System.out.println(jsonArray);
JSON in Java (mentioned in adendrata's answer): JSON-Java doc, maven
org.json.JSONObject secondObject = new org.json.JSONObject(jsonString);
org.json.JSONArray jsonArray2 = secondObject.getJSONArray("firstNames");
System.out.println(jsonArray2);
gson: Gson, maven
com.google.gson.JsonObject thirdObject = com.google.gson.JsonParser.parseString(jsonString).getAsJsonObject();
System.out.println(thirdObject.get("firstNames").getAsJsonArray());
For more complicated use cases, if you'd like to define your own class, and want to deserialize JSON string to your class, then you can use Gson or Jackson:
// Create your own class:
/*
public class YourOwnClass {
private List<String> firstNames;
public List<String> getFirstNames() {
return firstNames;
}
}
*/
Gson gson = new Gson();
YourOwnClass customObject1 = gson.fromJson(jsonString, YourOwnClass.class);
System.out.println(customObject1.getFirstNames());
ObjectMapper mapper = new ObjectMapper();
YourOwnClass customObject2 = mapper.readValue(jsonString, YourOwnClass.class);
System.out.println(customObject2.getFirstNames());
you can use JSONArray to get array type of Json and looping to access each index
example:
JSONArray array = firstObject.getJSONArray("firstNames");
for (int i = 0; i < array.length(); i++) {
System.out.println("Hello i'm " + array.get(i));
}
Try to use this : com.alibaba.fastjson.JSONObject, and here's the dependency:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
Then you can directly use the getJSONArray method the answer shown above.

Java get value by key in JSON data [duplicate]

This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 3 years ago.
[
{
"boylam":31.8039,
"enlem":40.5906,
"il":"",
"ilPlaka":"",
"ilce":"",
"oncelik":0,
"yukseklik":2052,
"aciklama":"",
"modelId":124774,
"gps":0
}]
Hi I have such a JSON data in my hand. I had a hard time getting the data out of here. For example, how do I print the "boylam" option in JSON data?
You can use JSON.simple to convert string data to JSON objects. https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple/1.1.1
public static void main(String[] args) throws ParseException {
String data = "[\n" +
"{\n" +
" \"boylam\":31.8039,\n" +
" \"enlem\":40.5906,\n" +
" \"il\":\"\",\n" +
" \"ilPlaka\":\"\",\n" +
" \"ilce\":\"\",\n" +
" \"oncelik\":0,\n" +
" \"yukseklik\":2052,\n" +
" \"aciklama\":\"\",\n" +
" \"modelId\":124774,\n" +
" \"gps\":0\n" +
"}]";
JSONParser parser = new JSONParser();
JSONArray jsonArray = (JSONArray) parser.parse(data);
JSONObject jsonObject = (JSONObject) jsonArray.get(0);
System.out.println(jsonObject.get("boylam"));
}
Use Google Gson,the code maybe like this:
// construct the json object
JsonArray jsonArray = new JsonArray();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("boylam",31.8039);
jsonArray.add(jsonObject);
// iterate the json array
jsonArray.forEach(jsonElement -> {
JsonObject element = (JsonObject) jsonElement;
System.out.println(element.get("boylam"));
});
using com.google.gson.Gson class, you can do this.
Gson gson= new Gson();
JSONObject json=new JSONObject();
json.put("boylam", "31.8039"); // this is your json object
Map map=gson.fromJson(json.toString(), Map.class);
System.out.println(map.get("boylam")); //ouput 31.8039

how do I convert a String like {key1=value1, key2=value2} into a json String or Jsonobject?

such like this:
{aliSerialNumber=111111, pubmsCode=null, orderNumber=111, orderId=null, queryNo=null, msgId=null, consNo=null, userId=null, instId=null, companyId=null, appId=null, extendMap=null, pageSource=null, aliStatus=null}
convert into like this:
{"aliSerialNumber":"111111" ...}
is there any utils in Java I can use?
ps:The String is not a println result, it is from log:
enter image description here
You can use Gson for this.
here is sample test code to convert your string into Gson based JsonObject and verify if converted json is valid. you can use the relative following code.
#Test
public void checkJson() {
String json = "{aliSerialNumber=111111, pubmsCode=null, orderNumber=111, orderId=null, queryNo=null, msgId=null, consNo=null, userId=null, instId=null, companyId=null, appId=null, extendMap=null, pageSource=null, aliStatus=null}";
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
assertNotNull(jsonObject);
assertEquals(jsonObject.get("aliSerialNumber").getAsInt(),111111);
System.out.print(jsonObject.get("aliSerialNumber"));
}
returns true.
further read about gson here
You can do that without any utils like:
String str = "{aliSerialNumber=111111, pubmsCode=null, orderNumber=111, orderId=null, queryNo=null, msgId=null, consNo=null, userId=null, instId=null, companyId=null, appId=null, extendMap=null, pageSource=null, aliStatus=null}";
str = str.replace("{", "");
str = str.replace("}", "");
String[] temp = str.split(",");
String json = "{";
for (String s : temp)
{
String key = s.split("=")[0].trim();
String val = s.split("=")[1].trim();
json += "\"" + key + "\":";
json += "\"" + val + "\", ";
}
json = json.substring(0, json.length() - 2);
json += "}";
System.out.println(json);
Result is this (valid JSON):
{"aliSerialNumber":"111111", "pubmsCode":"null", "orderNumber":"111", "orderId":"null", "queryNo":"null", "msgId":"null", "consNo":"null", "userId":"null", "instId":"null", "companyId":"null", "appId":"null", "extendMap":"null", "pageSource":"null", "aliStatus":"null"}

extract a json node from the json

how to extract a json node from another json .for example I want to fetch the "Company Name" i.e "kjh".But using this json parser code I am able to fetch the whole json and not only comapnt name..Can somebody help
jsonObject = (JSONObject) new org.json.simple.parser.JSONParser().parse(domainRequest);
final String companyName = (String) jsonObject.get("companyName");
here is the Json content:
{"companyName":{"Company Name:":"kjh","Address 1:":"kjhhkh","Address 2:":"hkjhkj","Address 3:":"hkjhhkj","Address 4:":"kjhj","Postcode:":898,"Default Email Address:":"kkjkh#y","Company Registration No:":98,"VAT No:":89098,"Website":"http://localhost:9000/#/support/domain/request?formLinkUuid=7f000101-4fdf-160d-814f-dfa60dc80000"}}
{"companyName" : {
"Company Name:":"kjh",
"Address 1:":"kjhhkh",
"Address 2:":"hkjhkj",
"Address 3:":"hkjhhkj",
"Address 4:":"kjhj",
"Postcode:":898,
"Default Email Address:":"kkjkh#y","Company Registration No:":98,
"VAT No:":89098,
"Website":"http://localhost:9000/#/support/domain/request?formLinkUuid=7f000101-4fdf-160d-814f-dfa60dc80000"
}}
You missed 1 step, you are actually getting a map (key-value pair), using this map get company name
public static void main(String[] args) throws JSONException {
String domainRequest = "{\"companyName\":{\"Company Name:\":\"kjh\",\"Address 1:\":\"kjhhkh\",\"Address 2:\":\"hkjhkj\",\"Address 3:\":\"hkjhhkj\",\"Address 4:\":\"kjhj\",\"Postcode:\":898,\"Default Email Address:\":\"kkjkh#y\",\"Company Registration No:\":98,\"VAT No:\":89098,\"Website\":\"http://localhost:9000/#/support/domain/request?formLinkUuid=7f000101-4fdf-160d-814f-dfa60dc80000\"}}";
JSONObject jsonObject = new JSONObject(domainRequest);
JSONObject jsonMap = (JSONObject) jsonObject.get("companyName"); // Generates HashMap, key-value pair
String companyName = (String) jsonMap.get("Company Name:"); // from map prepared above get key value
System.out.println(companyName);
}
Output
kjh
It is weird your json format. You should be check it out.
Remove colon from children property name.
String json =
"{\"companyName\" : {\n" +
" \"Company Name:\":\"kjh\",\n" +
" \"Address 1:\":\"kjhhkh\",\n" +
" \"Address 2:\":\"hkjhkj\",\n" +
" \"Address 3:\":\"hkjhhkj\",\n" +
" \"Address 4:\":\"kjhj\",\n" +
" \"Postcode:\":898,\n" +
" \"Default Email Address:\":\"kkjkh#y\",\"Company Registration No:\":98,\n" +
" \"VAT No:\":89098,\n" +
" \"Website\":\"http://localhost:9000/#/support/domain/request?formLinkUuid=7f000101-4fdf-160d-814f-dfa60dc80000\"\n" +
" }}";
JsonElement jsonElement = new Gson().fromJson(json, JsonElement.class);
String companyName = jsonElement.getAsJsonObject().get("companyName").getAsJsonObject().get("Company Name:").getAsString();
System.out.println(companyName);

How to generate JSON string in Java using net.sf.json?

I am struggling to generate JSON String in Java.
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
JSONArray ja = new JSONArray();
JSONObject js = new JSONObject();
JSONObject j = new JSONObject();
String s = "[{\"shakil\",\"29\",\"7676\"}]";
js.put("id", "1");
js.put("data", s);
ja.add(js);
j.put("rows", ja);
System.out.println(j.toString());
actual output:
{"rows":[{"id":"2","data":"[{\"shakil\",\"29\",\"7676\"}]"}]}
expected output:
{"rows":[{"id":"2","data":["shakil", "29","7676"]}]};
Your s is a String which is not unquoted when put into a JSONObject. You must build another JSONArray for the value of data:
// using http://jettison.codehaus.org/
JSONObject outerObject = new JSONObject();
JSONArray outerArray = new JSONArray();
JSONObject innerObject = new JSONObject();
JSONArray innerArray = new JSONArray();
innerArray.put("shakil");
innerArray.put("29");
innerArray.put("7676");
innerObject.put("id", "2");
innerObject.put("data", innerArray);
outerArray.put(innerObject);
outerObject.put("rows", outerArray);
System.out.println(outerObject.toString());
Result:
{
"rows": [
{
"id": "2",
"data": [
"shakil",
"29",
"7676"
]
}
]
}
Write
String[] s = new String[] {"shakil", "29" , "7676"};
instead of
String s = "[{\"shakil\",\"29\",\"7676\"}]";
Check out gson, it'll provide you with a whole lot of options for serializing/deserializing your Java objects to/from JSON.
Example taken from the page
Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};
//(Serialization)
gson.toJson(ints); ==> prints [1,2,3,4,5]
gson.toJson(strings); ==> prints ["abc", "def", "ghi"]
//(Deserialization)
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
Finally found answer for net.sf.json
JSONArray data1 = new JSONArray();
data1.add("shakil");
data1.add("29");
data1.add("100");
JSONObject inner1 = new JSONObject();
inner1.put("id", "1");
inner1.put("data", data1);
JSONArray list2 = new JSONArray();
list2.add(inner1);
JSONObject finalObj = new JSONObject();
finalObj.put("rows", list2);
System.out.println(finalObj);
Not being able to declare a JSON string in Java is huge pain. Mainly due to (a) no multiline strings (b) escaping double quotes makes it a mess wrt readability.
I work around this by using single quotes to declare the JSON string (using the standard multiline concatenation). Nothing fancy:
String jsonStr =
"{" +
"'address': " +
"{" +
"'name': '" + name + "'," +
"'city': '" + city + "'," +
"'street1': '"+ street1 +"'," +
"'street2': '"+ street2 +"'," +
"'zip': '" + zip + "', " +
"'state':'" + state + "'," +
"'country': '" + country + "'," +
"'phone': '" + phone + "'" +
"}" +
"}";
jsonStr = MyUtil.requote(jsonStr);
System.out.println(jsonStr);
MyUtil
public static String requote(String jsonString) {
return jsonString.replace('\'', '"');
}
Some might find this more cumbersome than declaring a Map but this works for me when I have to build a JSON with just string syntax.
I see a lot of problems when writing a json as String directly without using a Objectmapper or similar.
I would suggest you to write your Json (as you defined it):
{"rows":[{"id":"2","data":["shakil", "29","7676"]}]}
and then simply use this little online tool: http://www.jsonschema2pojo.org/
Which can convert a simply Json a Java-Class also with multiple classes. You can there choose during generation if you want to use Gson or Jackson later.
Gson is a little bit lightweighter and may is better for beginning. I prefer Jackson because you can create something like a computed property - but that's already to much detail.
https://code.google.com/p/google-gson/
After adding Gson all you need to do is:
Gson gson = new Gson();
MyGeneratedClass target = new MyGeneratedClass();
String json = gson.toJson(target);
As voila: you have generated a simple json without thinking about how to change it later!

Categories