Java: JSONObject.toString() - adding extra space after colon (":" -> ": ") - java

Been googling a while but haven't found anything useful since keywords are too common.
Currently in my Java code method toString() (called on some JSONObject object) produces output like this:
{"key_name":<numerical_value>}
while what I need (due to the fact that parser on the other side of the project is imperfect) is:
{"key_name": <numerical_value>}
The only difference is that extra space after colon. Is there any JSONObject builtin way to do it or do I need some handwritten simple string operation for it?

I can only imagine building a custom JSONStringer. In fact, it could be a JSONWriter built using a StringWriter. Then you override all the value methods to add a space before calling parent class method.
class JSONSpaceStringer extends JSONWriter {
private StringWriter sw;
JSONSpaceStringer(StringWriter sw) {
parent(sw); // initialize parent
this.sw = sw;
}
#Override
public JSONWriter value(long l) throws JSONException {
sw.write(" "); // add an initial space
parent.value(l); // and let parent class do the job...
}
// same for all other value methods
//...
}

use the below code. it will help you to solve the problem.
package com.javamad.utils;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class JsonUtils {
private static Logger logger = Logger.getLogger(JsonUtils.class.getName());
public static <T> T jsonToJavaObject(String jsonRequest, Class<T> valueType)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE,false);
T finalJavaRequest = objectMapper.readValue(jsonRequest, valueType);
return finalJavaRequest;
}
public static String javaToJson(Object o) {
String jsonString = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE,true);
jsonString = objectMapper.writeValueAsString(o);
} catch (JsonGenerationException e) {
logger.error(e);
} catch (JsonMappingException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
}
return jsonString;
}
}

Related

How to read properties file in java, which has value in key-value pair

if properties file contains below type values how to read it directly into map
user={'name':'test','age':'23','place':'london'}.
Thanks in advance!
You can inject values into a Map from the properties file using the #Value annotation like this.
#Value("#{${user}}")
private Map<String, String> user;
Entry in your application.properties must be:
user = {"name":"test","age":"23","place":"London"}
test.properties file
name=test
age=23
place=london
code
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
public class ReadPropertiesFile {
public static void main(String[] args) {
try {
File file = new File("test.properties");
FileInputStream fileInput = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInput);
fileInput.close();
Enumeration enuKeys = properties.keys();
while (enuKeys.hasMoreElements()) {
String key = (String) enuKeys.nextElement();
String value = properties.getProperty(key);
System.out.println(key + ": " + value);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope, this would help.. :)
This will read a property file and put it in Properties object.
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesConfig {
private Properties prop;
private PropertiesConfig() {
super();
init();
}
private static class PropertiesInstance {
private static PropertiesConfig instance = null;
public static PropertiesConfig getInstance() {
if (null == instance) {
instance = new PropertiesConfig();
}
return instance;
}
}
public static PropertiesConfig getInstance() {
return PropertiesInstance.getInstance();
}
private void init() {
prop = new Properties();
try (InputStream input = getClass().getResourceAsStream("/sample_config.properties")) {
// load a properties file
prop.load(input);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public String getProperty(String key) {
return prop.getProperty(key);
}
}
Now you can use any library to convert a value to Map as your value looks like a JSON.
Code example to achieve this through Jackson:
public static Map < String, Object > covertFromJsonToMap(String json) throws JsonTransformException {
try {
return mapper.readValue(json, new TypeReference < HashMap < String, Object >> () {});
} catch (Exception e) {
LOGGER.error("Error " + json, e);
throw new JsonTransformException("Error in json parse", e);
}
}
So something like this will do:
covertFromJsonToMap(PropertiesConfig.getInstance().get("user"));
Looks like you have a JSON representation of your map as a value. Once you read the value as a String in Java you can use Gson to convert it to map
Gson gson = new Gson();
String json = <YOUR_STRING>
Map<String,Object> map = new HashMap<String,Object>();
map = (Map<String,Object>) gson.fromJson(json, map.getClass());

Streaming one JSON object after another having a JSON array in one huge line in the file

I have a problem with huge JSON file (1GB) which contains an array of JSON objects but all of them are in one line. So it looks like...
[{JsonObject1},{JsonObject1},{JsonObject1},...,{JsonObject999999}]
I'm not able to save the content into the memory so I wanted to do this using streaming. I know how to stream line by line but if I have everything in one line only how can I stream JSON object one after another from this one line array?
I tried to browse the internet but I couldn't find anything :(
Using google gson, you can whip up something that operates lazily:
Maintained as a Gist here:
<script src="https://gist.github.com/smac89/bdcb9b08fcdf9d055150824d57ab3513.js"></script>
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.Iterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class ReadJsonFile {
private static final class JsonIterator<T> implements Iterator<T> {
private final Gson gson;
private final Type objectType;
private final JsonReader reader;
private JsonIterator(JsonReader reader, Gson gson, Type objectType) {
this.gson = gson;
this.objectType = objectType;
this.reader = reader;
}
#Override
public boolean hasNext() {
try {
return reader.hasNext();
} catch (IOException ioe) {
return false;
}
}
#Override
public T next() {
return gson.fromJson(reader, objectType);
}
}
public static <J> Stream<J> readJsonFromFile(Gson gson, URL jsonFile, Type type) throws IOException {
JsonReader reader = new JsonReader(
new BufferedReader(new InputStreamReader(jsonFile.openStream())));
reader.beginArray();
if (!reader.hasNext()) {
return Stream.empty();
}
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
new JsonIterator<J>(reader, gson, type), 0), false).onClose(() -> {
try {
reader.close();
} catch (IOException ioe) {
}
});
}
}
data.json
<script src="https://gist.github.com/smac89/15fc3bffa4f965d18587eec2db4972dd.js"></script>

Parsing an empty string with Gson returns null instead of throwing JsonSyntaxException

In order to have Gson throw an exception when it tries to deserialize an empty String, this comment suggests doing
gson.getAdapter(Foo.class).fromJson("")
instead of
gson.fromJson("", Foo.class)
The problem I'm having is that does not work when the gson in question has a custom adapter registered. Can anyone suggest a different workaround to get this unit test to pass:
#Test
public void testEmptyStringBehavior() {
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, new JsonDeserializer<Foo>() {
#Override
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
throw new JsonSyntaxException("Never gets here");
}
}).create();
try {
gson.getAdapter(Foo.class).fromJson("");
fail("Expected JsonSyntaxException");
} catch (JsonSyntaxException | IOException e) {
// Expected.
}
}
better to use jackson, instead of using Gson, it is very easy.
package parse;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonParsing {
public static void main(String[] args) {
String jsonString = "";
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
here i am using empty jsonString, by which it is throwing exception com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input

Write a json file in java

I want to write a json file in java, but it doesn't work, I get this warning:
I want to know how to do this, because I am going to convert a cfg file that is tabbed to json.
Type safety: The method add(Object) belongs to the raw type ArrayList. References to generic type ArrayList<E> should be parameterized
and I have this code:
package json;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class JsonWriter {
public static void main(String[] args) {
JSONObject countryObj = new JSONObject();
countryObj.put("Name", "India");
countryObj.put("Population", new Integer(1000000));
JSONArray listOfStates = new JSONArray();
listOfStates.add("Madhya Pradesh");
listOfStates.add("Maharastra");
listOfStates.add("Rajasthan");
countryObj.put("States", listOfStates);
try {
// Writing to a file
File file=new File("JsonFile.json");
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
System.out.println("Writing JSON object to file");
System.out.println("-----------------------");
System.out.print(countryObj);
fileWriter.write(countryObj.toJSONString());
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I would suggest that you just make a simple ArrayList with your objects, and then serialize them into JSON with a serializer (Using the Jacksoin library in the example below). It would look something like this:
First, define your model in a class (Made without incapsulations for readability):
public class Country{
public String name;
public Integer population;
public List<String> states;
}
Then you can go ahead and create it, and populate the list:
import java.io.File;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class JsonWriter {
public static void main(String[] args) {
Country countryObj = new Country();
countryObj.name = "India";
countryObj.population = 1000000;
List<String> listOfStates = new ArrayList<String>();
listOfStates.add("Madhya Pradesh");
listOfStates.add("Maharastra");
listOfStates.add("Rajasthan");
countryObj.states = listOfStates ;
ObjectMapper mapper = new ObjectMapper();
try {
// Writing to a file
mapper.writeValue(new File("c:\\country.json"), countryObj );
} catch (IOException e) {
e.printStackTrace();
}
}
}

Load an Object using Gson

Forgive me if this is trivial or not possible but I'm having a Monday morning moment here.
I'd like to create a method that implements some methods from the Gson library to loaded some settings Objects. Basically, I have a bunch of different settings objects but I don't want to habe to override the load method for each class to I'd like to have something like:
public class ConfigLoader {
public static void main(final String[] args) {
final ConfigurationSettings loadedConfigSettigs =
load("testSettings.json", ConfigurationSettings.class);
final AlternativeConfigurationSettings alternativeConfigSettigs =
load("testSettings2.json", AlternativeConfigurationSettings .class);
}
public T load(final InputStream inputStream, final Class<T> clazz) {
try {
if (inputStream != null) {
final Gson gson = new Gson();
final BufferedReader reader =
new BufferedReader(new InputStreamReader(inputStream));
return gson.fromJson(reader, clazz);
}
} catch (final Exception e) {
}
return null;
}
}
where I can pass in the InputStream and the class of the object I want to return. Is there a simple way to do this (I don't want to have to create a method for each Class I want to be able to load, nor do I want to have to create a specific loader for each class)?
The following code works (requires Java 1.5 or above):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.google.gson.Gson;
public class ConfigLoader {
public static void main(final String[] args) {
final ConfigurationSettings loadedConfigSettigs = load(new FileInputStream(new File("testSettings.json")),
ConfigurationSettings.class);
final AlternativeConfigurationSettings alternativeConfigSettigs = load(new FileInputStream(new File("testSettings2.json")),
AlternativeConfigurationSettings.class);
}
public static <T> T load(final InputStream inputStream, final Class<T> clazz) {
try {
if (inputStream != null) {
final Gson gson = new Gson();
final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
return gson.fromJson(reader, clazz);
}
} catch (final Exception e) {
}
return null;
}
}

Categories

Resources