Jackson #JsonIgnore changed semantics? - java

We just upgraded some maven dependencies, that triggered an update of Jackson from 1.7.x to 1.9.x
We use to annotate #JsonIgnore on setter methods, on methods not supposed to be set from client side. for example: the owner of an object (with should be set from the authentication principal), etc.
It seems to us that the semanthincs of this annotation have changed, is that possible? now the field is been jsonignored in all case, and not only when being set.
is that the case? is there an alternative way in 1.9 to implement ignore SET only?
thanks!
r.

Ok, I think I found and explicit mention to this issue in the javadoc. (jackson documentation is not easy to go through).
In addition, starting with Jackson 1.9, if this is the only annotation associated with a property, it will also cause cause the whole property to be ignored: that is, if setter has this annotation and getter has no annotations, getter is also effectively ignored. It is still possible for different accessors to use different annotations; so if only "getter" is to be ignored, other accessors (setter or field) would need explicit annotation to prevent ignoral (usually JsonProperty).

Related

Java compiler -parameters flag and Jackson

I tried enabling the -parameters flag in a project in order to use the JDBI ConstructorMapper without having to annotate each parameter.
What I then discovered was that the Jackson serialization changed behavior. I have been able to identify two things that have changed, but I have been unable to find any documentation on it.
When using the JsonCreator with mode default it now defaults to mode PROPERTIES when before it defaulted to mode DELEGATING. I now have to set this explicitly.
When using JsonProperty on a constructor parameter, that name is also kept when serializing the object. It used to serialize to the getter name, unless anything else was specified.
Are these all the changes to Jackson behavior? Also, are there any global settings I can change, so that I don't have to add lots of new annotations to my codebase?
I have tried looking for documentation, but it is hard to find the correct search terms.

Annotation Processing: how to change annotation target in Kotlin code?

Quite often, when I use annotations from Java libraries in Kotlin code, I have to specify target in order to specify what element in the compilled code has to be annotated:
data class User(
val id: String,
#get:Email
val email: String
)
Instead of specifying #get:Email, I would love to be able to use simply #Email, especially if it occurs in many places.
Question: Is there a way to hint Kotlin compiler to use a different target in all places so that if I use #Email it will handle it as if it was #get:Email? Or is there any other way to omit specifying target? How can it be achieved? May it be done on the compilation stage via annotation processing (like Lombok does)?
I would appreciate any ideas even if they don't answer my question directly.
You can't override it. Maybe create annotation that will target #Email annotation and provide the property getter when it tries to call target.
Specifying target is dictated by the annotation target. When the target of the annotation is specified to jvm use-targets then you must use #get: to specify that the annotation targets the getter of the property.
In order to use simply #Email you must use kotlin target types for your annotation, probably PROPERTY. Note that, PROPERTY target doesn't work with Java.
#Retention(AnnotationRetention.RUNTIME)
#Target(AnnotationTarget.PROPERTY)
annotation class Email
It should be possible with Kotlin Compiler plugins API. It's a complicated way, tho.
To achieve this you will need to add a ClassBuilder interceptor with a visitor handling #Email annotation and specifying a correct target.
Can't say without getting deeper if visitor will be enough or you will also need to modify source code on one of the compiler stages, check TreeVisitor.

can jackson serialize full version including #JsonIgnore?

I want to serialize an object using java jackson.
I want to serialize it once in a short version
and second in a full version.
I have added a #JsonIgnore annotation over the non-mandatory fields.
But how can I tell jackson to serialize all fields including #JsonIgnore when desired?
It is possible to ignore #JsonIgnore. I can think of 2 approaches:
Extend JacksonAnnotationIntrospector, over hasIgnoreMarker(...) method (I think that's the name -- can check javadocs)
Add #JsonIgnore(false) annotation override using "mix-in annotations": false means "do not ignore", and is explicitly allowed to be used (default value is true) for such overrides.
However: a better way would be to use JSON Views, or JSON filters.

when jackson auto detect setter, can I force it to use the pascal case?

Currently when jackson object mapper auto detetc setter, it defaults to lower case. Can I change the mapping to Pascal case?
It is possible to create custom AnnotationIntrospector that can find setters/getters that use different naming convention. But there is no automatic way to define mapping between external (in JSON) names to bean properties, using other name-mangling schemes. At least not yet; adding support is planned for 1.8.
Until then, one needs to use #JsonProperty annotation, or override internal classes (aside from AnnotationIntrospector there are other extension points that would work, but that's more of discussion for mailing lists).
I'm not sure what "Pascal case" is but the answer is no. All Java object mappers have to comply to the Java Beans API which clearly defines the case for fields, setters and getters and how one name can be derived from another.

Java Annotation: On property or on method? What the difference

Hibernate Search, Hibernate, Struts2... I see more examples... In same examples I see the annotation on the field.. Other on the get/set method.. There are differences? Or is casual..
I hope that is not a stupid question!
Saluti!
Luigi
The difference depends on the annotation and how it is used. For example, in Spring you can use the #Controller annotation only on a class. This tells Spring that the class is a controller.
As far as methods are concerned, #RequestMapping is an annotation that goes on a method. For properties, you can have validation annotations like #NotNull (in Hibernate validator).
Annotations are definitely not casual; they carry meaning and can affect the way the code behaves.
From the Java documentation regarding annotations:
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Annotations have a number of uses,
among them:
Information for the compiler — Annotations can be used by the
compiler to detect errors or suppress
warnings.
Compiler-time and deployment-time processing — Software tools can
process annotation information to
generate code, XML files, and so
forth.
Runtime processing — Some annotations are available to be
examined at runtime.
Annotations can be applied to a
program's declarations of classes,
fields, methods, and other program
elements.
You can specify what an annotation can annotate by specifying the the elements (using a #Target annotation) when you define your own annotation.
This really depends on the code that interprets the annotations. It can of course make a difference, but the annotations you are talking about are probably meant to annotate a "property", which is something that technically does not exist in Java.
Java has fields and methods, but these are used to simulate properties under the "Java Bean" conventions, i.e. you have a public setX() and a getX() method that often (but not always) write and read a private field x. They're tied together via a naming condition, not a language mechanism.
Because of that, most frameworks that use annotations for such properties (e.g. for persistence mapping or dependency injection) are flexible and allow you to annotate either the field or the get or set method.

Categories