Here is how I am trying to convert an object to json String
ObjectNode batch = OBJECT_MAPPER.createObjectNode();
String s = OBJECT_MAPPER.writeValueAsString((triggerCommands.getCommands()));
batch.put("commands", s);
System.out.println("raw String= " + s);
System.out.println("ObjectNode String = " + batch);
Which results in output of;
raw String= [{"cmdid":"a06c00d4-5b8b-4313-a8f3-5663dde0fa5b","type":"test"}]
ObjectNode String = {"commands":"[{\"cmdid\":\"a06c00d4-5b8b-4313-a8f3-5663dde0fa5b\",\"type\":\"test\"}]"}
I am curious to know why the String gets backslash when I add it into as value of ObjectNode. All i want is
ObjectNode String = {"commands":[{"cmdid":"a06c00d4-5b8b-4313-a8f3-5663dde0fa5b","type":"test"}]}
There is a similar question asked here but has no solid answer that worked.
Since you're working in the JsonNode domain, you want Jackson to convert your commands to a JsonNode, not a String. Like this:
ObjectNode batch = OBJECT_MAPPER.createObjectNode();
JsonNode commands = OBJECT_MAPPER.valueToTree(triggerCommands.getCommands());
batch.set("commands", commands);
I just read some sourcecodes toString() method of ObjectNode class, calls a TextNode.appendQuoted then a static method CharTypes.appendQuoted(StringBuilder sb, String content), this adds the ( " ) when the object is writed by toString(), here.. when is found a char " then it adds a backlash.
Since your key(s) is a Object array, if you check ObjectNode.put implementation its doesn't allow you add a key as array so.. it need to be parsed to a String
Note you wont get this.
ObjectNode String = {"commands":[{"cmdid":"a06c00d4-5b8b-4313-a8f3-5663dde0fa5b","type":"test"}]}
because the key it's not with between a " (quotes) and as a I told
ObjectNode doesn't allow you a key of type array.
private String writeUnicodeString() {
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.getNodeFactory().objectNode();
node.put("field1", "Hello World");
return node.toString();
}
This outputs:
{"field1":"Hello World"}
Related
When I serialize String element with \" inside, result is "{\"role\":\"student\", \"userType\":\"techer\"}" How to change result to "{"role":"student", "userType":"techer"}"? Used java, jackson lib.
String value = "{\"role\":\"student\", \"userType\":\"techer\"}";
System.out.println(value); //{"role":"student", "userType":"techer"}
String json2 = new ObjectMapper().writeValueAsString(value);
System.out.println(json2);// "{\"role\":\"student\", \"userType\":\"techer\"}"
While putting syntax like ${var_name:-{}} for a variable ,it returns output as variable value along with extra "}" or if variable value is null then it returns like {}} .. How to get rid of this extra "}"
ClassLoader currentCls=Thread.currentThread().getContextClassLoader();
InputStream template = currentCls.getResourceAsStream("system/CompartmentTerraformTemplate.json");
ObjectMapper _mapper = new ObjectMapper();
JsonNode obj=_mapper.readTree(template);
String templateString = obj.toString();
InputStream data=currentCls.getResourceAsStream("system/RequestSample.json");
HashMap<String,Object> mapRec=_mapper.readValue(data, HashMap.class);
StringSubstitutor sub = new StringSubstitutor(mapRec);
String finalString = sub.replace(templateString);
finalString=finalString.replace("=", ":");
System.out.println(finalString);
}
sample record for map
{
"compartment_id":"ocid1.compartment.oc1..adgnljndfgvbcoasdbffbvovafeooves34r3",
"description":"Testing for handling the JSON TF configuration",
"name":"compt_abhi",
"defined_tags":{"new":"users","Toy":"story"}
}
sample String Template in which value should be replaced
{
"resource":{
"oci_identity_compartment":{
"compt_req":{
"compartment_id":"${compartment_id}",
"description":"${description}",
"name":"${name}",
"defined_tags":"${defined_tags:-{}}",
"freeform_tags":"${freeform_tags:-{}}"
}
}
}
}
JsonNode:
{
name: ["bishal", "jaiswal", "Turtle"],
title: "jaiswal"
}
I want to extract the list of name from jsonNode as a comma separated string in an efficient way:
Output:
nameList ="bishal,jaiswal,Turtle"
Apart from converting the jsonNode of name array to a list & then using the join method to make the comma separated string. Any better way to do this ?
Here is the hack
ObjectMapper objectMapper = new ObjectMapper();
final JsonNode jsonNode = objectMapper.readTree("{\"name\":[\"bishal\",\"jaiswal\",\"Turtle\"],\"title\":\"jaiswal\"}");
final JsonNode name = jsonNode.get("name");
final Iterator<JsonNode> iterator = name.iterator();
StringBuilder s = new StringBuilder();
while (iterator.hasNext()){
final JsonNode next = iterator.next();
if(s.length() > 0){
s.append(",");
}
s.append(next);
}
System.out.println(s.toString());
Hope so it will help you.
You can use Jackson JSON in this case...
Jackson is a very popular and efficient java based library to serialize or map Java objects to JSON and vice versa
For e.g.
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonData); //jsonData is your json string here...
JsonNode names = rootNode.path("name");
Iterator<JsonNode> elements = names.elements();
while(elements.hasNext()){
JsonNode name = elements.next();
System.out.println("Names are = "+name);
}
Please can you let me know if this has solved your problem? Thanks
I'm pretty new to world of jackson, and wanted to read the value of specific field from list of jsons (which is a response body of third-party api).
for a single json, using objectMapper works fine.
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(sampleString);
JsonNode idNode = rootNode.path("id");
System.out.println("id: "+ idNode.asText());
But I want to parse list of jsons (which is a string coming from a response body)
.So for example I receive this body:
[
{
"id":10,
"firstName":"Jack",
"primaryPhone":"9999999999",
"email":"jack#me.com"
},
{
"id":4,
"firstName":"Mark",
"primaryPhone":"9999999991",
"email":"mark#me.com"
},
{
"id":12,
"firstName":"Susaan",
"primaryPhone":"9999999992",
"email":"susan23#me.com"
}
]
I want to read the ids first, and if I find a specific id, return some other info from that block.
For example if id=4, read the firstName and email of that person.
But I'm not sure how to parsee list of json.
Any suggestions/comments is appreciated.
You can try,
JsonNode array = objectMapper.readValue(sampleString, JsonNode.class);
for(int i=0;i<array.length;i++){
JsonNode jsonNode = array.get(i);
JsonNode idNode = jsonNode.get("id");
String id = idNode.asText();
if(id.equals("4")){
JsonNode firstNameNode = jsonNode.get("firstName");
String firstName = firstNameNode.asText();
System.out.println("firstName = " + firstName);
JsonNode emailNode = jsonNode.get("email");
String email = emailNode.asText();
System.out.println("email = " + email);
break;
}
}
You can use Json Path.
So, the query would be something like this:
$[?(#.id == 4)].firstName
You can create a POJO like the one below:
class Record {
private Long id;
private String firstName;
//Getters and setters
}
And deserialise the json into List of these POJOS, e.g.:
ObjectMapper mapper = new ObjectMapper();
List<Record> records = mapper.readValue("", new TypeReference<List<Record>>() { });
Once done, you can filter out the records with stream, e.g.:
List<Record> filtered = records.stream()
.filter(r -> r.getId() = 12)
.collect(Collectors.toList());
I use Jackson library to generate json string like this:
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(model);
and this snipped code for instance generate somtething like this:
{"x" : "This is x", "y" : "This is y"}
but I want to generate something like this:
{'x' : 'This is x', 'y' : 'This is y'}
I mean how can I change the double quote string with single quote string.I try to change code like this:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
String str = objectMapper.writeValueAsString(model);
but this snipped code generate the first one.
and of course I can handle this problem with replace method but I want Jackson library do this for me.
How can I handle this problem?
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); is about allowing single quotes in deserializing (JSON to Objects), not serializing (Objects to JSON) as you want.
In serializing, the issue seems to be with Jackson 1.X's default serializer. Below is the code that Jackson uses to write the String values. As you can see, the double quotes are hard coded and thus unchangeable through configuration:
#Override
public void writeString(String text)
throws IOException, JsonGenerationException
{
_verifyValueWrite("write text value");
if (text == null) {
_writeNull();
return;
}
if (_outputTail >= _outputEnd) {
_flushBuffer();
}
_outputBuffer[_outputTail++] = '"'; // <----------------- opening quote
_writeString(text); // <----------------- string actual value
// And finally, closing quotes
if (_outputTail >= _outputEnd) {
_flushBuffer();
}
_outputBuffer[_outputTail++] = '"'; // <----------------- closing quote
}
To achieve what you want, there are at least two options:
1: Replace the quotes using Regex:
This is a safe approach because Jackson gives the double quotes (") already escaped (\"). All you have to do is escape the single quotes and switch the " around properties names and values:
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(model);
System.out.println("Received.: "+str);
str = str.replaceAll("'", "\\\\'"); // escapes all ' (turns all ' into \')
str = str.replaceAll("(?<!\\\\)\"", "'"); // turns all "bla" into 'bla'
System.out.println("Converted: "+str);
Output:
Received.: {"x":"ab\"c","y":"x\"y'z","z":15,"b":true}
Converted: {'x':'ab\"c','y':'x\"y\'z','z':15,'b':true}
Or 2: User a custom JsonSerializer on every String field
Declare the custom serializer:
public class SingleQuoteStringSerializer extends JsonSerializer<String> {
#Override
public void serialize(String str, JsonGenerator jGen, SerializerProvider sP)
throws IOException, JsonProcessingException {
str = str.replace("'", "\\'"); // turns all ' into \'
jGen.writeRawValue("'" + str + "'"); // write surrounded by single quote
}
}
Use it in the fields you want to single quote:
public class MyModel {
#JsonSerialize(using = SingleQuoteStringSerializer.class)
private String x;
...
And proceed as usual (QUOTE_FIELD_NAMES == false is used to unquote the field names):
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
String str = objectMapper.writeValueAsString(model);
System.out.println("Received.: "+str);
Output:
Received.: {x:'ab"c',y:'x"y\'z',z:15,b:true}
Note: Since you seem to be wanting to embed the JSON into another, this last approach may also require escaping the "s (see x:'ab"c').
Configure ObjectMapper in the following way:
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//this may be what you need
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
Try looking into gson. It would look like this in gson.
House myHouse = new House();
Gson gson = new Gson();
String json = gson.toJson(myHouse);
Done...
http://code.google.com/p/google-gson/
As I said in the comment that's not valid JSON and it doesn't make any sense to escape it. You should handle it in a different way.
You should put that object inside a property.
I think you want to have something like
{"myString":"{\"fake json\":\"foo\"}"}
instead you should have:
{"myString":{"fake json":"foo"}}
That should be the proper way to handle this.