I am trying to create a JSON object in Java. Object structure looks like this:
{
"a" : {
"b" : {
"c" : {
"d" : [ {
"value" : false
} ]
}
},
"id" : "123"
},
"type" : "test"
}
I am using com.fasterxml.jackson.databind.ObjectMapper and usually I just create a corresponding domain objects that can be converted to JSON string using ObjectMapper.writeValueAsString() method.
The problem is that in order to match the JSON structure above I will have to create a bunch of domain objects with only one field and on top of that creating a complete JSON object will involve a lot of boilerplate code just to set 2 or 3 JSIN properties.
I am wondering if there is a better approach that I am not familiar with. Maybe, using JSONPath or another library.
Gson (com.google.gson) allows to register custom Serializer, Deserializers and TypeAdapters, with which you can handle a structure without boilerplate classes. This allows for a better conversion from JSON-DTOs to your actual Domain Objects.
See here for an example: https://www.baeldung.com/gson-deserialization-guide
(I'm also quite interested in additional answers to this question.)
Related
So I need to create an API with Spring Boot to manage different JSON. My problem is that these JSON can and will change in the future their structure, saying something like this:
Today's structure:
{
"name" : "example",
"surname" : "example"
}
Possible future structure:
{
"name" : "example",
"surname" : "example",
"data_array" : [
{
"path": "example"
}
]
}
So, my question is, is there any way to manipulate this kind of JSONs (the "flexible" ones), I don't know if this is possible.
Thank you in advance
Edit.
I don't know if I'm explaining this well enough, right now, to work with those JSONs I need to parse them into an object that I've already created with those fields as parameters. I would like to know if there is a way to not limit those JSONs with a defined object in java.
I have a JSON string as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\",\"createdBy\":{\"userProfileOne\":\"s:pdx\",\"userProfileTwo\":\"sid\",\"domainId\":\"did:pdx-tod-64003\"},\"lastModifiedBy\":{\"userProfileArn\":\"s:pdx-tod-64003\"},\"createdBy\":{\"userProfileOne\":\"s:p\",\"userProfileTwo\":\"si\",\"domainId\":\"did:ppot\"}}}
}
I get this input as a string and before passing it as a string to a parser I need to perform some string filtering and remove all "userProfileOne", "userProfileTwo","domainId" and their keys, without compromising the JSON structure. I am currently writing this code in Java using gson and json.
Note: There are multiple occurences of UserProfileOne, UserProfileTwo and DomainID.
The required Output is as follows:
{
"account": "1234",
"type": "ar-type",
"eventTypes": "Update",
"objectClassName": "com.triype",
"objectJson": "{\"Name\":\"pdpot\",\"traptype\":\"adpot",\"displayName\":\"pdpot",\"experimentName\":\"pdpotpie\",\"creationTime\":\"Mar 18, 2020 5:58:58 PM\"}}
}
Currently I am using substringBetween. But the operation does not work as intended.
A potential approach is to deserialize the json into a java structure then filter this structure by set to null fields you don't want to be serialize.
By using framework like Jackson you can set this before serialization on the ObjectMapper
mapper.setSerializationInclusion(Include.NON_NULL). So all null values won't be serialized in the final json/result.
I think the best maintainable way would be to create a class structure corresponding to that json and map it to the class.
Use #JsonIgnore on the fields to be ignored and then map it back to JSON from the class structure.
Another approach, a bit complex to implement, is to go through each node in the json and remove that node if it's not required
You can also do it by string matching but I don't think that is a good approach.
In a Java/Spring ReST application, I'm using swagger-annotations 1.3.7 I have a number of small classes (for example, GenderCode) that I use as properties in my ReST models. These classes have a single public property, called value. Using Jackson, my APIs can accept a simple String s and construct an instance of, say, GenderCode with its value set to s. Similarly, it can serialize a GenderCode as a simple String (which of course represents the value of value).
I would like my Swagger documentation to represent these objects as simple strings, since that represents what the JSON will look like. Instead it represents an complex type with a "value" key:
{
"genderCode": {
"value": ""
},
...
}
It should look simply like this:
{
"genderCode": "",
...
}
Here's what the Java model would look like:
public class Person {
#JsonProperty("genderCode")
#Valid
#KnownEnumValue
#ApiModelProperty(value = "GenderCode", dataType="string", required = false,
allowableValues=GenderCode.POSSIBLE_VALUES_DISPLAY)
private GenderCode genderCode;
...
}
Here's the definition of that property within the API definition file that Swagger generates:
"genderCode":{"enum":["ANY","M","F"],"description":"GenderCode","required":false,"type":"GenderCode"}
I've tried using an OverrideConverter, but that had no effect. Any thoughts on how this can be done?
At the moment I'm designing a RESTful API and use JAX-RS for the backend. Many reponses have the following simple form:
{
"someList": [
"item1" : ...,
"item2" : ...,
"itemn" : ...
]
}
The important thing is the field name of the array. It's required by the client (EmberJS Data). I try to create the responses with the standard ResponseBuilder, but I don't know how to define a field name for the list. All responses I get look like:
[
"item1" : ...,
"item2" : ...,
"itemn" : ...
]
In the past I just always created a container class with one property for the list. That works, but I think there must be a better solution. Maybe a helper class to envelope other objects?
This is depending on the JSON-Serializer you are using. Jettison is wrapping the response in a root-element per default (I don’t think EnvelopeObject is a correct word for this).
If you are using Jackson you can configure this behavior with SerializationFeature.WRAP_ROOT_VALUE (or DeserializationFeature).
The name of the key can be specified with #JsonRootName if you are using Jackson-Annotations or #XmlRootElement if you are using JAXB-Annotations.
We have the following Json:
{
"type" : "1",
"otherStuff" : "2",
...
"items" : [
{
"commonItemAttribute" : "value",
"specificToType1" : "whatever"
...
}
]
}
We need to polymorphically deserialise the items into different sub classes based on the type attribute.
Is it possible in a custom Jackson deserialiser to get the type value?
Can we safely look back up the Json tree using the JsonParser given to the deserialize method?
I found this blog about polymorphic deserialisation but it seems to require a type attribute on the items themselves.
Thanks
This kind of JSON is not supported, since while "External" type ids of form:
{ "childType" : "SomeTypeId",
"child" : { .... }
}
are supported (with #JsonTypeInfo.As.EXTERNAL_PROPERTY), they only work for simple types, not for Collections or Maps.
So if you can't change JSON to be bit more standard (including type id for elements is the standard way), you will need to use custom serializers, deserializers.