How can you write raw JSON through Jackson's JsonGenerator? - java

I want to generate a JSON String in the following structure using Jackson API (JsonFactory,JsonGenerator). How can i do it ?
Expected:
{
"api": {
"Salutaion": "Mr",
"name": "X"
},
"additional": {
"Hello",
"World"
}
}
Actual:
{
"api": "{
\"Salutaion\": \"Mr\",
\"name\": \"X\"
}",
"additional": "{
\"Hello\",
\"World\"
}"
}
The values of the attributes api & additional will be available to me as String. Should i be using writeObjectField (as follows) ?
jGenerator.writeObjectField("api", apiString);
After constructing the jGenerator object, how do i get the final constructed JSON Object's String representation ?
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JsonGenerator jGenerator = jfactory.createJsonGenerator(outputStream);
jGenerator.writeStartObject();
jGenerator.writeObjectField("api", apiString);
jGenerator.writeObjectField("additional", additionalString);
jGenerator.writeEndObject();
jGenerator.close();
outputStream.close();
outputStream.toString()
The outputStream.toString() gives a json string but the double quotes (") in the apiString are getting prefixed with an escape character \
Is this the right way ?

Assuming apiString and additionalString are references to String objects with JSON content, you'll want to write them raw, ie. their content directly. Otherwise, you're serializing them as JSON strings and Jackson will need to escape any relevant characters.
For example
jGenerator.writeFieldName("api");
jGenerator.writeRawValue(apiString);
for api, and the same for additional.

Related

How to convert a Response from string to jsonObject?

My response as below and I want to convert it to json object but I don't know how to do it. Could you guide me? Thank you!
Response:
{"m_list": "[{\"contract\":{\"category\":1,\"cor_num\":101,\"contract_name\":\"ABC\"},\"bu_unit\":{\"bu_name\":\"1-1E\"}}]"}
My expected => It'll convert as a json object as below
{ m_list:
[ { contract:
{ category: 1,
cor_num: 101,
contract_name: 'ABC'},
bu_unit: { bu_name: '1-1E' }} ] }
I tried the following way but seem it didn't work
JSONObject jsonObject = new JSONObject(str)
You can use library Josson to restore the JSON object/array from a string inside a JSON.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"{\"m_list\": \"[{\\\"contract\\\":{\\\"category\\\":1,\\\"cor_num\\\":101,\\\"contract_name\\\":\\\"ABC\\\"},\\\"bu_unit\\\":{\\\"bu_name\\\":\\\"1-1E\\\"}}]\"}");
Transformation
JsonNode node = josson.getNode("map(m_list.json())");
System.out.println(node.toPrettyString());
Output
{
"m_list" : [ {
"contract" : {
"category" : 1,
"cor_num" : 101,
"contract_name" : "ABC"
},
"bu_unit" : {
"bu_name" : "1-1E"
}
} ]
}
The string you want to convert is not in the JSON format. From the official documentation of JSON https://www.json.org/json-en.html - it has to start with left brace { , and end with right brace }.
Following the comment from #tgdavies if you get the response from some server, ask for clarification. If you just do this yourself, then this string is the correct format for the json file you want.
{"m_list":[{"contract":{"category":1,"cor_num":101,"contract_name":"ABC"},"bu_unit":{"bu_name":"1-1E"}}]}

Excluding “ when using StringEscapeUtils.escapeHtml4

I am trying to Sanitize the requestBody. For this purpose I am converting Object to Json and then passing the Json to
requestBody
{
"data": {
"id": "123",
"unit_id": "456",
"country": "jp",
}
}
StringEscapeUtils.escapeHtml
Output post escaping:
{"data":{"id":"123","unit_id":"456","country":"jp"}}
It is escaping the double quotes(“) which is breaking the Json structure when I am trying convert the Json back to Object.
How I can exclude double quotes(“) alone during this process?

Improving processing time for mapping one json object to another

I am working on a module where i am getting a JSON response from a RESTful web service. The response is something like below.
[{
"orderNumber": "test order",
"orderDate": "2016 - 01 - 25",
"Billing": {
"Name": "Ron",
"Address": {
"Address1": "",
"City": ""
}
},
"Shipping": {
"Name": "Ron",
"Address": {
"Address1": "",
"City": ""
}
}
}]
This is not the complete response, but only with important elements just to elaborate the issue.
So what i need to do is, convert this JSON response into another JSON that my application understands and can process. Say the below for example.
{
"order_number": "test order",
"order_date": "2016-01-25",
"bill_to_name": "Ron",
"bill_to_address": "",
"bill_to_city": "",
"ship_from_name": "Ron",
"ship_from_Address": "",
"ship_from_city": ""
}
The idea that i had tried was to convert the JSONObject in the response i receive to a hashmap using JACKSON and then use StrSubstitutor to replace the placeholders in my application json with proper values from response json(My Application string with placeholders Shown below).
{"order_number":"${orderNumber}","order_date":"${orderDate}","bill_to_name":"${Billing.name}","bill_to_address":"${Billing.Address}","bill_to_city":"${Billing.City}","ship_from_name":"${Shipping.Name}","ship_from_Address":"${Shipping.Address}","ship_from_city":"${Shipping.City}"}
But the issue i faced was that
JSON to MAP didn't work with nested JSONOBJECT as shown in the response above.
Also to substitute Billing.Name/Shipping.Name etc, even if i extract the Shipping/Billing JSONObjects from the response, when i
would convert them to hashmap, they would give me Name, City,
Address1 as keys and not Billing.Name, Billing.City etc.
So as a solution i wrote the below piece of code which takes the response JSONObject(srcObject) and JSONObject of my application(destObject) as inputs, performs processing and fits in the values from the response JSON into my application JSON.
public void mapJsonToJson(final JSONObject srcObject, final JSONObject destObject){
for(String key : destObject.keys()){
String srcKey = destObject.getString(key)
if(srcKey.indexOf(".") != -1){
String[] jsonKeys = srcKey.split("\\.")
if(srcObject.has(jsonKeys[0])){
JSONObject tempJson
for(int i=0;i<jsonKeys.length - 1;i++){
if(i==0) {
tempJson = srcObject.getJSONObject(jsonKeys[i])
} else{
tempJson = tempJson.getJSONObject(jsonKeys[i])
}
}
destObject.put(key, tempJson.getString(jsonKeys[jsonKeys.length - 1]))
}
}else if(srcObject.has(srcKey)){
String value = srcObject.getString(srcKey)
destObject.put(key, value)
}
}
}
The issue with this piece of code is that it takes some time to process. I want to know is there a way i can implement this logic in a better way with less processing time?
You should create POJOs for your two data types, and then use Jackson's mapper to deserialize the REST data in as the first POJO, and then have a copy constructor on your second POJO that accepts the POJO from the REST service, and copies all the data to its fields. Then you can use Jackson's mapper to serialize the data back into JSON.
Only if the above still gives you performance issues would I start looking at faster but more difficult algorithms such as working with JsonParser/JsonGenerator directly to stream data.
I feel the standard approach will be to use XSLT equivalent for JSON. JOLT seems to be one such implementation. Demo page can be found here. Have a look at it.

GSON : How to convert Object (which itself contains JSON) to JSON

I have a different use case where fields in POJO itself stores JSON data, basically grouping of all data.
Now i want the complete JSON generated from above POJO.
At present i am using this method
private static Gson gson = new Gson();
public static String convertObjectToJSON(Object object) throws Exception {
String jsonResponse = gson.toJson(object);
return jsonResponse;
}
But getting output with escape characters around double quotes like below
{ \"_id\" : 234242, \"name\" : \"carlos\"}
I tried various options in GsonBuilder, but not working.
Basically, i am just grouping multiple JSON data and sending it across.
Could you please do the needful help to get rid of the escape characters around double quotes.
UPDATE:
Question is : I have 3 JSONs and need to combine them into a single JSON and need to pass it to html5 client through Spring MVC. As of now i am added the 3 JSONs into a POJO and trying to convert the same to JSON. Same is explained above.
Thanks & Regards
Venkat
I have tried below sample code and it doesn't have any escape characters around double quotes.
class MyPOJO{
private int _id;
private String name;
// getter & setter
}
String json="{ \"_id\" : 234242, \"name\" : \"carlos\"}";
MyPOJOobj=new Gson().fromJson(json, MyPOJO.class);
System.out.println(new Gson().toJson(obj));
output:
{"_id":234242,"name":"carlos"}
EDIT
If you want to combine 3 JSON string then It will be stored as List of object as illustrated below:
sample code:
String json = "[" +
" { \"_id\" : 1, \"name\" : \"A\"}," +
" { \"_id\" : 2, \"name\" : \"B\"}," +
" { \"_id\" : 3, \"name\" : \"C\"}" +
"]";
Type type = new TypeToken<ArrayList<MyPOJO>>() {}.getType();
ArrayList<MyPOJO> obj = new Gson().fromJson(json, type);
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(obj));
output:
[
{
"_id": 1,
"name": "A"
},
{
"_id": 2,
"name": "B"
},
{
"_id": 3,
"name": "C"
}
]

Converting Nested Json files to CSV in java

{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
This is how my Json file looks .I m required to convert this json to a csv .(I m trying to convert a multi-dimesional data to 2d).I m using gson for my purpose.I cannot use gson.fromgson() function to object map with a template because it should be generic .
I know we can use CDL to convert jsonarray to csv format but It wont work in my case .
my csv format looks like
Employee*
empMID,comment.$,contact.address,contact.freetext,gender
mock:1,,2400 waterview,TRUE,male
mock:123,,2200 waterview,TRUE,female
colA#
TRUE
colB#
FALSE
I tried using google-GSON api to convert to this format .But I m not able to convert to this format .I have used * to represent its a json array and # to represent its a primitive type and contact.address to represent nested array inside another json array .I having problem relating this nested structure .I m able to traverse everything recursively like a column. Thanks in advance
public static void main(String[] args) throws IOException{
BufferedReader reader=null;
StringBuilder content=null;
String result=null;
reader = new BufferedReader(new FileReader("temp.json"));
String line = null;
content= new StringBuilder();
while ((line = reader.readLine()) != null) {
content.append(line);
}
reader.close();
result= content.toString();
JsonElement jelement = new JsonParser().parse(result);
printJsonRecursive(jelement);
}
public static void printJsonRecursive(JsonElement jelement){
if(jelement.isJsonPrimitive()){
System.out.println(jelement.getAsString());
return;
}
if(jelement.isJsonArray()){
JsonArray jarray= jelement.getAsJsonArray();
for(int i=0;i<jarray.size();i++){
JsonElement element= jarray.get(i);
printJsonRecursive(element);
}
return;
}
JsonObject jobject= jelement.getAsJsonObject();
Set<Entry<String, JsonElement>> set= jobject.entrySet();
for (Entry<String, JsonElement> s : set) {
printJsonRecursive(s.getValue());
}
}
}
You can achieve this thru reflection if you have a object mapped to the json.
use gson/jackson to convert json to java object
append fields using reflection by iterating the class and get any field you interested in.
append value with reflection by getting value from the target object.
More detail look at my blog post below:
vcfvct.wordpress.com/2015/06/30/converting-nested-json-files-to-csv-in-java-with-reflection/
You are not printing the key. This should fix it.
for (Entry<String, JsonElement> s : set) {
System.out.println(s.getKey()); //Added
printJsonRecursive(s.getValue());
}
You can take care of \ns from here.
EDIT
If you want to print the keys just once for repeating json objects, create a Java bean to hold the data and populate it during your recursion. Once the bean is complete, add a method there to print all the data in the format you want (printing keys only once and so on).
You can use the library json2flat for converting your JSON to CSV.
This library doesn't require any POJO's. It simply takes your JSON as string and returns a 2D representation of it in the format of List<Object[]>.
For example for the JSON:
{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
It gives an output:
/cola,/colb,/Employee/empMID,/Employee/col1,/Employee/gender,/Employee/contact/address,/Employee/contact/freetext
,,"mock:1","something",,"2400 waterview",true
,,"mock:2","something",,"2200 waterview",true
false,false,,,,,
/**
* Get separated comlumns used a separator (comma, semi column, tab).
*
* #param headers The CSV headers
* #param map Map of key-value pairs contains the header and the value
*
* #return a string composed of columns separated by a specific separator.
*/
private static String getSeperatedColumns(Set<String> headers, Map<String, String> map, String separator) {
List<String> items = new ArrayList<String>();
for (String header : headers) {
String value = map.get(header) == null ? "" : map.get(header).replaceAll("[\\,\\;\\r\\n\\t\\s]+", " ");
items.add(value);
}
return StringUtils.join(items.toArray(), separator);
}

Categories