Reputation: 2093
I need to extract a field from a JSON object as a substring with exactly the same formatting and all whitespaces preserved.
For example when I have this object:
{
"body":
{
"name": "John",
"surname": "Smith"
},
"signature": "message_signature"
}
I need to extract the field body
as an exact sub-string.
So the result should look like this:
{
"name": "John",
"surname": "Smith"
}
I cannot use a standard JSON library such as Jackson, because it parses the JSON into a tree structure and the formatting is lost. I need some library which would be able to return the original sub-string for any given node.
The reason why I need this is to verify the message signature, which takes into account all the whitespaces (it's a 3rd-party API, can't do anything about that).
Upvotes: 0
Views: 148
Reputation: 133
You can achieve this with Jackson by writing a custom deserializer for your body property. In the deserializer you would then extract the value raw between the starting "{" and ending "}".
See a showcase here (ignoring proper error/edge case handling):
public class App {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
var json = """
{
"body":
{
"name": "John",
"surname": "Smith"
},
"signature": "message_signature"
}
""";
var om = new ObjectMapper();
System.out.println(om.readValue(json, Data.class));
}
public static class BodyDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
var startBody = (int) jp.getCurrentLocation().getCharOffset();
jp.skipChildren();
var endBody = (int) jp.getCurrentLocation().getCharOffset();
var rawJson = jp.getCurrentLocation().getSourceRef().toString();
return rawJson.substring(startBody - 1, endBody);
}
}
public static class Data {
@JsonProperty("body")
@JsonDeserialize(using = BodyDeserializer.class)
public String body;
@JsonProperty("signature")
public String signature;
@Override
public String toString() {
return "Data [body=" + body + ", signature=" + signature + "]";
}
}
}
Upvotes: 1