Jackson Json Escaping - json

I created json using Jackson. It is working fine. But while parsing json using jackson i had issues in Escaping trademark symbol. can any one please suggest me how to do escape in json jackson provided library.
Thanks in advance.

Well, basically you don't have to do that. I have written a small test case to show you what I mean:
public class JsonTest {
public static class Pojo {
private final String value;
#JsonCreator
public Pojo(#JsonProperty("value") final String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
#Test
public void testRoundtrip() throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
final String value = "foo ™ bar";
final String serialized = objectMapper.writeValueAsString(new Pojo(value));
final Pojo deserialized = objectMapper.readValue(serialized, Pojo.class);
Assert.assertEquals(value, deserialized.getValue());
}
}
The above illustrates that the trademark symbol can be serialized and deserialized without escaping.
With that being said, to solve your problem make sure that you are reading the input using the correct encoding. The encoding can e.g. be set when opening the URL or opening the file
BufferedReader urlReader = new BufferedReader(
new InputStreamReader(
url.openStream(), "UTF-8"));
BufferedReader in = new BufferedReader(
new InputStreamReader(
new FileInputStream(file), "UTF-8"));
Also, if you wish to escape characters you do that by using the \ character.
From the docs on json.org:
A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

Related

How to convert string Map to JSON string in java?

I have fact an issue related to convert string map to string json with below example
public class Demo {
public static void main(String[] args) throws JsonProcessingException {
String stringRequest = "{A=12, B=23}";
System.out.println(new Gson().toJson(stringRequest));
}
}
```
OUTPUT: "{A\u003d12, B\u003d23}"
Please you help me how can I map this to json string.
It is a bit unclear what actually is your problem but the main thing in your example is that you are serializing a String object to JSON. That is why you get such an output, it is not a presentation of a Map but a String.
However with that string you can easily create a Map which you can then serialize. Not saying there is any point on that unless you want to do some cleaning or so but anyway:
// Check first which kind of types are keys & values
// keys are always Strings and here it seems that values can be Integers
Type type = new TypeToken<Map<String, Integer>>(){}.getType();
// Create the actual map from that string
Map<String, Integer> map = getGson().fromJson(stringRequest, type);
// Serialize the map to the console (added pretty printing here)
System.out.println(new Gson().toJson(map));
and you can see:
{ "A": 12, "B": 23 }

Spring - Return Raw JSON without double serialization

I know there are other posts similar to this, but I haven't found any that help me find a solution for this particular case.
I am trying to return a HashMap<String, Object> from my Controller.
The Object part is a JSON string, but its being double serialized and not returned as a raw JSON string, thus not ending up with extra quotations and escape characters.
Controller function:
#RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public HashMap<String, Object> heartbeat(){
String streamInfo = service.getStreamInfo();
String streamCursorInfo = service.getStreamCursorInfo();
String topicInfo = service.getTopicInfo();
String greeting = "This is a sample app for using Spring Boot with MapR Streams.";
HashMap<String, Object> results = new HashMap();
results.put("greeting", greeting);
results.put("streamInfo", streamInfo);
results.put("streamCursorInfo", streamCursorInfo);
results.put("topicInfo", topicInfo);
return results;
}
Service function:
private String performCURL(String[] command){
StringBuilder stringBuilder = new StringBuilder();
try{
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process p = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line = reader.readLine()) != null){
stringBuilder.append(line);
}
}
catch(Exception e){
LOGGER.error(ExceptionUtils.getRootCauseMessage(e));
}
return stringBuilder.toString();
}
The cURL command I run already returns a raw JSON string. So im just trying to add it to the HashMap to be returned in the heartbeat response.
But every time I run this, my output looks like:
{
"greeting": "This is a sample app for using Spring Boot with MapR Streams.",
"streamCursorInfo": "{\"timestamp\":1538676344564,\"timeofday\":\"2018-10-04 02:05:44.564 GMT-0400 PM\",\"status\":\"OK\",\"total\":1,\"data\":[{\"consumergroup\":\"MapRDBConsumerGroup\",\"topic\":\"weightTags\",\"partitionid\":\"0\",\"produceroffset\":\"44707\",\"committedoffset\":\"10001\",\"producertimestamp\":\"2018-10-03T05:57:27.128-0400 PM\",\"consumertimestamp\":\"2018-09-21T12:35:51.654-0400 PM\",\"consumerlagmillis\":\"1056095474\"}]}",
...
}
If i return only the single string, such as streamInfo then it works fine and doesnt add the extra quotes and escape chars.
Can anyone explain what im missing or need to do to prevent this double serialization?
Instead of returning a HashMap, create an object like this:
public class HeartbeatResult {
private String greeting;
... //other fields here
#JsonRawValue
private String streamCursorInfo;
... //getters and setters here (or make the object immutable by having just a constructor and getters)
}
With #JsonRawValue Jackson will serialize the string as is. See https://www.baeldung.com/jackson-annotations for more info.
streamCursorInfo is a string, not an object => the serialization will escape the " character.
If you are able to return the object containing the data, it will work out of the box. If what you have is just a String, I suggest to serialize it to JsonNode and add it in your response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode streamCursorInfo = objectMapper.readTree(service.getStreamInfo())
results.put("streamCursorInfo", streamCursorInfo);

How to let jackson generate json string using single quote or no quotes?

For example, I want to generate a json string for ng-style:
<th ng-style="{width:247}" data-field="code">Code</th>
But with jackson, the result is:
<th ng-style="{"width":247}" data-field="code">Code</th>
It's not easy to read.
So I want jackson to generate the json string with single quote or no quotes. Is it possible to do this?
If you have control over the ObjectMapper instance, then configure it to handle and generate JSON the way you want:
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
JsonGenerator.Feature.QUOTE_FIELD_NAMES
is deprecated, you can use this instead:
mapper.configure(JsonWriteFeature.QUOTE_FIELD_NAMES.mappedFeature(), false);
mapper.configure(JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES.mappedFeature(), true);
Note that JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES is not deprecated (as of now), the corresponding JsonReadFeature is mentioned here just for completeness.
The simplest and the best option is to use regular expression and update the string value.
The sample code is as listed below.
partNumberList=partNumberList.replaceAll(":", ":\"").replaceAll("}", "\"}");
The complete code is as shown below
public static void main(String[] args) throws JsonParseException, JsonMappingException,
IOException {
TestJack obj = new TestJack();
//var jsonString ='{"it":"Stati Uniti d'America"}';
// jsonString =jsonString.replace("'", "\\\\u0027")
ObjectMapper mapper = new ObjectMapper();
String partNumberList = "[{productId:AS101R}, {productId:09902007}, {productId:09902002}, {productId:09902005}]";
partNumberList = partNumberList.replaceAll(":", ":\"").replaceAll("}", "\"}");
System.out.println(partNumberList);
mapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
List<ProductDto> jsonToPersonList = null;
jsonToPersonList = mapper.readValue(partNumberList, new TypeReference<List<ProductDto>>() {
});
System.out.println(jsonToPersonList);
}

parse JSON with gson and GsonBuilder()

String jsons = "{'appname':'application', 'Version':'0.1.0', 'UUID':'300V', 'WWXY':'310W', 'ABCD':'270B', 'YUDE':'280T'}";
This is my json string. How can i parse it to GsonBuilder() that i will get object back? I try few thinks but none works.
I also read https://sites.google.com/site/gson/gson-user-guide
public class YourObject {
private String appname;
private String Version;
private String UUID;
private String WWXY;
private String ABCD;
private String YUDE;
//getters/setters
}
parse to Object
YourObject parsed = new Gson().fromJson(jsons, YourObject.class);
or
YourObject parsed = new GsonBuilder().create().fromJson(jsons, YourObject.class);
minor test
String jsons = "{'appname':'application', 'Version':'0.1.0', 'UUID':'300V', 'WWXY':'310W', 'ABCD':'270B', 'YUDE':'280T'}";
YourObject parsed = new Gson().fromJson(jsons, YourObject.class);
works well
EDIT
in this case use JsonParser
JsonObject object = new JsonParser().parse(jsons).getAsJsonObject();
object.get("appname"); // application
object.get("Version"); // 0.1.0
JSON uses double quotes ("), not single ones, for strings so the JSON you have there is invalid. That's likely the cause of any issues you're having converting it to an object.

How to deserialize JSON string between JSON.org library using GSON library

I have a problem when using GSON library which is json library from Google. Hope someone can give me some hint.
The problem is when I use the gson.fromJson() function trying to convert a json string to a specified defined class.
The example code:
String jsonStr = "{name:"ABC", countries:["US"]}"; // Some Json string.
Gson gson = new Gson();
Example example = gson.fromJSON(jsonStr, Example.class);
class Example {
// does no have no-arg constructor
private String name;
private Integer age;
private JSONArray keywords; // import org.json.JSONArray;
private JSONArray countries;
// other codes
}
The above code is simplied version of my problem.
The problem is in the fromJson() function. The error message is saying "JsonParseException: Expecting object found ["US"]".
I can not figure out what the problem is. I guess maybe gson does not know how to covert a string to JSONArray. Because in here, JSONArray is from another library(org.json).
I try to figure out in the gson documents. It look like I need to write some "Instance Creator" code.
I am wondering whether another can give me some solution. Thank you.
Just make keywords and countries a java List type. I've never seen org.json mixed with gson. Usually gson replaces org.json it's not meant to be used together.
EDIT:
Small example:
class Example {
private String name;
private Integer age;
private List<String> keywords;
private List<String> countries;
public String toString() {
return new Gson().toJson(this);
}
}