I have a question on how would be the best way to get the information from a string but that has JSON format.
{
"internal_id":"1234",
"moreInformation":"Failed authentication for user."
}
In this case, I want to get the value of "internal_id" and I already did, with subtring, lastIndexOf and indexOf
public static String returnInternalCode(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length() - 1);
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
I also tried several JSONs with order changes that don't have the data and it also worked. I leave the full class of tests I did:
public class Test {
public static void main(String[] args) {
// Original JSON
String json = "{\"internal_id\":\"999999\",\"moreInformation\":\"Failed authentication for user, 1 authentication attempt remaining.\"}";
// Other JSON order
String json2 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\", \"moreInformation2\":\"Failed authentication for user. \", \"internal_id\":\"45678\"}";
// JSON without the internal_id
String json3 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\"}";
// JSON without moreInformation
String json4 = "{\"internal_id\":\"999999\"}";
System.out.println("JSON: ".concat(json4));
System.out.println("internalId: " + returnInternalId(json4));
System.out.println("moreInformation: " + returnMoreInformation(json4));
}
public static String returnInternalId(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length());
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
public static String returnMoreInformation(String json){
String moreInformation = (json.substring(json.lastIndexOf("\"moreInformation\":\"") + "\"moreInformation\":\"".length(), json.length()));
if (json.lastIndexOf("\"moreInformation\":\"") == -1) return null;
return moreInformation.substring(0, moreInformation.indexOf("\""));
}
}
I would like to know if there are better ways to do what I did, such as with StringBuilder or StringBuffer and also to find out which way uses less memory or is faster to run, how do I know that? How long does it take to execute a method?
Thank you very much!
You can extract the values this way; Using Simple-json library
JSONObject jobj = (JSONObject) parser.parse(yourJsonString); // Pass the Json formatted String
String internal_id = (String) jobj.get("internal_id"); // Extract the value from your key
System.out.println(internal_id); // 1234
I am given three inputs .
A JSON object (nested)
A node structure
key value pair
My task is to append the key value pair to a node by looking at the node structure and updating the original JSON.
For example, if the inputs are,
JSON Object
{
a:
{
b:
{
c:{}
}
}
}
Node structure
a.b.
Key k and value v
The final updated JSON should look like
{
a:
{
b:
{
key:val
c:{}
}
}
}
Please note that the original JSON can be {} also. Then I have to build the whole JSON by looking at the node structure.
Here is my code
making a key value pair
public JSONObject makeEV(String ele, String val) throws JSONException{
JSONObject json =new JSONObject();
json.put(ele, val);
return json;
}
Appending it to JSON
public void modifiedJSON(JSONObject orgJson, String nodeStruct, JSONObject ev) throws JSONException{
JSONObject newJson = new JSONObject();
JSONObject copyJson = newJson;
char last = nodeStruct.charAt(nodeStruct.length()-1);
String lastNode = String.valueOf(last);
int i = 0;
while(orgJson.length() != 0 || i< nodeStruct.length()){
if(orgJson.length() ==0){
if(nodeStruct.charAt(i) == last){
newJson.put(String.valueOf(last), ev.toString());
}else{
newJson.put(String.valueOf(nodeStruct.charAt(i)), "");
}
newJson = newJson.getJSONObject(String.valueOf(nodeStruct.charAt(i)));
}
else if(i >= nodeStruct.length()){
if(orgJson.has(lastNode)){
newJson.put(String.valueOf(last), ev.toString());
}else{
}
}
}
}
I am stuck here. Please help. Thanks in advance.
It could be done using String#split(regex) as next:
public void modifiedJSON(JSONObject orgJson, String nodeStruct,
String targetKey, String value) {
// Split the keys using . as separator
String[] keys = nodeStruct.split("\\.");
// Used to navigate in the tree
// Initialized to the root object
JSONObject target = orgJson;
// Iterate over the list of keys from the first to the key before the last one
for (int i = 0; i < keys.length - 1; i++) {
String key = keys[i];
if (!target.has(key)) {
// The key doesn't exist yet so we create and add it automatically
target.put(key, new JSONObject());
}
// Get the JSONObject corresponding to the current key and use it
// as new target object
target = target.getJSONObject(key);
}
// Set the last key
target.put(targetKey, value);
}
I am looking to test if my json input contains a specific key with a specific value. I used org.joson lib to parse it and test it. I followed a recursive approach.
Is it the best approach to use? or is there a simpler one?
public boolean isJsonContains(String dataKey, String dataValue) {
logger.systemWriteOutput("is JSON data key "+ dataKey + " contains value: " +dataValue,3);
JSONObject jsonObject = null;
if (jsonInput!=null){
jsonObject = new JSONObject(jsonInput);
return isJSONObjectContainsKeyAndValue(dataKey, dataValue,jsonObject );
}
else{
return false;
}
}
private boolean isJSONObjectContainsKeyAndValue (String dataKey, String dataValue, JSONObject object){
String[] keys = JSONObject.getNames(object);
logger.systemWriteOutput("JSONObject is: "+object.toString(),3);
for (String key : keys)
{
boolean result = isJSONKeyContainsValue(key, dataValue, object);
if(result)
return true;
}
logger.systemWriteOutput("no value : "+ dataValue +" has been found for id: " +dataKey,3);
return false;
}
private boolean isJSONKeyContainsValue (String dataKey, String dataValue, JSONObject object){
Object value = object.get(dataKey);
if(dataKey.equals(dataKey) && value.toString().equals(dataValue)){
logger.systemWriteOutput("value of id: " +dataKey+" is: "+value.toString(),3);
return true;
}
else{
logger.systemWriteOutput("value of id: " +dataKey+" is: "+value.toString(),3);
//see if that the nested element contains the id
if (value instanceof JSONArray){
logger.systemWriteOutput("key array is: "+dataKey,3);
JSONArray jsonArray = (JSONArray) object.getJSONArray(dataKey);
logger.systemWriteOutput("key array lenbgth is: "+jsonArray.length(),3);
return isJSONArrayContainsKeyAndValue(dataKey,dataValue, jsonArray);
}
else if (value instanceof JSONObject){
return isJSONObjectContainsKeyAndValue(dataKey, dataValue, object.getJSONObject(dataKey));
}
}
return false;
}
private boolean isJSONArrayContainsKeyAndValue(String dataKey, String dataValue, JSONArray jsonArray) {
boolean result;
logger.systemWriteOutput("jsonArray is: "+jsonArray.toString(),3);
logger.systemWriteOutput("jsonArray length is: "+jsonArray.length(),3);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i);
result= isJSONObjectContainsKeyAndValue(dataKey, dataValue ,jsonobject);
if( result)
return result;
}
return false;
}
Thanks in advance for your help!
The best way to parse JSON is to actually use an existing library, like GSON or JSON. For example, you could use the has method (doc) to find if a given key is present.
If you really want to build your own system, then an iterative approach will allow you to use add parallelism to your system. Other than that, it very usually depends on the problem and the implementation which one is "better". Check this lecture.
My goal is to read a JSON file and understand the location of all the values, so that when I encounter that same JSON, I can easily read all the values. I am looking for a way to return a list containing all of the paths to each data value, in Jayway JsonPath format.
Example JSON:
{
"shopper": {
"Id": "4973860941232342",
"Context": {
"CollapseOrderItems": false,
"IsTest": false
}
},
"SelfIdentifiersData": {
"SelfIdentifierData": [
{
"SelfIdentifierType": {
"SelfIdentifierType": "111"
}
},
{
"SelfIdentifierType": {
"SelfIdentifierType": "2222"
}
}
]
}
}
Ideally I would like to take that JSON as a String and do something like this:
String json = "{'shopper': {'Id': '4973860941232342', 'Context': {'CollapseOrderItems': false, 'IsTest': false } }, 'SelfIdentifiersData': {'SelfIdentifierData': [{'SelfIdentifierType': {'SelfIdentifierType': '111'} }, {'SelfIdentifierType': {'SelfIdentifierType': '2222'} } ] } }";
Configuration conf = Configuration.defaultConfiguration();
List<String> jsonPaths = JsonPath.using(conf).parse(json).read("$");
for (String path : jsonPaths) {
System.out.println(path);
}
This code would print this, which is the location of all values in the JSON:
$.shopper.Id
$.shopper.Context.CollapseOrderItems
$.shopper.Context.IsTest
$.SelfIdentifiersData[0].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
$.SelfIdentifiersData[1].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
Then ideally, I would be able to take that list and parse the same JSON object to get each value present.
//after list is created
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
for (String path : jsonPaths) {
Object value = JsonPath.read(document, path);
//do something
}
I am aware that I could get a Map that is a representation of the JSON file, but I am not sure that provides the same ease of access to retrieve all the values. If there is a easy way to do with JSONPath, that would be great, otherwise any other approaches are welcome.
I came up with a solution, sharing in case anyone else is looking for the same thing:
public class JsonParser {
private List<String> pathList;
private String json;
public JsonParser(String json) {
this.json = json;
this.pathList = new ArrayList<String>();
setJsonPaths(json);
}
public List<String> getPathList() {
return this.pathList;
}
private void setJsonPaths(String json) {
this.pathList = new ArrayList<String>();
JSONObject object = new JSONObject(json);
String jsonPath = "$";
if(json != JSONObject.NULL) {
readObject(object, jsonPath);
}
}
private void readObject(JSONObject object, String jsonPath) {
Iterator<String> keysItr = object.keys();
String parentPath = jsonPath;
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
jsonPath = parentPath + "." + key;
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
}
else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
private void readArray(JSONArray array, String jsonPath) {
String parentPath = jsonPath;
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
jsonPath = parentPath + "[" + i + "]";
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
} else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
}
Refer to this utility : https://github.com/wnameless/json-flattener
Perfect answer to your requirement. Provides Flattened map and Flattened strings for complex json strings.
I am not the author of this but have used it successfully for my usecase.
I'm using json-simple and I need to pretty-print JSON data (make it more human readable).
I haven't been able to find this functionality within that library.
How is this commonly achieved?
Google's GSON can do this in a nice way:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJsonString);
String prettyJsonString = gson.toJson(je);
or since it is now recommended to use the static parse method from JsonParser you can also use this instead:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement je = JsonParser.parseString(uglyJsonString);
String prettyJsonString = gson.toJson(je);
Here is the import statement:
import com.google.gson.*;
Here is the Gradle dependency:
implementation 'com.google.code.gson:gson:2.8.7'
I used org.json built-in methods to pretty-print the data.
import org.json.JSONObject;
JSONObject json = new JSONObject(jsonString); // Convert text to object
System.out.println(json.toString(4)); // Print it with specified indentation
The order of fields in JSON is random per definition. A specific order is subject to parser implementation.
With Jackson (com.fasterxml.jackson.databind):
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject))
From: How to enable pretty print JSON output (Jackson)
I know this is already in the answers, but I want to write it separately here because chances are, you already have Jackson as a dependency and so all you will need would be an extra line of code
It seems like GSON supports this, although I don't know if you want to switch from the library you are using.
From the user guide:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
Using org json. Reference link
JSONObject jsonObject = new JSONObject(obj);
String prettyJson = jsonObject.toString(4);
Using Gson. Reference link
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(obj);
Using Jackson. Reference link
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = mapper.writeValueAsString(obj);
Using Genson. Reference link.
Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);
Using javax.json. Reference link.
Map<String, Boolean> config = new HashMap<>();
config.put(JsonGenerator.PRETTY_PRINTING, true);
JsonWriterFactory writerFactory = Json.createWriterFactory(config);
Writer writer = new StringWriter();
writerFactory.createWriter(writer).write(jsonObject);
String json = writer.toString();
Using Moshi library. Reference link.
String json = jsonAdapter.indent(" ").toJson(emp1);
(OR)
Buffer buffer = new Buffer();
JsonWriter jsonWriter = JsonWriter.of(buffer);
jsonWriter.setIndent(" ");
jsonAdapter.toJson(jsonWriter, emp1);
json = buffer.readUtf8();
If you are using a Java API for JSON Processing (JSR-353) implementation then you can specify the JsonGenerator.PRETTY_PRINTING property when you create a JsonGeneratorFactory.
The following example has been originally published on my blog post.
import java.util.*;
import javax.json.Json;
import javax.json.stream.*;
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jgf.createGenerator(System.out);
jg.writeStartObject() // {
.write("name", "Jane Doe") // "name":"Jane Doe",
.writeStartObject("address") // "address":{
.write("type", 1) // "type":1,
.write("street", "1 A Street") // "street":"1 A Street",
.writeNull("city") // "city":null,
.write("verified", false) // "verified":false
.writeEnd() // },
.writeStartArray("phone-numbers") // "phone-numbers":[
.writeStartObject() // {
.write("number", "555-1111") // "number":"555-1111",
.write("extension", "123") // "extension":"123"
.writeEnd() // },
.writeStartObject() // {
.write("number", "555-2222") // "number":"555-2222",
.writeNull("extension") // "extension":null
.writeEnd() // }
.writeEnd() // ]
.writeEnd() // }
.close();
Pretty printing with GSON in one line:
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(jsonString)));
Besides inlining, this is equivalent to the accepted answer.
My situation is my project uses a legacy (non-JSR) JSON parser that does not support pretty printing. However, I needed to produce pretty-printed JSON samples; this is possible without having to add any extra libraries as long as you are using Java 7 and above:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine scriptEngine = manager.getEngineByName("JavaScript");
scriptEngine.put("jsonString", jsonStringNoWhitespace);
scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
String prettyPrintedJson = (String) scriptEngine.get("result");
Most of the existing answers either depend on some external library, or requiring a special Java version. Here is a simple code to pretty print a JSON string, only using general Java APIs (available in Java 7 for higher; haven't tried older version although).
The basic idea is to tigger the formatting based on special characters in JSON. For example, if a '{' or '[' is observed, the code will create a new line and increase the indent level.
Disclaimer: I only tested this for some simple JSON cases (basic key-value pair, list, nested JSON) so it may need some work for more general JSON text, like string value with quotes inside, or special characters (\n, \t etc.).
/**
* A simple implementation to pretty-print JSON file.
*
* #param unformattedJsonString
* #return
*/
public static String prettyPrintJSON(String unformattedJsonString) {
StringBuilder prettyJSONBuilder = new StringBuilder();
int indentLevel = 0;
boolean inQuote = false;
for(char charFromUnformattedJson : unformattedJsonString.toCharArray()) {
switch(charFromUnformattedJson) {
case '"':
// switch the quoting status
inQuote = !inQuote;
prettyJSONBuilder.append(charFromUnformattedJson);
break;
case ' ':
// For space: ignore the space if it is not being quoted.
if(inQuote) {
prettyJSONBuilder.append(charFromUnformattedJson);
}
break;
case '{':
case '[':
// Starting a new block: increase the indent level
prettyJSONBuilder.append(charFromUnformattedJson);
indentLevel++;
appendIndentedNewLine(indentLevel, prettyJSONBuilder);
break;
case '}':
case ']':
// Ending a new block; decrese the indent level
indentLevel--;
appendIndentedNewLine(indentLevel, prettyJSONBuilder);
prettyJSONBuilder.append(charFromUnformattedJson);
break;
case ',':
// Ending a json item; create a new line after
prettyJSONBuilder.append(charFromUnformattedJson);
if(!inQuote) {
appendIndentedNewLine(indentLevel, prettyJSONBuilder);
}
break;
default:
prettyJSONBuilder.append(charFromUnformattedJson);
}
}
return prettyJSONBuilder.toString();
}
/**
* Print a new line with indention at the beginning of the new line.
* #param indentLevel
* #param stringBuilder
*/
private static void appendIndentedNewLine(int indentLevel, StringBuilder stringBuilder) {
stringBuilder.append("\n");
for(int i = 0; i < indentLevel; i++) {
// Assuming indention using 2 spaces
stringBuilder.append(" ");
}
}
Now this can be achieved with the JSONLib library:
http://json-lib.sourceforge.net/apidocs/net/sf/json/JSONObject.html
If (and only if) you use the overloaded toString(int indentationFactor) method and not the standard toString() method.
I have verified this on the following version of the API:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
Following the JSON-P 1.0 specs (JSR-353) a more current solution for a given JsonStructure (JsonObject or JsonArray) could look like this:
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.json.Json;
import javax.json.JsonStructure;
import javax.json.JsonWriter;
import javax.json.JsonWriterFactory;
import javax.json.stream.JsonGenerator;
public class PrettyJson {
private static JsonWriterFactory FACTORY_INSTANCE;
public static String toString(final JsonStructure status) {
final StringWriter stringWriter = new StringWriter();
final JsonWriter jsonWriter = getPrettyJsonWriterFactory()
.createWriter(stringWriter);
jsonWriter.write(status);
jsonWriter.close();
return stringWriter.toString();
}
private static JsonWriterFactory getPrettyJsonWriterFactory() {
if (null == FACTORY_INSTANCE) {
final Map<String, Object> properties = new HashMap<>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
FACTORY_INSTANCE = Json.createWriterFactory(properties);
}
return FACTORY_INSTANCE;
}
}
In JSONLib you can use this:
String jsonTxt = JSONUtils.valueToString(json, 8, 4);
From the Javadoc:
You can use Gson like below
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gson.toJson(object);
From the post JSON pretty print using Gson
Alternatively, You can use Jackson like below
ObjectMapper mapper = new ObjectMapper();
String perttyStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
From the post Pretty print JSON in Java (Jackson)
Hope this help!
Update: new JsonParser().parse(...) is #deprecated
Based on the javadoc for Gson 2.8.6:
No need to instantiate this class, use the static methods instead.
JsonParser static methods:
JsonParser.parseString(jsonString);
JsonParser.parseReader(reader);
Packages:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
Example:
private Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static String getPerfectJSON(String unformattedJSON) {
String perfectJSON = GSON.toJson(JsonParser.parseString(unformattedJSON));
return perfectJSON;
}
Google Gson dependency using Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
Reference:
JsonParser is deprecated
This worked for me, using Jackson:
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
So I too like the json-simple lib, and looked into pretty printing its output. Unfortunately, while it's an open issue there, I couldn't find any code for it. So I thought I'd give it a try, here's what I came up with (using their own source)..
public class JsonPrinter {
public static String toJson(Map<?,?> map) {
StringBuilder out = new StringBuilder(32);
new JsonPrinter(out).print(map);
return out.toString();
}
public static String toJson(List<?> list) {
StringBuilder out = new StringBuilder(32);
new JsonPrinter(out).print(list);
return out.toString();
}
private final Appendable out;
private final String indentUnit;
private final String newLine;
private int indents;
public JsonPrinter(Appendable out) {
this(out, " ", System.lineSeparator());
}
/**
*
*/
public JsonPrinter(Appendable out, String indentUnit, String newLine) {
this.out = Objects.requireNonNull(out, "null out");
this.indentUnit = Objects.requireNonNull(indentUnit, "null indentUnit");
this.newLine = Objects.requireNonNull(newLine, "null newLine");
if (!indentUnit.isBlank())
throw new IllegalArgumentException(
"indentUnit must be a blank sequence (quoted): '" + indentUnit + "'");
if (!"\r\n".equals(newLine) && ! "\n".equals(newLine))
throw new IllegalArgumentException(
"unrecognized newLine (quoted): '" + newLine + "'");
}
public void print(List<?> list) throws UncheckedIOException {
try {
assert indents == 0;
printImpl(list);
assert indents == 0;
} catch (IOException iox) {
throw new UncheckedIOException("on print(List): " + list, iox);
}
}
public void print(Map<?,?> map) throws UncheckedIOException {
try {
assert indents == 0;
printImpl(map);
assert indents == 0;
} catch (IOException iox) {
throw new UncheckedIOException("on print(Map): " + map, iox);
}
}
protected void printImpl(List<?> list) throws IOException {
if (list == null) {
out.append("null");
return;
}
boolean first = true;
var iter = list.iterator();
open('[');
while (iter.hasNext()) {
if (first)
first = false;
else
out.append(',');
out.append(newLine);
appendIndents();
appendValue(iter.next());
}
close(']');
}
protected void printImpl(Map<?, ?> map) throws IOException {
if (map == null) {
out.append("null");
return;
}
boolean first = true;
var iter = map.entrySet().iterator();
open('{');
while (iter.hasNext()) {
if (first)
first = false;
else
out.append(',');
out.append(newLine);
appendIndents();
var entry = iter.next();
print(entry.getKey().toString(), entry.getValue());
}
close('}');
}
private void open(char c) throws IOException {
out.append(c);
++indents;
}
private void close(char c) throws IOException {
--indents;
out.append(newLine);
appendIndents();
out.append(c);
}
private void appendIndents() throws IOException {
for (int count = indents; count-- > 0; )
out.append(indentUnit);
}
private void print(String key, Object value) throws IOException {
out.append('"');
appendString(key);
out.append('"').append(':').append(' ');
appendValue(value);
}
private void appendString(String s) throws IOException {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch(ch){
case '"':
out.append("\\\"");
break;
case '\\':
out.append("\\\\");
break;
case '\b':
out.append("\\b");
break;
case '\f':
out.append("\\f");
break;
case '\n':
out.append("\\n");
break;
case '\r':
out.append("\\r");
break;
case '\t':
out.append("\\t");
break;
case '/':
out.append("\\/");
break;
default:
//Reference: http://www.unicode.org/versions/Unicode5.1.0/
if ((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')) {
String ss = Integer.toHexString(ch);
out.append("\\u");
for (int k=0; k < 4-ss.length(); k++) {
out.append('0');
}
out.append(ss.toUpperCase());
}
else{
out.append(ch);
}
}
}//for
}
private void appendValue(Object value) throws IOException {
if (value == null) {
out.append("null");
} else if (value instanceof String) {
out.append('"');
appendString(value.toString());
out.append('"');
} else if (value instanceof Double) {
var num = (Double) value;
if (num.isInfinite() || num.isNaN())
out.append("null");
else
out.append(value.toString());
} else if (value instanceof Float) {
var num = (Float) value;
if (num.isInfinite() || num.isNaN())
out.append("null");
else
out.append(value.toString());
} else if (value instanceof Map) {
printImpl((Map<?,?>) value);
} else if (value instanceof List) {
printImpl((List<?>) value);
// } else if (value instanceof Number || value instanceof Boolean) {
// out.append(value.toString());
} else {
out.append(value.toString());
}
}
}
It works for JSONObject and JSONArray even tho it has no dependeny on them.. cuz these are regular Map and List objects resp. (and the fact code was lifted from same lib).
https://github.com/crums-io/io-util/blob/master/src/main/java/io/crums/util/json/JsonPrinter.java
You can use small json library
String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString(" ");
I also use the org.json.simple package. I have simply coded the formatter, but since I don't have nulls, numbers or booleans in my JSON objects in the program that I wrote, I only coded for strings, objects and arrays. If anyone is interested, let this just be in the public domain. You are welcome to add the missing data types (where it says in the comment "it's a string"). Also, you can add the indentation as a parameter whereas mine is just two spaces. Please reshare after you've tested your improvements.
Usage: printJsonObject(jsonObject, "");
Functions:
public static void printJsonObject(JSONObject object, String prefix) {
boolean notFirst = false;
System.out.println(prefix + "{");
for (Object key : object.keySet()) {
if (notFirst) {
System.out.println(", ");
}
notFirst = true;
Object value = object.get(key);
System.out.print(prefix + " " + "\"" + key + "\"" + ": ");
if (value instanceof JSONObject) {
printJsonObject((JSONObject) value, prefix + " ");
} else if (value instanceof JSONArray) {
printJsonArray((JSONArray) value, prefix + " ");
} else { // it's a string
System.out.print("\"" + value + "\"");
}
}
System.out.println("");
System.out.print(prefix + "}");
}
public static void printJsonArray(JSONArray array, String prefix) {
boolean notFirst = false;
System.out.println("[");
for (Object item : array) {
if (notFirst) {
System.out.println(", ");
}
notFirst = true;
if (item instanceof JSONObject) {
printJsonObject((JSONObject) item, prefix + " ");
} else if (item instanceof JSONArray) {
printJsonArray((JSONArray) item, prefix + " ");
} else {
System.out.print(prefix + " " + "\"" + item + "\"");
}
}
System.out.println("");
System.out.print(prefix + "]");
}
This would be a public method to print a pretty version of your object (You need the Gson dependency installed:
import com.google.gson.GsonBuilder;
...
public void printMe(){
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyJSON = gson.toJson(this);
System.out.println(printable);
}
Underscore-java has static method U.formatJson(json).
Five format types are supported: 2, 3, 4, tabs and compact. Live example
import com.github.underscore.U;
import static com.github.underscore.Json.JsonStringBuilder.Step.TABS;
import static com.github.underscore.Json.JsonStringBuilder.Step.TWO_SPACES;
public class MyClass {
public static void main(String args[]) {
String json = "{\"Price\": {"
+ " \"LineItems\": {"
+ " \"LineItem\": {"
+ " \"UnitOfMeasure\": \"EACH\", \"Quantity\": 2, \"ItemID\": \"ItemID\""
+ " }"
+ " },"
+ " \"Currency\": \"USD\","
+ " \"EnterpriseCode\": \"EnterpriseCode\""
+ "}}";
System.out.println(U.formatJson(json, TWO_SPACES));
System.out.println(U.formatJson(json, TABS));
}
}
Output:
{
"Price": {
"LineItems": {
"LineItem": {
"UnitOfMeasure": "EACH",
"Quantity": 2,
"ItemID": "ItemID"
}
},
"Currency": "USD",
"EnterpriseCode": "EnterpriseCode"
}
}
{
"Price": {
"LineItems": {
"LineItem": {
"UnitOfMeasure": "EACH",
"Quantity": 2,
"ItemID": "ItemID"
}
},
"Currency": "USD",
"EnterpriseCode": "EnterpriseCode"
}
}