Ignore Empty Collections during Serialisation - java

I have read questions like these #JsonInclude to ignore null values.
This works for me for regular fields within an entity but not for Collections. In case of empty Collections within an entity, Json serialisation gives a null value.
How does one do a equivalent ignore for collections ?

Try with the annotation
#JsonInclude(Include.NON_EMPTY)
private Collection field;

Since the Jackson 2.x it provides #JsonInclude annotation that controls serialization of a class as a whole or its individual fields based on their values during serialization. It recognizes following annotations as:
Include.NON_NULL Indicates that only non-null properties should be serialized.
Include.NON_EMPTY Indicates that only non-null and non-empty properties should be serialized. This is actually the superset of Include.NON_NULL
Hence over a collection Include.NON_EMPTY will work like
#JsonInclude(Include.NON_EMPTY)
private Collection field;
or you can put it over the class to impact upon the whole model like
#JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Foo {
}

Related

How to map non-annotated fields to attributes by default in Jaxb

By default, JAXB maps non-annotated Java field and properties to elements.
Is there a way to change this behaviour so JAXB maps non-annotated Java field and properties to attributes instead of elements?
There is no way with the current spec. Even if you annotate one of the fields with #XmlValue, you must explicitly set all other fields with #XmlAttribute otherwise marshalling will fail.

#Transient variable is not serialized using jackson [duplicate]

We use JSON serialization with Jackson to expose internal state of the system for debugging properties.
By default jackson does not serialize transient fields - but I wish to serialize them as well.
How can I serialize these fields?
One way I know is to supply a getters for these fields - but I don't want to do that, as I have some getX methods that I don't want to be invoked ( for instance, there are some getters that change the objects state ).
I know I could create an annotation, but I really want to avoid it.
So my question is:
Is there a way to setup jackson to serialize all the objects fields? include transient ones.
My solution with Jackson 2.4.3:
private static final ObjectMapper mapper =
new ObjectMapper(){{
Hibernate4Module module = new Hibernate4Module();
module.disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
registerModule(module);
}};
I don't think Jackson supports any type of configuration to enable it to serialize a transient field. There's an open issue to add that feature, but it's old and hasn't been addressed (as far as I can tell): http://jira.codehaus.org/browse/JACKSON-623
So my question is: Is there a way to setup jackson to serialize all
the objects fields? include transient ones.
So to answer your question, no.
Some other Java JSON tools, such as GSON do support a configuration option to serialize transient fields. If you can use another tool, you might look into that (for GSON, see: https://sites.google.com/site/gson/gson-user-guide).
To expand a little, you might try a different approach.
First, You shouldn't try to serialize a transient field. After all the definition of transient is "don't serialize this." Nevertheless I can think of a few specific situations where it might be necessary, or at least convenient (like when working with code you can't modify or such). Still, in 99% of cases, the answer is don't do that. Change the field so that it's not transient if you need to serialize it. If you have multiple contexts where you use the same field, and you want it serialized in one (JSON, for example), and not serialized in another (java.io, for example) then you should create a custom serializer for the case where you don't want it, rather than abuse the keyword.
Second, as to using a getter and having "some getters that change the objects state," you should try to avoid that too. That can lead to various unintended consequences. And, technically, that's not a getter, that's a setter. What I mean is, if it mutates state, you've got a mutator (setter) rather than accessor (getter), even if you name it following the "get" convention and return some stuff.
You can create a custom getter for that transient field and use #XmlElement attribute. It doesn´t matter the name of that getter.
For example:
public class Person {
#XmlTransient private String lastname;
#XmlElement(name="lastname")
public String getAnyNameOfMethod(){
return lastname;
}
}
Another way to let Jackson serialize property is to add #JsonProperty annotation above it.
I guess it's better approach cause you do not need to disable default behaviour for all #Transient fields, like in Gere's answer.

Is is possible to create a combo-annotation which combines multiple field annotations?

I have some boolean fields in my JPA entities which are annotated in the following way:
#Column(length = 1)
#Type(type = "yes_no")
private final boolean myField;
Is it possible to create a combo-annotation (e. g. MyAnnotation) which combines both of this annotations?
#MyAnnotation
private final boolean myField;
How?
Obviously you could create an annotation that provides the equivalent of multiple other annotations.
Equally obviously no JPA provider will support it, since they will check for the javax.persistence annotations only (not that #Type is javax.persistence).
What you want is similar to CDI stereotypes - unfortunately, JPA does not support such a concept, therefore you must copy recurring annotations all over.
If you can afford to wrap your field into an object, you may mark it as #Embeddable and put your field into it - the annotations on that field will be copied wherever you embed that object into an entity. You may extend the annotations using #AnnotationOverrides. Obviously, the drawback of such solution is additional complexity when accessing the field in your entity.

Serialize an object with no data in Jackson

Is it possible to serialize an object with no fields in Jackson using only annotations? When I attempt to serialize such an object with no annotations I get:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class [redacted].SubjectObjectFeatureExtractor and no properties discovered to create BeanSerializer
I have examined the list of Jackson annotations without seeing a way to annotate the class as having no serializable data. I tried putting #JsonCreator on the empty constructor (not expecting it to work, since it's a deserialization annotation), and I got the same error. There are no accessors or fields to put #JsonProperty on. Any ideas?
Update: The reason for this is that I have a list of objects which represent transformations which can be applied to a certain type of data. Some of these transformations are defined by parameters which needs to be serialized, but some of these are parameter-less (the data-less objects in question). I'd like to be able to serialize and deserialize a sequence of these transformations. Also, I'm using DefaultTyping.NON_FINAL so that the class name will be serialized.
Update: An example class would be
class ExtractSomeFeature implements FeatureExtractor<SomeOtherType> {
public void extractFeature(SomeOtherType obj, WeightedFeatureList output) {
// do stuff
}
}
I don't particularly care how the JSON for this looks like, as long as I can deserialize List<FeatureExtractor>s properly. My impression is that using default typing, the expected JSON would be something like:
['com.mycompany.foo.ExtractSomeFeature', {}]
Other sub-classes of FeatureExtractor would have real parameters, so they would presumably look something like:
[`com.mycompany.foo.SomeParameterizedFeature', {some actual JSON stuff in here}]
I think I could use #JsonValue on some toJSONString() method to return {}, but if possible I'd like to hide such hackery from end-users who will be creating FeatureExtractor sub-classes.
You have to configure your object mapper to support this case.
ObjectMapper objectMapper = ...
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
The documentation of this feature can be found here : Fail on empty beans
Feature that determines what happens when no accessors are found for a
type (and there are no annotations to indicate it is meant to be
serialized). If enabled (default), an exception is thrown to indicate
these as non-serializable types; if disabled, they are serialized as
empty Objects, i.e. without any properties.
The answer to disable SerializationFeature.FAIL_ON_EMPTY_BEANS is global, and you therefore might not wish to apply it.
The answer to add any serialisation annotation showed the correct (as in: the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS suggests it) way to fix it, but only with a hackish or an unrelated annotation.
By merely adding…
#JsonSerialize
… to my class (not even parenthesēs after it, lest alone arguments!) I was able to produce the same effect (as, again, indicated by the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS).
Adding the following annotation onto the class seems to solve the problem:
#JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.NONE)
Adding an unrelated annotated like
#JsonRootName("fred")
also seems to fix it. This seems to match the claim in the JIRA ticket that adding any Jackson annotation to the class will prevent the exception. However, it appears adding annotations within the class does not.
Not sure I get your question, but perhaps you want JsonInclude.Include.NON_DEFAULT, JsonInclude.Include.NON_NULL, or JsonInclude.Include. NON_EMPTY.

Jackson deserialization specific getter turning off

What is the most simple way to tell the Jackson to not serialize a specific getter method? I only want to say explicit to one getter, because I have a custom, complex class, and all setter and getter should function, only one should not:
mapper.configure(SerializationConfig.Feature.AUTO_DETECT_GETTERS, true);
So this is not the proper way. I need to tell that I don't want to use the getter in this class:
public static class EventRow implements Serializable, Cloneable, GRSerializable {
public int x
public int y
public double z
public String eventKeyValuesPacked;
//This getter should not be used, because there is no explicit setter
//for this, and also no public... And it is only unpack
//EventKeyValuesPacked so it would be multiple data...
public KeyValue[] getEventKeyValues() {
KeyValue[] kvs = DA_EventKey.unpackKeyValues(eventKeyValuesPacked);
return kvs == null ? new KeyValue[0] : kvs;
}
}
Is there any annotation or SerializationConfig option to make invisible the getEventKeyValues() getter method?
What is the most simple way to tell the Jackson to not serialize a specific getter method
...
without annotation?
Without writing a customer serializer...
If directly annotating the field/property/getter/setter to be skipped is undesirable, another approach is to make use of the Jackson Mix-In feature.
Yet another approach for serialization only would be to make use of the Jackson JSON Views feature, though this too requires annotations in some capacity.
There is an annotation for this: #JsonIgnore.
#JsonIgnore
public KeyValue[] getEventKeyValues() {
...
If you don't want to use an annotation for this then you'll need to write a custom serializer.
I think this almost do it:
objectMapper.configure(DeserializationConfig.FAIL_ON_UNKNOWN_PROPERTIES,
false);
This may depend on Jackson version -- prior to 1.9, getters and setters were handled separately, so not auto-detecting getter would have been enough. But with 1.9 and beyond, setter/getter/field are all combined into logical property, which may allow Jackson to deduce existence of property from setter.
So what you probably need to do is to also disable setter detection. Other options already given would work as well, mix-in annotations being a common way to do this.
objectMapper.configure(SerializationConfig.Feature.AUTO_DETECT_GETTERS, false);

Categories

Resources