I have below json, i want to update each and every value of that json but sometimes only one value
{
"msgType": "NEW",
"code": "205",
"plid": "PLB52145",
}
I've already tried to update using below code
FileReader reader = new FileReader(filePath);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
System.out.println(jsonObject);
long id =Long.valueOf((String) idNewObj.get("plid"));
System.out.println(plid);
idNewObj.put("plid",PL809809809);
System.out.println(jsonObject);
To make transformation/filtering of JSON files, I'd suggest to use stream/event-oriented parsing and generating rather than any object mapping. Just an example, which uses simple and lightweight JSON parser https://github.com/anatolygudkov/green-jelly :
import org.green.jelly.AppendableWriter;
import org.green.jelly.JsonEventPump;
import org.green.jelly.JsonParser;
import java.io.StringWriter;
import java.io.Writer;
public class UpdateMyJson {
private static final String jsonToUpdate = "{\n" +
"\"msgType\": \"NEW\",\n" +
"\"code\": \"205\",\n" +
"\"plid\": \"PLB52145\",\n" +
"}";
public static void main(String[] args) {
final StringWriter result = new StringWriter();
final JsonParser parser = new JsonParser();
parser.setListener(new MyJsonUpdater(result));
parser.parse(jsonToUpdate); // if you read a file with a buffer,
// call parse() several times part by part in a loop until EOF
parser.eoj(); // and then call .eoj()
System.out.println(result);
}
static class MyJsonUpdater extends JsonEventPump {
private boolean isPlid;
MyJsonUpdater(final Writer output) {
super(new AppendableWriter<>(output));
}
#Override
public boolean onObjectMember(final CharSequence name) {
isPlid = "plid".contentEquals(name);
return super.onObjectMember(name);
}
#Override
public boolean onStringValue(final CharSequence data) {
if (isPlid) {
if ("PLB52145".contentEquals(data)) {
return super.onStringValue("PL809809809");
}
}
return super.onStringValue(data);
}
}
}
Props:
the file/data doesn't require to be loaded entirely into memory, you can process megs/gigs with no problems
it works much more faster, especially for large files
it's easy to implement any custom type/rule of transformation with this pattern
Both of standard Gson and Jackson libs also provide tokenizers to work with JSON in streaming manner.
UPDATED: JsonEventPump used
You need to write the updated JSON into the file from where JSON was read. Also, I did not understand your variable assignment so I have updated that as well. Use below code:
FileReader reader = new FileReader(filePath);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
System.out.println(jsonObject);
long id =Long.valueOf((String) idNewObj.get("plid"));
System.out.println(id);
jsonObject.put("plid",PL809809809);
System.out.println(jsonObject);
FileWriter writer = new FileWriter(filePath, false); //overwrites the content of file
writer.write(jsonObject.toString());
writer.close();
Related
I have an Object array which is a list of argument values a function could take. This could be any complex object.
I am trying to build a json out of the Object array using gson as below:
private JsonArray createArgsJsonArray(Object... argVals) {
JsonArray argsArray = new JsonArray();
Arrays.stream(argVals).forEach(arg -> argsArray.add(gson.toJson(arg)));
return argsArray;
}
This treats all the arg values as String.
It escapes the String args
"args":["\"STRING\"","1251996697","85"]
I prefer the following output:
"args":["STRING",1251996697,85]
Is there a way to achieve this using gson?
I used org.json, I was able to achieve the desired result, but it does not work for complex objects.
EDIT:
I applied the solution provided by #MichaĆ Ziober, but now how do I get back the object.
Gson gson = new Gson();
Object strObj = "'";
JsonObject fnObj = new JsonObject();
JsonObject fnObj2 = new JsonObject();
fnObj.add("response", gson.toJsonTree(strObj));
fnObj2.addProperty("response", gson.toJson(strObj));
System.out.println(gson.fromJson(fnObj.toString(),
Object.class)); --> prints {response='} //Not what I want!
System.out.println(gson.fromJson(fnObj2.toString(),
Object.class)); --> prints {response="\u0027"}
Use toJsonTree method:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import java.util.Date;
public class GsonApp {
public static void main(String[] args) {
GsonApp app = new GsonApp();
System.out.println(app.createArgsJsonArray("text", 1, 12.2D));
System.out.println(app.createArgsJsonArray(new Date(), new A(), new String[] {"A", "B"}));
}
private Gson gson = new GsonBuilder().create();
private JsonArray createArgsJsonArray(Object... argVals) {
JsonArray argsArray = new JsonArray();
for (Object arg : argVals) {
argsArray.add(gson.toJsonTree(arg));
}
return argsArray;
}
}
class A {
private int id = 12;
}
Above code prints:
["text",1,12.2]
["Sep 19, 2019 3:25:20 PM",{"id":12},["A","B"]]
If you want to end up with a String, just do:
private String createArgsJsonArray(Object... argVals) {
Gson gson = new Gson();
return gson.toJson(argVals);
}
If you wish to collect it back and alter just do:
Object[] o = new Gson().fromJson(argValsStr, Object[].class);
Try using setPrettyPrinting with DisableHtml escaping.
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(jsonArray.toString());
System.out.println( gson.toJson(je));
So I have an object with some fields...
protected String name;
protected String relativePathAndFileName;
protected DateTime next_Run;
protected ArrayList<String> hosts;
Which gets serialized to JSON like this:
public void serialize(){
Gson gson = Converters.registerDateTime(new GsonBuilder()).setPrettyPrinting().create();
String json = gson.toJson(this);
try {
FileWriter writer = new FileWriter(this.relativePathAndFileName);
writer.write (json);
writer.close();
} catch (IOException e) {
logger.error("Error while trying to write myAlert to json: ", e);
}
}
Later when I need to read in this json file, I try to do so like this:
try {
for (File f : alertConfigFiles) {
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(f));
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson(reader, type);
Alert tempAlert = new Alert(myMap);
myAlerts.add(tempAlert);
logger.debug("Imported: " + f.toString());
}
The error that I'm getting is:
Unhandled exception when trying to import config files:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 28 column 13 path $.
The JSON inside the file is something to the effect of:
{
"name": "Logs Per Host - past 24 hours",
"relativePathAndFileName": "./Elk-Reporting/Alerts/logs_per_host24h.json",
"next_Run": "2017-06-07T22:24:56.682-04:00",
"hosts": [
"app-12c",
"app1-18",
"wp-01",
"app-02",
"wp-02",
"cent-04",
"app-06",
"app-05"
]
}
It seems to be choking when it tries to import the ArrayList of hosts, but it was able to write them out without issues.
Can anyone offer some advice on how to get my import working without issues?
try to keep it simple. Using maps and so on, is a way to have issues.
Here is a working code to deserialise / serialise :
package com.rizze.beans.labs.sof;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.google.gson.Gson;
public class SOFGson {
public String json = "{ \"name\": \"Logs Per Host - past 24 hours\", \"relativePathAndFileName\": \"./Elk-Reporting/Alerts/logs_per_host24h.json\", \"next_Run\": \"2017-06-07T22:24:56.682-04:00\", \"hosts\": [ \"bos-qa-app-12c\", \"bos-qa-app1-18\", \"bos-qa-wp-01\", \"bos-lt-app-02\", \"bos-qa-wp-02\", \"bos-dev-cent-04.americanwell.com\", \"bos-qa-app-06\", \"bos-qa-app-05\" ]}";
public class MyObj{
protected String name;
protected String relativePathAndFileName;
protected String next_Run;
protected String[] hosts;
}
#Test
public void test() {
Gson gson = new Gson();
MyObj obj = gson.fromJson(json, MyObj.class);
assertTrue(obj!=null);
assertTrue(obj.hosts.length==8);
System.out.println(gson.toJson(obj));
}
}
here is the class in gist : https://gist.github.com/jeorfevre/7b32a96d4ddc4af68e40bf95f63f2c26
Those two lines seem to be the problem:
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson(reader, type);
You serialize your object of some specific class. You then deserialize it to type. But your JSON does not fit into a Map. Better do it like this, so you can use your own class.
YourClass myMap = gson.fromJson(reader, YourClass.class);
If you want to use this approach, you might want to change your Java class to hold an array of strings instead of an ArrayList of strings.
Maybe this page helps you a bit. Especially the first case fits your situation.
Another option is a custom Deserialzer as described here.
I create a java URL class which contain my Json data and have some function to obtain back my json data for doing some data comparison, I found out it's might not support by JSONObject for passing the data into the JSONObject. Do I need to use JSONArray in my case because my JSON data have array structure as well?
try
{
JSONObject obj = new JSONObject ();
obj.readJsonFromUrl(theUrl);
System.out.println(obj.toString());
}
catch(MalformedURLException e)
{
System.out.print("your problem here ...1");
}
}
else
{
System.out.print("Can't Connect");
}
I am sure that this is the place give me the error message because it return me this error in my compiler
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method readJsonFromUrl(URL) is undefined for the type JSONObject
there are also some warning message for that the JSONObject readJsonFromUrl method
private static JSONObject readJsonFromUrl(URL theUrl) throws IOException, JSONException {
Anyone can provide me the explaination of how the JSON data work in java? I saw quite number of Java class for JSON which make me confuse for it such as JSONObject, JSONArray , JSONValue. I search some information online but I also not very clear about it since I am very new to JSON data processing This is my sample json data and the data I need is scan_result only
{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"file_info":{
"display_name":"",
"file_size":242,
"file_type":"Not available",
"file_type_description":"Not available",
"md5":"aa69ba384f22d0dc0551ace2fbb9ad55",
"sha1":"09ceb54e65df3d3086b222e8643acffe451a6e8a",
"sha256":"dcb46d6ae2a187f789c12f19c44bbe4b9a43bd200a3b306d5e9c1fcf811dc430",
"upload_timestamp":"2016-11-18T09:09:08.390Z"
},
"process_info":{
"blocked_reason":"",
"file_type_skipped_scan":false,
"post_processing":{
"actions_failed":"",
"actions_ran":"",
"converted_destination":"",
"converted_to":"",
"copy_move_destination":""
},
"profile":"File scan",
"progress_percentage":100,
"result":"Allowed",
"user_agent":""
},
"scan_results":{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"progress_percentage":100,
"scan_all_result_a":"No Threat Detected",
"scan_all_result_i":0,
"scan_details":{
"Ahnlab":{
"def_time":"2016-11-08T15:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":1,
"threat_found":""
},
"Avira":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":133,
"threat_found":""
},
"ClamAV":{
"def_time":"2016-11-08T10:28:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":94,
"threat_found":""
},
"ESET":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":38,
"threat_found":""
}
},
"start_time":"2016-11-18T09:09:08.405Z",
"total_avs":4,
"total_time":250
},
"vulnerability_info":{
}
}
As mentioned here, there are many ways to solve this. Either you have to implement the read, parse operations yourself (#Roland Illig 's answer)
//you have to implement the readJSON method
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
Or you could use a library. The most well-known and widely used libraries are jackson and gson.
The big picture is that you try to "map" your json Object to a class.
You have your json file:
{
"id":1,
"name":"eirini",
"hobbies":["music","philosophy","football"]
}
and a class that represents this file and will store the values (depending on the library that you use there might be different requirements, for example getters, setters etc..)
public class Person {
public int id;
public String name;
public List<String> hobbies = new ArrayList<String>();
public String toString() {
return name +" has the id: " + id + " the following hobbies" + hobbies.get(0) + " " + hobbies.get(2);
}
}
Finally in your main method:
public static void main(String[] args) throws IOException, ParseException {
ObjectMapper mapper = new ObjectMapper();
InputStream input = this.getClass().getResourceAsStream(FILE); //read your file. There are many ways to achieve this.
ObjectMapper mapper = new ObjectMapper(); // just need one
Person eirini = mapper.readValue(input, Person.class);
System.out.println(eirini.toString());
You cannot pass json in url, you can pass it in body. Writing Json to stream body and post it using regular java method.
Here is oracle community url of explanation of your problem.
Required Jar can be downloaded from here.
Test Code Follows:
URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
try (InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("data");
for (JsonObject result : results.getValuesAs(JsonObject.class)){
System.out.print(result.getJsonObject("from").getString("name"));
System.out.print(": ");
System.out.println(result.getString("message", ""));
System.out.println("-----------");
}
}
I have the following JSON Array as a string like this,
String output = "[{\"Symbol\":\"AMZN\",\"Name\":\"Amazon.com Inc\",\"Exchange\":\"NASDAQ\"},{\"Symbol\":\"VXAZN\",\"Name\":\"CBOE Amazon VIX Index\",\"Exchange\":\"Market Data Express\"}]";
I want to parse it and make a string array like this,
array = {"AMZN Amazon.com Inc NASDAQ", "VXAZN CBOE Amazon VIX Index Market Data Express"};
I came up with the following code to parse the string into a JSON Array using the json-simple-1.1.1.jar library,
import org.json.simple.*;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class RESTclient {
public static void main(String[] args) {
String output = "[{\"Symbol\":\"AMZN\",\"Name\":\"Amazon.com Inc\",\"Exchange\":\"NASDAQ\"},{\"Symbol\":\"VXAZN\",\"Name\":\"CBOE Amazon VIX Index\",\"Exchange\":\"Market Data Express\"}]";
JSONParser parser = new JSONParser();
JSONArray jsonArray = null;
try {
jsonArray = (JSONArray) parser.parse(output);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(jsonArray);
}
}
This gives me the following OUTPUT,
[{"Name":"Amazon.com Inc","Exchange":"NASDAQ","Symbol":"AMZN"},{"Name":"CBOE Amazon VIX Index","Exchange":"Market Data Express","Symbol":"VXAZN"}]
Now after this, is there an elegant way to achieve my desired output?
You have to write extra code.
ArrayList<String> stringArray = new ArrayList<String>();
for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
JSONObject map = (JSONObject)iterator.next();
stringArray.add(map.get("Symbol")+" "+map.get("Name")+" "+map.get("Exchange"));
}
//stringArray is want you want
You can do it with Jackson like,
private ObjectMapper mapper = new ObjectMapper();
String[] outputArray = mapper.readValue(jsonString, String[].class);
I'm using GSON on my Java EE server to provide some json to views.
In some object, I have long text, that can contains anything (like 'What a "great" news!').
I'm supprised that by default GSON doesn't escape the double quote, so it doesn't generate a valid JSON.
Is there a good way of doing this ?
Maybe I'm not understanding your question, but I was able to get GSON to handle Strings with quotes without any settings or changes.
import com.google.gson.Gson;
public class GSONTest {
public String value;
public static void main(String[] args) {
Gson g = new Gson();
GSONTest gt = new GSONTest();
gt.value = "This is a \"test\" of quoted strings";
System.out.println("String: " + gt.value);
System.out.println("JSON: " + g.toJson(gt));
}
}
Output:
String: This is a "test" of quoted strings
JSON: {"value":"This is a \"test\" of quoted strings"}
Maybe I don't understand what you're asking?
Try using setPrettyPrinting with DisableHtml escaping.
import com.google.gson.Gson;
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(jsonArray.toString());
System.out.println( gson.toJson(je));
Here's some sample GSON code:
final JsonObject obj = new JsonObject();
obj.addProperty("foo", "b\"a\"r");
System.out.println(obj.toString());
The Output is:
{"foo":"b\"a\"r"}
(as it should be)
So either you are doing something wrong, or you are using an ancient version of GSON. Perhaps you should show some of your code?
That is what I did to solve that
private final Gson mGson;
{
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(String.class, new EscapeStringSerializer());
mGson = builder.create();
}
private static class EscapeStringSerializer implements JsonSerializer<String> {
#Override
public JsonElement serialize(String s, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(escapeJS(s));
}
public static String escapeJS(String string) {
String escapes[][] = new String[][]{
{"\\", "\\\\"},
{"\"", "\\\""},
{"\n", "\\n"},
{"\r", "\\r"},
{"\b", "\\b"},
{"\f", "\\f"},
{"\t", "\\t"}
};
for (String[] esc : escapes) {
string = string.replace(esc[0], esc[1]);
}
return string;
}
}