How to use Jackson PropertyNamingStrategy with Immutables library - java

I am using https://immutables.github.io/ library with Jackson.
I want my class to be Jackson-serializable. I would like to use custom PropertyNamingStrategy (configured for com.fasterxml.jackson.databind.ObjectMapper using mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
Unfortunately Immutables library puts #JsonProperty("propertyName") at every field in generated code. That overrides PropertyNamingStrategy defined at mapper level (or at class level, using #com.fasterxml.jackson.databind.annotation.JsonNaming annotation).
Is it possible to make Immutables library stop putting property name for every field (using org.immutables.value.Value.Style or similar means)?
I have come with workaround, putting #JsonProperty (without value) at every property, but I am not satisfied with this.

Style property forceJacksonPropertyNames=false does not force property names to specific strings. It works with naming strategies configured at class level and at mapper level.
Introduction to styles is available here: http://immutables.github.io/style.html
You can read some background information about this setting in issues: https://github.com/immutables/immutables/issues/431 https://github.com/immutables/immutables/issues/353

Related

Swagger CodeGen personalize Equals in properties

i am working on a project that use swagger codegen, unfortunately they asked me to do a fix and I feel really stack, we have this swagger with an object, they requested me that in a specific object of the swagger when the class is generated the equals method must not check all the properties of the object and ignore one specific property, is possible so personalize the generation of the equals for a single object of swagger? for example using templates?
The only solution I can think of is using customized templates and extensions (e.g. x-skip-equal) to indicate a particular property needs extra handling.

How to I DISABLE DefaultTyping. Is it disabled by default

I need to ensure that the application I am writing has no Jackson XML/JSON vulnerabilities (CSV's). All the discussions I have seen talk about how to manage it! I want it OFF.
I am using the latest Jackson version 2.10.0 and the latest Spring boot 2.1.9 and Spring 5.2.0 but I have to justify my use of Jackson and I do not require any polymorphic behaviour.
The doc says I need to use activateDefaultTyping(). This sounds as if it turns it ON. Do I need to use activateDefaultTyping and implement PolymorphicTypeValidator to prevent it? Do I need this to prevent ALL polymorphic behaviour?
I have read lots of articles on managing the behaviour but I am still unclear what the default behaviour is. If it is polymorphic by default I need to turn if OFF.
You are vulnerable if you accept input from third parties, outside your application, in JSON format through your external API, and in which input you accept fields of type Object (or other widely implemented classes like Serializable). Then a potential attacker could send (almost) anything, including widely available classes (so called gadget classes), available on your classpath, whose constructors or setters execution (upon instantiation by Jackson at deserialization time) could result in dangerous effects on your system.
In order to be vulnerable, you need to have your Object field annotated with
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "#class", visible = true)
or use
ObjectMapper.enableDefaultTyping()
or
ObjectMapper.activateDefaultTyping() from Jackson 2.10.0
This will tell Jackson to deserialize the incoming json into the specific type specified by #class.
Otherwise, whatever data is sent will be deserialized into a key-value map by default.
So by default the "default typing" is OFF.
The activateDefaultTyping() you've mentioned should be used only in to be used in combination with a custom validator to define yourself in a decoupled way what types you allow for deserialization.
In shortest: if you want it OFF and don't need polymorphic deserialization, don't use #JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) or don't enable it specifically.
You can also call
ObjectMapper.deactivateDefaultTyping() to be sure it's not used, but note that using #JsonTypeInfo on your classes will not be affected by this call.

Can Jackson remove the #JsonFilter restriction

My code use a default ObjectMapper without filters defined, but the target class with a #JsonFilter annotation. My expectation is to Jackson will ignore the annotation and do a normal thing.
And in another case, if I want to use the filter and I also give the filter defined, why must add #JsonFilter to the class otherwise jackson will work as no filter.
#JsonFilter looks a redundant thing. We already defined the filters. The real issue is the problem described at beginning. We can't modify the class with annotation, we just serialize the class with normal behavior.
There's way to create a dummy filter and set setFailOnUnknownId(false). But this looks not so general.

jackson - ignoring case in snake case keys

I have a requirement to receive JSON with keys that contain underscore and even ignore the case in words. For e.g. Device_control_API, device_control_API, Device_Control_API, device_control_aPI etc all should map to same property.
Now I know that I can create multiple setter methods using #JsonSetter with all combinations possible, but I don't think that will be good.
I have seen other questions which suggest using mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
for ObjectMapper object to ignore case, but I can't do that because I am using spring-boot and want my REST API to get payload in the form POJO object.
Is there any annotation or some way to do so
Please help !!!
I dont think you can use the MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES as annotation. Got the following information from here
Jackson on/off features: MapperFeature
Jackson defines a set of per-mapper configuration, which can ONLY be
defined before using ObjectMapper -- meaning that these settings can
not be changed on-the-fly, on per-request basis. They configure
fundamental POJO introspection details, and resulting built objects
(serializers, deserializers, related) are heavily cached. If you need
differing settings for these, you have to use separate ObjectMapper
instances.
And the MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES is one of the configuration.
But maybe a custom deserialization class could help you. There are many tutorials and questions on Stackoverflow.
I found some:
Jackson: using #JsonSerialize (or #JsonDeserialize) annotation to register a custom serializer (or deserializer)
Right way to write JSON deserializer in Spring or extend it
There is also this property:
spring.jackson.mapper.accept_case_insensitive_properties=true

Changing names of properties while Serializing to JSON without source code

Need to serialize java objects to JSON while doing compression such as name change, exclusion etc. Objects use class from jar, source code of which is not available.
Looked through many libraries(Jackson , Gson), but found none solving this particular problem. Most of them are annotations based, which I can't use given I don't have source code.
One way to solve this problems is, use reflection and recursively go through object until you find a property name of which should be replaced or object is excluded in serialized JSON.
Need solution for this. Better if it is already implemented and tested.
You can also have a look at Genson library http://code.google.com/p/genson/.
You can rename and filter with quite concise code:
// renames all "fieldOfName" to "toName", excludes from serialization
// and deserialization fields named "fieldNamed" and declared in DefinedInClass
// and uses fields with all visibility (protected, private, etc)
Genson genson = new Genson.Builder().rename("fieldOfName", "toName")
.exclude("fieldNamed", DefinedInClass.class)
.setFieldFilter(VisibilityFilter.ALL)
.create();
genson.serialize(myObject);
If you want to do some more complex filtering (based on annotations for example) you can implement BeanMutatorAccessorResolver or extend BaseResolver.
Same for property renaming you can implement PropertyNameResolver and have full control.
And finally if you want to filter fields, methods or constructors according to their modifiers you can define your own VisiblityFilter.
Concerning performances of filtering/renaming there should be no problem as it is done only once per class and then cached.
To start using Genson you can have a look at the Getting Started Guide.
Found solution to the problem.
Google gson has class called GsonBuilder which has methods for exclusion strategy and naming strategy.
Using these two methods implemented a custom solution, where all the mapping and exclusion rules are stored using a xml and used at the time of serialization and de-serialization.
Works perfectly, though not sure about the performance of same.

Categories

Resources