I'm calling 3rd party API and receiving as a response json:
{\"name\":\"name \\"A\\" and other\",\"id\":1}
If I try to map it like that I'm getting sure that:
Unexpected character ('\' (code 92)): was expecting double-quote to start field name
How could I map it with jackson? Should I remove backslashes with regex? Like every \" -> " and \\" -> \"
That is not well formed. What are you planning to do looks fine
File a bug against whoever is producing this broken output; it is not valid JSON.
{\"name\":\"name A and other\",\"id\":1}, this is the valid form of JSON or
{"name":"name A and other","id":1} it is also valid.
If this is not possible to do it, ask your vendor to validate the JSON structure
Related
In Java, I want to serialize a JSON string containing values such as 12/28 to 12\/28
Using Apache lib StringEscapeUtils and then for serialization, using jackson lib, output comes out as 12\\/28:
Current output:
{
"expiryDate": "12\\/28"
}
However, I want the output to be "12/28"
Desired output:
{
"expiryDate": "12\/28"
}
Any suggestions?
According to the JSON specification (e.g. the syntax graphs at http://json.org), \/ is a valid JSON escape sequence.
However the sequence \/ means the the same thing as /, so there is little point in using \/. (A conformant JSON parser will read it as a /.)
I am not was not aware of any JSON library that will output a / as \/ when serializing data to JSON. However, it appears that json-simple (link, link) always escapes a / as \/:
I don't know why they decided to do that.
The code that implements this behavior is in the method org.json.simple.JSONValue.
On the other hand, I am not aware of a JSON library that won't escape a literal \ in a string when it sees one. (That would be broken, IMO, unless it was part of a design feature for stitching together already formatted JSON string fragments.)
After exploring some options, was able to achieve desired output using below.
Library used:
compile 'com.googlecode.json-simple:json-simple:1.1.1'
Code Sample:
JSONObject jsonObject = new JSONObject();
jsonObject.put("expiryDate", "12/28");
String jsonString = jsonObject.toString();
Output:
{"expiryDate":"12\/28"}
I'm trying to create an MUnit test that mocks an HTTP request by setting the payload to a JSON object that I have saved in a file. In Mule 3 I would have just done getResource('fileName.json').asString() and that worked just fine. In Mule 4 though, I can't statically call getResource.
I found a forum post on the Mulesoft forums that suggested I use MunitTools::getResourceAsString. When I run my test, I do see the JSON object but with all the \n and \r characters as well as a \ escaping all of the quotation marks. Obviously this means my JSON is no longer well formed.
Ideally I would like to find a reference for MunitTools so that I can see a list of functions that I can call and maybe find one that does not add the escape characters, but I haven't had any luck. If anybody knows of a some reference document that I can refer to, please let me know.
Not being able to find a way to return the data without the extra characters, I tried replacing them via dataweave. This is fine when replacing \n and \r, but as there are also more \s in front of each double quote and I can't seem to make these go away.
If I do this...
replace (/\/) with ("")
...I get an error. A co-worker suggested targeting the each \" and replacing them with ", but that's a problem because that gives me """. To get around this, I've tried
replace(/\"/) with "\""
...which does not cause any errors, but for some reason it reads the \ as a literal so it replaces the original string with itself. I've also tried...
replace(/\"/) with '"'
...but that also results in an error
I'm open to any other solutions as well.
Thanks
--Drew
I had the same concern so I started using the readUrl() method. This is a DataWeave method so you should be able to use it in any MUnit processor. Here is an example of how I used it in the set event processor. It reads the JSON file and then converts it into Java for my own needs but you can just replace java with JSON for your needs.
<munit:set-event doc:name="Set Event" doc:id="e7b1da19-f746-4964-a7ae-c23aedce5e6f" >
<munit:payload mediaType="application/java" value="#[output application/java --- readUrl('classpath://singleItemRequest.json','application/json')]"/>
</munit:set-event>
Here is the documentation for readUrl https://docs.mulesoft.com/mule-runtime/4.2/dw-core-functions-readurl
Hope that helps!
Follow this snippet (more specifically the munit-tools:then-return tag):
<munit-tools:mock-when doc:name="Mock GET /users" doc:id="89c8b7fb-1e94-446f-b9a0-ef7840333328" processor="http:request" >
<munit-tools:with-attributes >
<munit-tools:with-attribute attributeName="doc:name" whereValue="GET /users" />
</munit-tools:with-attributes>
<munit-tools:then-return>
<munit-tools:payload value="#[read(MunitTools::getResourceAsString('examples/responses/anypoint-get-users-response.json'), "application/json")]" />
</munit-tools:then-return>
</munit-tools:mock-when>
It mocks an HTTP request and returns a JSON object using the read() function.
I need to write an attribute on a JSON document, and this attribute is an URL
This is my code:
String url = "http://localhost:1028/accumulate";
JSONObject cabecera = new JSONObject();
cabecera.put("reference", url);
But when I create the JSON,this attibute is writted in this way:
"reference":"http:\/\/localhost:1028\/accumulate",
So, the service that receives the JSON String, it's sending me an error:
<subscribeContextResponse>
<subscribeError>
<errorCode>
<code>400</code>
<reasonPhrase>Bad Request</reasonPhrase>
<details>JSON Parse Error: <unspecified file>(1): invalid escape sequence</details>
</errorCode>
</subscribeError>
</subscribeContextResponse>
What is the correct way to write the URL??
Thanks in advance
But when I create the JSON,this attibute is writted in this way:
"reference":"http:\/\/localhost:1028\/accumulate",
That's fine, the backslashes are harmless, whatever you're using to serialize to JSON is just being a bit hyper with its escapes. The string represented by the above contains no backslashes at all, just slashes. \/ inside a JSON string is exactly the same as /, as we can see from the highlighted rule from http://json.org:
("solidus" is a fancy term for slash)
We have a form which has a long paragraph for a scienctific application that contains characters like symbol beta(ß-arrestin) etc. We have a JSON service running on Mule that takes the data and persists to an oracle database. This particular element with long paragraph is giving me an error in RAML/JSON. Below is the error
com.fasterxml.jackson.core.JsonParseException: Illegal unquoted character ((CTRL-CHAR, code 9)): has to be escaped using backslash to be included in string value
The form element to which the scientists write we have no control. So on the Mule side how can we escape these characters automagically like java has URLEncoded. Many Thanks
In your case it looks like the incoming data is malformed. It must be in an encoding supported by the JSON spec: UTF-8 (default), UTF-16, or UTF-32. So not sure if the following is applicable. Nevertheless...
For most apps I would recommend JSON to Object mapping, which will take care of the escaping. Otherwise, you can call Jackson's (the JSON library used by Mule) String escape method directly.
Here's an example that you can use in MEL. String.valueOf is necessary because quoteAsString returns char[]:
<configuration>
<expression-language>
<import class="org.codehaus.jackson.io.JsonStringEncoder" />
<global-functions>
def quoteJSONString(s) {
String.valueOf(JsonStringEncoder.getInstance().quoteAsString(s))
}
</global-functions>
</expression-language>
</configuration>
At the target you can receive the data as text/plain.
Clean it by running :
input.replaceAll("\\p{Cc}", "").
Convert it back to JSON data using any JSON library :
JSONObject inputParams = JSONObject.fromObject(input);
Hope it helps.
I'm trying to put a json in a javascript file in java, but when I write the json to a string, the string doesn't appear to be a valid json for javascript; it is missing some escapes. (This is happening in a string in the json which I formatted as a faux json.)
For example, this would be a valid json in my javascript file:
{
"message":
"the following books failed: [{\"book\": \"The Horse and his Boy\",\"author\": \"C.S. Lewis\"}, {\"book\": \"The Left Hand of Darkness\",\"author\": \"Ursula K. le Guin\"}, ]"
}
Here's what I get, though, where the double quotes aren't escaped:
{
"message":
"The following books failed: [{"book": "The Horse and his Boy","author": "C.S. Lewis"}, {"book": "The Left Hand of Darkness","author": "Ursula K. le Guin"}, ]"
}
I get the second result when I do this:
new ObjectMapper().writer().writeValueAsString(booksMessage);
But when I write it directly to a file with jackson, I get the first, good result:
new ObjectMapper().writer().writeValue(fileToWriteTo, booksMessage);
So why does jackson escape differently when writing to a file, and how do I get it to escape like that for me when writing to a string?
The writeValue() methods of the ObjectWriter class encode the input text.
You don't need to write to a file. An alternative approach for getting the same string could be:
StringWriter sw = new StringWriter();
new ObjectMapper().writer().writeValue(sw, booksMessage);
String result = sw.toString();
I added
booksJson = Pattern.compile("\\\\").matcher(booksJson).replaceAll("\\\\\\\\");
which escapes all the escape characters. That way when I write it to file and it removes the escapes, I still have the escapes I need. So turns out my real question was how to write to file without Java escapes being removed.
I'm very late to the party but I faced a similar problem and I realized it was not a problem with Jackson or my data. It was Java. I was reading from a JSON file and then trying to write it into a template HTML file.
I had a line my original JSON like yours, something like:
{"field" : "This field contains what looks like another JSON field: {\"abc\": \"value\"}"}
And when I wrote the above to a string, the backslash before the quotes in abc and value disappeared. I noticed that the contextual help for String.replaceAll mentioned something about Matcher.quoteReplacement. I went from this:
template = template.replaceAll("%template%", jsonDataString);
to this:
Pattern pattern = Pattern.compile("%template%");
Matcher matcher = Pattern.matcher(template);
matcher.replaceAll(matcher.quoteReplacement(jsonDataString));
Problem solved.
Matcher.quoteReplacement