GROOVY I am getting random backslashes when creating JSON file in Folder - java

I am having trouble compiling the JSON file. This is my method (the main method just has the name of the method I am writing this code in it so I did not include the main method in here.)
static void buildJSONFiles() {
String commandJson = "C:/Users/Name/Desktop/docfiles/command_config.json"
def data = [
commands:
JsonOutput.toJson([new Commands(name:"upload", path:"\${BUILTIN_EXE(command)}", includeCommandName: true),
new Commands(name:"file_info", path:"\${BUILTIN_EXE(command)}", includeCommandName: true)])
]
println(data)
def json_str = JsonOutput.toJson(data)
def json_beauty = JsonOutput.prettyPrint(json_str)
File file = new File(commandJson)
file.write(json_beauty)
println(json_str)
}
static class Commands {
String name
String path
boolean includeCommandName
}
my output in the console does come out right like this
[commands:[{"includeCommandName":true,"path":"${BUILTIN_EXE(command)}","name":"upload"},{"includeCommandName":true,"path":"${BUILTIN_EXE(command)}","name":"file_info"}]]
but sending it to the JSON file it comes out like this
{"commands":"[{\"includeCommandName\":true,\"path\":\"${BUILTIN_EXE(command)}\",\"name\":\"upload\"},{\"includeCommandName\":true,\"path\":\"${BUILTIN_EXE(command)}\",\"name\":\"file_info\"}]"}
I understand that JSON backslash is a special character so I expected it to be only around the :"${BUILTIN_EXE(command)} but it is showing up everywhere where I did not even have a backslash.

You don't have "random backslashes", you have double-quoted JSON, since you're using JsonOutput twice. json_str is a string with JSON in it, and then you're wrapping that as a JSON value inside more JSON.

Related

RedisGraph: how to persist properties in data containing BOTH single AND double quotes?

I am testing RedisGraph as a way to store my data which originates from a client as JSON.
The JSON passes through a bean for validation etc and I use Jackson to serialise the bean so the RedisGraph string is in the correct format. For completeness on that formatting step see the sample code at the end.
The data properties might contain sinqle quotes in valid JSON format eg: O'Toole
{ "name" : "Peter O'Toole", "desc" : "An actors actor" }
I can use a formatter as per the code block at the end to get the JSON into a format the RedisGraph command will allow which copes with the single quotes (without me needing to escape the data content - ie it can use what the client sends). eg this works:
GRAPH.QUERY movies "CREATE (:Actor {name:\"Peter O'Toole\", desc:\"An actors actor\", actor_id:1})"
So far, so good.
Now, the problem: I am having trouble with the syntax to persist original JSON where it ALSO contains escaped double quotes. eg:
{ "name" : "Peter O'Toole", "desc" : "An \"actors\" actor" }
I don't want to have to escape or wrap the desc property value because it is already escaped as valid JSON. But then how do I construct the RedisGraph command so it persists the properties using the values it is given? ie containing escaped double quotes.
In other words, this throws a parsing error because of the \" in the desc property.
GRAPH.QUERY movies "CREATE (:Actor {name:\"Peter O'Toole\", desc:\"An \"actors\" actor\", actor_id:1})"
Given it would be quite common to want to persist data containing valid JSON escaped double quotes \" AND unescaped single quotes, there must be a way to do this. eg name and address data.
Any ideas?
Thanks, Murray.
PS: this doesnt work either: it chokes on the embedded ' in O'Toole
GRAPH.QUERY movies "CREATE (:Actor {name:\'Peter O'Toole\', desc:\'an \"actors\" actor\', actor_id:3})"
// \u007F is the "delete" character.
// This is the highest char value Jackson allows and is
// unlikely to be in the JSON (hopefully!)
JsonFactory builder = new JsonFactoryBuilder().quoteChar('\u007F').build();
ObjectMapper objectMapper = new ObjectMapper(builder);
// Set pretty printing of json
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Do not surround property names with quotes. ie { firstName : "Peter" }
objectMapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
// Make a Person
Person person = new Person("Peter", "O'Toole");
// Set the desc property using embedded quotes
person.setDesc("An \"actors\" actor");
// Convert Person to JSON
String json = objectMapper.writeValueAsString(person);
// Now convert your json to escape the double quotes around the string properties:
String j2 = json.replaceAll("\u007F", "\\\\\"");
System.out.println(j2);
This yields:
{
firstName : \"Peter\",
lastName : \"O'Toole\",
desc : \"An \"actors\" actor\"
}
which is in a format Redis GRAPH.QUERY movies "CREATE..." can use (apart from the issue with \"actors\" as discussed above).
OK. The issue was an artefact of trying to test the syntax by entering the commands into RedisInsight directly. As it turns out all one needs to do is to remove the double quotes from the valid json.
So, to be clear, based on normal valid json coming from the client app,
the formatter test is:
ObjectMapper objectMapper = new ObjectMapper();
// (Optional) Set pretty printing of json
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Do not surround property names with quotes. ie { firstname : "Peter" }
objectMapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
// Make a Person
// For this example this is done directly,
// although in the Java this is done using
// objectMapper.readValue(incomingJson, Person.class)
Person person = new Person("Peter", "O'Toole");
// Set the desc property using escaped double quotes
person.setDesc("An \"actor's\" actor");
// Convert Person to JSON without quoted property names
String json = objectMapper.writeValueAsString(person);
System.out.println(json);
yields:
{
firstname : "Peter",
lastname : "O'Toole",
desc : "An \"actor's\" actor"
}
and the command string is consumed by the Vertx Redis:
Vertx vertx = Vertx.vertx();
private final Redis redisClient;
// ...
redisClient = Redis.createClient(vertx);
String cmdStr = "CREATE (:Actor {firstname:"Peter", lastname: "O'Toole", desc:"An \"actor's\" actor", actor_id:1})";
Future<String> futureResponse = redisClient.send(Request.cmd(Command.GRAPH_QUERY).arg("movies").arg(cmdStr))
.compose(response -> {
Log.info("createRequest response=" + response.toString());
return Future.succeededFuture("OK");
})
.onFailure(failure -> {
Log.error("createRequest failure=" + failure.toString());
});
:-)

Java insert text line above specifice text in string from file with string indentation

i have simple text im reading from file and I'm getting its content as string
String pomxml = "c:\\foo\\test.json";
String content = FileUtils.readFileToString(file);
the string content (example) is :
"email_settings": {
"email.starttls.enable":"true",
"email.port":"111",
"email.host":"xxxx",
"email.auth":"true",
}
i like to insert new string above "email.host":"xxxx", only if it finds it.
so it will look like :
"email_settings": {
"email.starttls.enable":"true",
"email.port":"111",
"email.name":"myTest",
"email.host":"xxxx",
"email.auth":"true",
}
My question is how to insert this new line into the string
UPDATE
in this example it is JSON , but it can be also simple text or XML file
so i can't rely on JSON providers
You could try doing a regex replacement here:
String input = "\"email_settings\": {\n \"email.starttls.enable\":\"true\",\n \"email.port\":\"111\",\n \"email.host\":\"xxxx\",\n \"email.auth\":\"true\",\n}";
String output = input.replaceAll("([ ]*\"email.host\":\".*?\")", " \"email.name\":\"myTest\",\n$1");
System.out.println(output);
This prints:
"email_settings": {
"email.starttls.enable":"true",
"email.port":"111",
"email.name":"myTest",
"email.host":"xxxx",
"email.auth":"true",
}
However, if you are dealing with proper JSON content, then you should consider using a JSON parser instead. Parse the JSON text into a Java POJO and then write out with the new field.
content = content.replace("\"email.host\":", "\"email.name\":\"myTest\",\n" + " \"email.host\":");
Or you could look in to libraries which parse json files.

Converting malformed json array string to Java object

I have a malformed json array string which I get from an API call as follows:
[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Processed successfully\"}]\"}]
There is a double quote before open square bracket in the value of Response Msg property.
Is there a way to convert this into Java object ?
What I have tried so far:
I have used Jackson to parse it as follows but it gives error
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new ResponseNameStrategy());
Response[] response = mapper.readValue(strOutput1, Response[].class);
Error: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token
I have also tried using Gson to parse it but it also gives error
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
.create();
Response[] response = gson.fromJson(strOutput1, Response[].class);
Error: Expected BEGIN_ARRAY but was STRING at line 1 column 35 path $[0].ResponseMsg
I have gone through the following links on StackOverflow but none of them has addressed my issue:
How to Convert String Array JSON in a Java Object
Convert a JSON string to object in Java ME?
JSON Array to Java objects
Convert json String to array of Objects
converting 'malformed' java json object to javascript
I think the answer is in the comments, you appear to be trying to solve the issue on the wrong place.
You are receiving json which you wish to parse into java objects, unfortunately the json is malformed so will not parse.
As a general rule you should never be trying to solve the symptom, but should look for the root cause and fix that, it may sound trivial but fixing symptoms leads to messy, unpredictable, and unmaintainable systems.
So the answer is fix the json where it is being broken. If this is something or of your control, while you wait for the fix, you could put a hack in to fix the json before you parse it.
This way you won't compromise your parsing, and only have a small piece of string replacement to remove when the third party has fixed the issue. But do not go live with the hack, it should only be used during development.
As i mentioned in the comment, you should prepare your service response in order to parse it.
I implemented an example:
public class JsonTest {
public static void main(String args[]) throws JsonProcessingException, IOException{
String rawJson =
"[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Processed successfully\"}]\"}]";
String goodJson = "{"+rawJson.split("[{{.}]")[2]+"}";
ObjectMapper mapper = new ObjectMapper();
final ObjectNode node = mapper.readValue(goodJson, ObjectNode.class);
System.out.println("Pretty Print: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));
System.out.println("Just code: " + node.get("Code"));
}
}
Which returns:
This is how I finally solved my issue:
String inputJsonStr = "[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Claim has been added successfully.\"}"
+ "]\"}]";
int indexOfRes = inputJsonStr.indexOf("ResponseMsg");
if(inputJsonStr.substring(indexOfRes+13,indexOfRes+14).equals("\""))
{
inputJsonStr = inputJsonStr.substring(0,indexOfRes+13) + inputJsonStr.substring(indexOfRes+14);
}
int indexOfFirstClosingSquare = inputJsonStr.indexOf("]");
if(inputJsonStr.substring(indexOfFirstClosingSquare+1, indexOfFirstClosingSquare+2).equals("\"")) {
inputJsonStr = inputJsonStr.substring(0, indexOfFirstClosingSquare+1)+inputJsonStr.substring(indexOfFirstClosingSquare+2);
}
Now inputJsonStr contains a valid json array which can be parsed into Java custom object array easily with gson as given in this SO link:
Convert json String to array of Objects

JSON parsing Exception using Jackson - unexpected non-digit at line 1 column 2

I'm kinda getting frustrated after searching and trying around everything my mind came up with...
I try to parse a JSON file into a list or array of MyObject. I found this post Link and played around with the code. But now I always get the same Exception, whatever I do/change in the JSON file.
Exception I get:
SyntaxError: JSON.parse: unexpected non-digit at line 1 column 2 of the JSON data
What I tried:
I reduced the file to just 2 objects not containing some special stuff to make sure it works. It doesnt..
Validating the json file with an online tool
All different types of importing the JSON as object list/array from 1
playing around with the JSON file
Heres the current code for importing
List<MyClass> myObjects = Arrays.asList(mapper.readValue(content, MyClass[].class));
JSON
[
{
"name":"1000.1000",
"maskId":"1000",
"fieldId":"1000",
"i18nKey":"debugLabel_1",
"label":"Logo",
"tooltip":" ---"
},
{
"name":"1000.1000",
"maskId":"1000",
"fieldId":"1000",
"i18nKey":"debugLabel_1",
"label":"Logo",
"tooltip":" ---"
}
]
MyClass
public class MyClass{
String name;
String maskId;
String fieldId;
String i18nKey;
String label;
String tooltip;
public MyClass(String name, String maskId, String fieldId, String i18nKey, String tooltip, String label) {
this.name = name;
this.maskId = maskId;
this.fieldId = fieldId;
this.i18nKey = i18nKey;
this.tooltip = tooltip;
this.label = label;
}
// Getter + Setter
}
Thanks for advices in advance.
It seems that your class expects to receive a number for it's property and sees string.
This should work:
[
{
"name":"1.1",
"maskId":1,
"fieldId":"1",
"i18nKey":"test1",
"label":"Test 1",
"tooltip":"---"
},
{
"name":"1.2",
"maskId":1,
"fieldId":"2",
"i18nKey":"test2",
"label":"Test 2",
"tooltip":"---"
}
]
Gson gson = new GsonBuilder().create();
final String jsonString = gson.toJson(mapper.readValue(content, MyClass[].class);
try this, i think it will work
I solved it... but I still cant tell what the problem was.
I recreated all the files and Classes and nowit works... kinda strange
But thanks for the help!

how to return data in json format to javascript ajax call

I have the following method:
public String getUTResult() throws IOException {
BuildResultParser bp = new BuildResultParser();
BuildResultBean b = bp.getreadFile("C:\\bc.txt");
String str = b.getuTresult();
return str;
Now str variable contains the value as: [0,5,5]
Now I need to pass this value to ajax call in javascript in following format:
unittest
{
fail:0
pass:5
total:5
}
Actually in javascript, I need this data in array format so that I can access each value and do some processing.
Read this : http://hmkcode.com/java-servlet-send-receive-json-using-jquery-ajax/ or any example of converting data to json format.
If your requirement is limited to the example, u can have another function which takes str and creates json data out of it, in the format required by you.

Categories