How to serialise POJO to json differently using Jackson? - java

I have a POJO that I want to Serialize differently based on a value of one of the properties.
Say, I have the POJO below. I want to include NULLs when "show" is true, and exclude NULLS when "show" is false. Be aware that the actual Object I am trying to Serialize has over 30 properties.
public class User {
#JsonIgnore
private boolean show;
private String name;
private Integer age;
...
...
}
I would like to know how to do that using Jackson. Do I have to implement my own JsonSerializer, or should I create a PropertyFilter? Or have I missed an out of the box feature?

You can write your own custom serialiser that takes care of the generation of null properties based on the show instance variable. For that you can create a ObjectMapper with NULL serialisation settings based on your show property and then delegate the serialisation to it.
I have a similar requirement and probably I'll be acquainting myself with the actual APIs of Object Mapper. I'll try to post the code for the above.

Related

Jackson #JsonIgnoreProperties targeting nested attributes

Is there a way to make #JsonIgnoreProperties target nested attributes?
Something like the code below:
public class ParentObject() {
#JsonIgnoreProperties({ "subAttributeA.subAttributeB.subAttributeC" })
private ChildObject attribute;
}
In this example, I want that subAttributeC is not included in the serialization of a ParentObject - but this same subAttributeC still need to be serializable in other scenarios.
If not possible with annotations, how to achieve this?
One possible way is to use #JsonSerialize with a custom serializer. This operates on a low abstraction level and you basically have to specify how to serialize every single attribute. There's an example here that uses a flat object, but given that JsonGenerator has methods like writeObject etc., I'm sure this can be used for a hierarchical structure, too.
If jackson is configured to not serialize null attributes:
objectMapper.setSerializationInclusion(Include.NON_NULL);
Then a simpler workaround is to set the unwanted attribute as null before returning it.

How to print JSON object by Gson without sensitive attributes?

I am using Gson to print objects as JSON but I realise that it prints all things and it also exposes sensitive datas. Anyway to prevent that easily?
You can use #Expose(serialize = false, deserialize = true) over fields that you do not want to expose as JSON. This way you do not convert some fields when converting to JSON format but they are available when you receive a JSON object over the network and want to use those fields.
If you take a look at the Gson-doc here you can see the answer to your question. Do not forget to invoke GsonBuilder.excludeFieldsWithoutExposeAnnotation()
I just have another way to do it:
Just write the keyword "transient" before the field you want to remove. For example:
private transient String emailAddress;
"transient" works like just #Expose(serialize = false, deserialize = false). That field will not be present during the serialization as well as the deserialization of your object.

Gson: How to use a custom serializer only with some annotations?

I have some classes containing integer IDs, something like this:
class MyClass {
int myId;
// Other fields
}
I need a way to use a custom serializer only in certain cases (so that I cannot use #JsonAdapter) and of course I cannot generically use this serializer for all the integer values, because sometimes I want a sort of transformation of my ID (i.e. this is a web server response and I want to mask my ids so that they cannot be reused).
The full data model is quite complex and deep, and I annotated all the ID fields (even when they are collections) with a custom annotation #MyId. The point is that I don't find a valid way to say to a Gson instance "please, use this serializer for fields annotated with #MyId.
Do you have any ideas?

Serialize Set of UUID using Jackson

I found that jackson comes equipped with a UUID serizlizer/deserializer that can be used like this:
#Data
#NoArgsConstructor
public class MyClass {
#JsonSerialize(using=UUIDSerializer.class)
#JsonDeserialize(using=UUDIDeserializer.class)
private UUID myUUID;
}
And then using ObjectMapper on MyClass will correctly serialize/deserialize the myUUID field.
However, my class has a set of UUIDs that I want to serialize. I tried annotating the field the same way as above, but it complains that Set cannot be converted to UUID (as I half expected).
I know I can create my own serializer/deserializers by extending JsonSerializer/JsonDeserializer, but this feels hacky. Is there another solution I can use? I also don't have the option to configure the ObjectMapper with my classes, since I don't have access to the ObjectMapper. I am using Amazon SWF and it automatically uses Jackson.
Jackson should automatically use UUID serializers, deserializers, so your annotations should not be necessary.
But as to annotation usage, as suggested, (de)serializer for content (instead of value itself!) does need to use contentUsing property of the annotation -- otherwise Jackson will try to apply given (de)serializer directly for the value, with reported mismatch,

Jackson JSON converts integers into strings

I am using the object mapper to map into an object that has String variables. This works a little too well, because even integers and booleans from the JSON are converted into Strings.
Example:
{"my_variable":123}
class MyClass{
String my_variable;
}
I would like the object mapper to report an error in this kind of situation instead of converting 123 into a string for my_variable. Is this possible?
There is currently no such configuration, but you can override default deserializer with a custom one (see fasterxml wiki) and make that throw an exception?
If you would like a more convenient way you can file a Jira enhancement request; for example, new DeserializationConfig.Feature.COERCE_STRINGS_AS_NUMBERS (default to true) that one could disable to prevent such coercion.

Categories