Jackson annotation to override the one in parent class - java

I would like all my objects to have an ID and I wish to serialise it for some child class but not for some others
for example:
public class A {
protected Long id;
..getter and setter
}
public class B extends A {
#Override
#JsonIgnore
public Long getId() {..}
#Override
#JsonIgnore
public void setId(Long id) {..}
}
public class C extends B {
#Override
#JsonInclude
public Long getId() {..}
#Override
#JsonInclude
public void setId(Long id) {..}
}
public class Test {
Set<C> tests ...
..getter setter
}
I have tried serialising Test but the JSON string doesn't include the IDs
If I remove the JsonIgnore from B then in that case the Ids are there.
Is there a way with jackson to archive this?

Use
#JsonIgnore(false)
instead of
#JsonInclude

Related

Java EE: Interface with a method that returns an instance of a helper class. Bad idea?

I have an interface that defines a method that returns an instance of a helper class and I was wondering if there's a better way of going about what I'm trying to do.
For example, say I have a Tag class:
public class Tag {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
You can assign Tags to other objects.
The assignment is represented by TagAssign:
public abstract class TagAssign {
private Tag tag;
public Tag getTag() {
return tag;
}
public void setTag(Tag tag) {
this.tag = tag;
}
}
A new type of assignment will extend TagAssign and define what the Tag's being assigned to.
For example, a Tag assigned to a User would look like the following:
public class UserTag extends TagAssign {
private long id;
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
An object that can have a tag assigned to it will implement the TagAssignable interface:
public interface TagAssignable {
public TagAssignableHelper getTagAssignableHelper();
}
TagAssignable defines a method that returns an instance of TagAssignableHelper.
At the moment, TagAssignableHelper just defines a method that assigns the Tag to the TagAssignable, returning a TagAssign.
public interface TagAssignableHelper<A extends TagAssignable, T extends TagAssign> {
public T assignTag(A assignable, Tag tag);
}
Here's what a User class that implements TagAssignable would look like:
public class User implements TagAssignable {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Override
public UserTagAssignableHelper getTagAssignableHelper() {
return new UserTagAssignableHelper();
}
}
And UserTagAssignableHelper looks like:
public class UserTagAssignableHelper implements TagAssignableHelper<User, UserTag> {
#Override
public UserTag assignTag(User assignable, Tag tag) {
UserTag userTag = new UserTag();
userTag.setUser(assignable);
userTag.setTag(tag);
return userTag;
}
}
The code in use:
public class Main {
public static void main(String[] args) {
List<TagAssignable> assignables = new ArrayList<>();
assignables.add(new User());
Tag tag = new Tag();
List<TagAssign> assignments = new ArrayList<>();
for (TagAssignable assignable : assignables) {
TagAssign assignment = assignable.getTagAssignableHelper().assignTag(assignable, tag);
assignments.add(assignment);
}
}
}
I basically want each type of TagAssignable to define how it's used inside the framework. When a developer marks a class as TagAssignable, they have to define how the TagAssign class is created, because at some point in the framework it's going to try and do just that.
I'm trying to avoid doing something like this:
if(assignable instanceof User) {
User user = (User) assignable;
UserTag userTag = new UserTag();
userTag.setTag(tag);
userTag.setUser(user);
return userTag;
}
// followed by more ifs for each type of TagAssignable
I'm open to all feedback and suggestions.
I think introducing the TagAssign class hierarchy complicates your design. What I would try to achieve is to change the TagAssignable interface to only have Set<Tag> getTags(), add(Tag tag) and remove(Tag tag) tags. If you want to achieve immutability of objects with tags, you could change the interface to have with(Tag tag) and without(Tag tag) methods that return mutated instances. This would remove the need for separate assignment classes and their corresponding helpers.

Java + Jackson serialization & deserialization for interface, implemented by enum's

I am facing issue on deserializing pojo having field as interface which is implemented by multiple enum's
public interface interfaceEnum {
}
public enum a implements interfaceEnum {
A, B, C
}
public enum b implements interfaceEnum {
D, E, F
}
public class pojo {
public Integer id;
public interfaceEnum enum;
public Integer getId(){
return id;
}
public void setId(Integer id) {
this.id = id;
}
public intefaceEnum getInterfaceEnum() {
return interfaceEnum;
}
public void setIntefaceEnum(intefaceEnum enum){
this.interfaceEnum = enum;
}
}
I had also tried to implement custom deserializer by using
#JsonDeserialize of fasterxml.jackson on interfaceEnum but i am facing issue is Content
type 'application/json;charset=UTF-8' not supported
I need to pass json to pojo from UI side or using rest client, so i need to do both serializing and deserializing the interfaceEnum in pojo.
Thanks in advance for the help. :)

save mongo entity to the different collections

I've been using Spring Data for saving entities to the mongo DB and my code at the moment looks like this:
I have a repo class:
public interface LogRepo extends MongoRepository<Log, String> {
}
and I have an Entity Log which looks like this:
#Document(
collection = "logs"
)
public class Log {
#Id
private String id;
private String jsonMessage;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getJsonMessage() {
return jsonMessage;
}
public void setJsonMessage(String jsonMessage) {
this.jsonMessage = jsonMessage;
}
}
and this work well for me, however this approach works only for the case if I want to save Log entities to "logs" collection. However it would be very nice for me to be able to save Log entity to different collections depending on the context. I mean it would be nice to define collection name in the runtime. Is it possible somehow?
Thanks, cheers
Try to use inheritance and define appropriate collection names in such way. May give you possibility to save in different collections but you will be still not able to specify dynamically collection names and resp. their amount at runtime.
#Document(
collection = "logs"
)
public class Log {
#Id
private String id;
private String jsonMessage;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getJsonMessage() {
return jsonMessage;
}
public void setJsonMessage(String jsonMessage) {
this.jsonMessage = jsonMessage;
}
}
#Document(
collection = "log_child"
)
public class LogChild extends Log{}
With the MongoOperations save method you can choose which class to use and
based on the class it will choose the appropriate collection.
#Document(collection = "collection_#{T(com.github.your_project.DBUtils).getCollectionName()}")
public Class Collection
You can change the name in real time using a static getter
#UtilityClass
public class DBUtils {
private String collectionName;
public String getCollectionName() {
return collectionName;
}
public void setCollectionName(String collectionName) {
DBUtils.collectionName = collectionName;
}
}

Response with the parent class in SPRING REST

I have implemented a REST API with SPRING REST using Jackson (specifying in the pom.xml with the package org.codehaus.jackson - jackson-mapper-asl - 1.9.13). In the controller I have:
#Controller
#RequestMapping("/test")
public class TestController {
#RequestMapping(value="id", method= RequestMethod.GET)
#ResponseBody
public Parent findById(#PathVariable("id") int id) {
Child child = new Child();
child.setId(id);
child.setName("test");
return child;
}
}
For example in the Parent we could have:
public class Parent {
int id;
public void setId(int id) {
this.id = id;
}
}
And the child:
public class Child extend Parent {
String name;
public void setName(String name) {
this.name = name;
}
}
My problem is that I'd want the response to be only with the parent class and not with the child class (because now the response has the structure of the child).
One solution that would work for you is the following:
#JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
public class Parent {
#JsonProperty
int id;
public void setId(int id) {
this.id = id;
}
}
I have to admit that this solution is not terribly elegant since you need to add the #JsonProperty annotation to every field in the Parent class, but does have the benefit that no modifications are needed to any of it's subclasses
All the annotations that are present in the jackson library can be found here.
The javadoc for #JsonAutoDetectcan be found here

Overriding #jsonIgnore in subclass

I have a class Parent
public class Parent
{
private int id;
#JsonIgnore
int getId() {}
void setId(int id) {}
}
I have a subclass which is derived from Parent
public class Child extends Parent
{
#JsonProperty // just to explicitly tell jackson to serialize this
#Override
int getId() {}
#Override
void setId(int id) {}
}
I actually don't want the id property to be serialized when an object of Parent is returned but it should be serialized when an object of Child class is returned.
I think if Parent was an Interface, overriding the visibility would work, but I am not sure if the behavior is the same with superclass.
Is there a simple solution for this? I would really appreciate your answers. Tx.
What you want in the Child class is not #JsonProperty but instead #JsonIgnore(false).

Categories