JSON is printed with backslashes - mysql

{"externalQueryDate":"4018-11-23"}
this is my json string, which is in a column of mysql.
I get it with creditRisk.getCreditRiskDataCodeBased()
and in javascript or in swagger, i see with backslashes:
"{\"externalQueryDate\":\"4018-11-23\"}"
I can use JSON.parse in frontend but , i want to solve this is backend.
even
for
StringWriter sw = new StringWriter();
objectMapper.writer().writeValue(sw, creditRisk.getCreditRiskDataTermBased());
it writes this:
"responseCode": "\"{\\\"externalQueryDate\\\":\\\"4018-11-23\\\"}\""
I tried those
objectMapper.readTree(creditRisk.getCreditRiskDataCodeBased()).toString()
and
objectMapper.writer().writeValue(sw, creditRisk.getCreditRiskDataTermBased());
and
#JsonRawValue
#JsonValue
How can i solve this?
In mysql, it is also without slashes

If you want to parse the json string with jackson objectMapper you need to use 'read' and tell it what class to use to create the parsed object from.
So in your case you could do something like
ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"externalQueryDate\":\"4018-11-23\"}";
Map map = objectMapper.readValue(json, Map.class);
System.out.print(map.get("externalQueryDate"));
I've just used a Map here as I don't know what class you're wanting to parse the json into. If you have a class with an externalQueryDate field you can read into that. You could also use #JsonFormat on the field to tell it what the date format is if you want to parse the value straight into a LocalDate field.
I suggest you write a few simple unit tests to get the hang of escaped quotes in strings. It looks like they're causing you some confusion.

Related

Enumerating of JObject of NewtonSoft.Json loses '\' character in C#

I would like to parse json string using JObject.Parse() of NewtonSoft.Json. Assume that the json string is like this:
{"json":"{\"count\":\"123\"}"}
The result of jObject.First.ToString() is "json": "{\"count\":\"123\"}".
The result of jObject["json"].ToString() is {"count":"123"}. Enumerating gets the same result as this.
The testing code I used is like this.
[TestMethod()]
public void JsonParseTest()
{
var json = "{\"json\":\"{\\\"count\\\":\\\"123\\\"}\"}";
var jObject = JObject.Parse(json);
Console.WriteLine($"json : {json}");
Console.WriteLine($"jObject.First.ToString() : {jObject.First}");
Console.WriteLine($"jObject[\"json\"].ToString() : {jObject["json"]}");
}
We can see that enumerating of jObject will lose the character '\'. What is the problem? I would be appreciated for any suggestion :)
EDIT 1
The version of NewtonSoft is 12.0.3 released in 2019.11.09.
The parser isn't loosing anything. There is no literal \ in your example. The backslashes are purely part of the JSON syntax to escape the " inside the string vlue. The value of the key json is {"count":"123"}.
If you want to have backslashes in that value (however I don't see why you would want that), then you need add them, just like you added them in your C# string (C# and JSON happen to have the same escaping mechanism):
{"json":"{\\\"count\\\":\\\"123\\\"}"}
with leads to the C# code:
var json = "{\"json\":\"{\\\\\\\"count\\\\\\\":\\\\\\\"123\\\\\\\"}\"}";

How to split the data of NodeObject in Apache Flink

I'm using Flink to process the data coming from some data source (such as Kafka, Pravega etc).
In my case, the data source is Pravega, which provided me a flink connector.
My data source is sending me some JSON data as below:
{"key": "value"}
{"key": "value2"}
{"key": "value3"}
...
...
Here is my piece of code:
PravegaDeserializationSchema<ObjectNode> adapter = new PravegaDeserializationSchema<>(ObjectNode.class, new JavaSerializer<>());
FlinkPravegaReader<ObjectNode> source = FlinkPravegaReader.<ObjectNode>builder()
.withPravegaConfig(pravegaConfig)
.forStream(stream)
.withDeserializationSchema(adapter)
.build();
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<ObjectNode> dataStream = env.addSource(source).name("Pravega Stream");
dataStream.map(new MapFunction<ObjectNode, String>() {
#Override
public String map(ObjectNode node) throws Exception {
return node.toString();
}
})
.keyBy("word") // ERROR
.timeWindow(Time.seconds(10))
.sum("count");
As you see, I used the FlinkPravegaReader and a proper deserializer to get the JSON stream coming from Pravega.
Then I try to transform the JSON data into a String, KeyBy them and count them.
However, I get an error:
The program finished with the following exception:
Field expression must be equal to '*' or '_' for non-composite types.
org.apache.flink.api.common.operators.Keys$ExpressionKeys.<init>(Keys.java:342)
org.apache.flink.streaming.api.datastream.DataStream.keyBy(DataStream.java:340)
myflink.StreamingJob.main(StreamingJob.java:114)
It seems that KeyBy threw this exception.
Well, I'm not a Flink expert so I don't know why. I've read the source code of the official example WordCount. In that example, there is a custtom splitter, which is used to split the String data into words.
So I'm thinking if I need to use some kind of splitter in this case too? If so, what kind of splitter should I use? Can you show me an example? If not, why did I get such an error and how to solve it?
I guess you have read the document about how to specify keys
Specify keys
The example codes use keyby("word") because word is a field of POJO type WC.
// some ordinary POJO (Plain old Java Object)
public class WC {
public String word;
public int count;
}
DataStream<WC> words = // [...]
DataStream<WC> wordCounts = words.keyBy("word").window(/*window specification*/);
In your case, you put a map operator before keyBy, and the output of this map operator is a string. So there is obviously no word field in your case. If you actually want to group this string stream, you need to write it like this .keyBy(String::toString)
Or you can even implement a customized keySelector to generate your own key.
Customized Key Selector

How can I define a ReST endpoint that allows json input and maps it to a JsonSlurper

I want to write an API ReST endpoint, using Spring 4.0 and Groovy, such that the #RequestBody parameter can be any generic JSON input, and it will be mapped to a Groovy JsonSlurper so that I can simply access the data via the slurper.
The benefit here being that I can send various JSON documents to my endpoint without having to define a DTO object for every format that I might send.
Currently my method looks like this (and works):
#RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> putTest(#RequestBody ExampleDTO dto) {
def json = new groovy.json.JsonBuilder()
json(
id: dto.id,
name: dto.name
);
return new ResponseEntity(json.content, HttpStatus.OK);
}
But what I want, is to get rid of the "ExampleDTO" object, and just have any JSON that is passed in get mapped straight into a JsonSlurper, or something that I can input into a JsonSlurper, so that I can access the fields of the input object like so:
def json = new JsonSlurper().parseText(input);
String exampleName = json.name;
I initially thought I could just accept a String instead of ExampleDTO, and then slurp the String, but then I have been running into a plethora of issues in my AngularJS client, trying to send my JSON objects as strings to the API endpoint. I'm met with an annoying need to escape all of the double quotes and surround the entire JSON string with double quotes. Then I run into issues if any of my data has quotes or various special characters in it. It just doesn't seem like a clean or reliable solution.
I open to anything that will cleanly translate my AngularJS JSON objects into valid Strings, or anything I can do in the ReST method that will allow JSON input without mapping it to a specific object.
Thanks in advance!
Tonya

Why is GSON not parsing these fields properly? (FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)

I have a JSONArray of JSONObjects that I'm trying to parse with GSON. I'm using FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES. It's parsing correctly for most fields (so the FieldNamingPolicy is set correct), but I'm getting null returned for
{
"image_sq_48x48_url": "url1",
"image_sq_64x64_url": "url2",
"image_sq_96x96_url": "url3"
}
with field names
imageSq48x48Url
imageSq64x64Url
imageSq96x96Url
Maybe a better question would be what is the proper camelCase? I have also tried
imageSq48X48Url
imageSq48X48url
If I map with #SerializedName("image_sq_96x96_url") it parses/populates correctly.
Unfortunately those fieldnames in your JSON don't conform to what Gson looks for using that strategy.
If you create a POJO and serialize it, you can see what the issue is:
class MyPojo
{
String imageSq48x48Url = "hi";
}
The resulting JSON from Gson using that strategy is:
{"image_sq48x48_url":"hi"}
It doesn't consider/look at numeric digits as leading indicators / start of a "word".
If you rename the field to:
String imageSq_48x48Url;
It would work with your JSON example and that strategy.
Basically, you either need to create your own class that implements FieldNamingStrategy that will handle those JSON fieldnames the way you want, or do what you're doing with the #SerializedName annotation.

Json dynamic string list

I want to return a list of validation errors from my mvc app to the client side to I can take use of the jquery validation showErrors which takes an object
I can get a list of fields and the the erorr(s) that apply to them in any way that is best suited.
I have tried a few formats already, dictionary and none of these serialise to the correct structure as required by the validation library.
ie.
{"fieldname":"some error for fieldname", "fieldname2": "some error for fieldname2"}
All of my examples seem to serialise into something along the lines of
{"Key": "fieldname", "Value" : "some error for fieldname"}
What is the best way to return my data and how can I get it serialised in the correct way that I need?
I suggest you use Json.NET (it is default JSON serializer for ASP.NET MVC 4 as well) and its JsonWriter:
StringWriter errorsStringWriter = new StringWriter();
JsonWriter errorsJsonWriter = new JsonWriter(jsonStringWriter);
errorsJsonWriter.WriteStartObject();
errorsJsonWriter.WritePropertyName("fieldname");
errorsJsonWriter.WriteValue("some error for fieldname");
errorsJsonWriter.WritePropertyName("fieldname2");
errorsJsonWriter.WriteValue("some error for fieldname2");
...
errorsJsonWriter.WriteEndObject();
errorsJsonWriter.Flush();
You can return JSON generated this way with ContentResult:
return Content(errorsStringWriter.GetStringBuilder().ToString(), "application/json");
UPDATE
Json.NET also supports dynamic JSON through JObject. In that case your code can look like this:
var jsonObject = new JObject();
jsonObject.Add("fieldname", "some error for fieldname");
jsonObject.Add("fieldname2", "some error for fieldname2");
...
Creating ContentResult in this case can look like this:
return Content(jsonObject.ToString(Newtonsoft.Json.Formatting.None), "application/json");