Jackson: exclude field from one JsonView class - java

I have a model.
public class Model {
#JsonProperty("model_id")
private Integer id;
#JsonView(face.Test.class)
#JsonProperty("model_name")
private String name;
#JsonProperty("model_level")
private Byte level;
#JsonView(face.New.class)
#JsonProperty("model_score")
private Byte score;
#JsonView(face.Test.Tester.class)
#JsonProperty("model_community")
private Long community;
//getter and setters
}
as you can see my id and level fields will be included in all JSONs which be created from this model.
now I want to put for example field level in all JSONs (which be created from this model) except one.
is there something like #JsonView(!face.Example.class) ? if it's not, what is the best solution for this case?
thanks so much

I believe you need to use view class inheritance to accomplish this.
public class face {
public static class BaseView {}
public static class Test extends BaseView {}
public static class New extends BaseView {}
public static class Example {} // no parent
}
And so:
public class Model {
// included in all views
private Integer id;
// only in Test view
#JsonView(face.Test.class)
private String name;
// included in BaseView and its children (ie not Example)
#JsonView(face.BaseView.class)
private Byte level;
// ...
}
Presumably you have a logical hierarchy of views that apply to more than just the one field.

Related

Unable to find generated Parcelable class with Realm

I am trying to pass realm object with bundle and I used Parcel library
This is my realm model class.
Album.java
#Parcel
public class Album extends RealmObject implements Serializable {
#PrimaryKey
public String id;
public String upc;
public String albumName;
public String albumArtUrl;
public String artistName;
public String genre_id;
public String genreName;
public String price;
public String releaseYear;
public int explicit;
public RealmList<Song> songs = new RealmList<>();
}
And this is Song.java.
#Parcel
public class Song extends RealmObject implements Serializable {
#PrimaryKey
public String id;
public String isrc;
public String songName;
public String artistName;
public String album_id;
public String albumArtUrl;
public String genre_id;
public String genreName;
public String releaseYear;
public String price;
public String lyrics;
public String demo;
public int explicit;
}
When I try to pass album object in bundle like that,
b.putParcelable("album", Parcels.wrap(album));
I am having that error.
Unable to find generated Parcelable class for com.devhousemyanmar.juketrill.models.Album, verify that your class is configured properly and that the Parcelable class com.devhousemyanmar.juketrill.models.Album$$Parcelable is generated by Parceler.
please help me to solve this.
If you check the documentation, it has a section dedicated to using Parceler.
// All classes that extend RealmObject will have a matching RealmProxy class created
// by the annotation processor. Parceler must be made aware of this class. Note that
// the class is not available until the project has been compiled at least once.
#Parcel(implementations = { PersonRealmProxy.class },
value = Parcel.Serialization.BEAN, // <-- requires getters/setters if set
analyze = { Person.class })
public class Person extends RealmObject {
// ...
}
But what's worth noting is that you don't need to specify implementations = {PersonRealmProxy.class} if you use realm.copyFromRealm(song) before passing it to Parcels.wrap(). You'll need to do that anyways if you want to use field values instead of bean serialization strategy, anyways.
Also, you might need a RealmList parceler configuration.

Best way to write pojos that can have common fields

I am currently making a service in which there are lots of public API's. And the response and request objects overlap a lot. So, I was thinking that is there a way by which we can generalise the pojo creation for the request/response objects.
Sometimes the response object is identical to the request object with one or two extra fields.
Let me give you an example.
#Data
public class Request {
private A objA;
private B objB;
}
#Data
public class Response {
private A objA;
private B objB;
private C objC;
}
#Data
public class A {
private D objD;
}
#Data
public class B {
private String sB;
private E obje;
}
#Data
public class C {
private String sC;
}
Similary, D and E are pojos as well. The thing is that there is a lot of similarity(overlapping fields) in request/response objects.
Your solution is probably inheritance: Create a parent abstract object type with the overlapping fields and have the request and response objects extend it and specify any extra (unique) fields they need.
Inheritence
public abstract class Common {
private String overlapfield1;
private String overlapfield2
}
public class Request extends Common {
private String requestField1;
private String requestField2;
}
public class Response extends Common {
private String responseField1;
private String responseField2;
}
You could also approach this using composition: Create an object type with the overlapping fields and include this object as a sub-object of the Request/Response types:
Composition
public class Common {
private String overlapfield1;
private String overlapfield2
}
public class Request {
private String requestField1;
private String requestField2;
private Common common;
}
public class Response {
private String responseField1;
private String responseField2;
private Common common;
}
There are pros and cons to each approach which are widely discussed on this and other boards. These however, are the two standard approaches to dealing with such a problem.
It really depends on what you are trying to achieve. I don't see it being a huge problem repeating the fields but you've given an abstract use case rather than a real world situation where I can understand what you're trying to achieve.
Perhaps you want to pass your #Data objects to the same services? In which case you might want to use interfaces because a class can implement multiple interfaces.
Eg
public interface AContiner {
A getA();
void setA(A a);
}
public interface BContiner {
B getB();
void setB(B b);
}
#Data
public class Bean1 implements AContainer {
private A a;
}
#Data
public class Bean2 implements AContainer, BContainer {
private A a;
private B b;
}
public class MyFantasticService {
public void doStuffWithA(AContainer data) {
System.out.println(data.getA());
}
public void doStuffWithB(BContainer data) {
System.out.println(data.getB());
}
}

Dozer: Mapping fields for specific subclasses

The situation is this:
On the side of the domain we have a superclass let's call it Plant
and two subclasses Vegestable and DecorativePlant.
public abstract class Plant {
private String name;
#Mapping("elementValue.carbonValue")
private int carbonValue;
#Mapping("elementValue.oxygenValue")
private int oxygenValue;
}
public abstract class Vegestable extends Plant {
private int nutritionValue;
}
public abstract class DecorativePlant extends Plant {
private int rating;
}
now on the side of our soap api we have simular objects. The main difference
would probably be that we don't want the decorative plant on the soap-side to have
public class Vegestable {
private int nutrition;
private ElementValue elementValue;
}
public class DecorativePlant {
private int rating;
}
public class ElementValue {
private int carbonValue;
private int oxygenValue;
}
So now I was wondering if it is possible to specify that Dozer only maps the fields carbonValue and oxygenValue for subclasses of Vegestable and not for subclasses of DecorativePlant? If it's possible in Dozer than I won't have to actually alter my classes on the domain level and basically place the carbonValue and oxygenValue in both subclasses and than Dozer won't do the mapping for DecorativePlant. (A side from the #Mapping annotation I'm doing all my mapping in a mappings.xml file.)
Big thanks in advance!

Mapping abstract class in dozer

I have the following class structure (it actually is a VO layer with Hibernate mappings):
public abstract class abstractClassVO {
private int id;
private String name;
}
public class concreteClassAVO extends abstractClassVO {
private String aAttribute;
}
public class concreteClassBVO extends abstractClassVO {
private Long bAttribute;
}
And the equivalent DTO objects:
public abstract class abstractClassDTO {
private int id;
private String name;
}
public class concreteClassADTO extends abstractClassDTO {
private String aAttribute;
}
public class concreteClassBDTO extends abstractClassDTO {
private Long bAttribute;
}
Then I have another object like this:
public class compositeObject {
private int anAttribute;
private abstractClassVO myInstance;
}
and its equivalent:
public class compositeObjectDTO{
private int anAttribute;
private abstractClassDTO myInstance;
}
How can I tell dozer to automatically map myInstance to the specific DTO that corresponds to the concrete class implementation in the VO layer?
Currently, out of the box, Dozer isn't even putting anything in the myInstance field of the compositeObjectDTO class. My guess is that it's due to the fact that abstractClassDTO it is an abstact class, and since it cannot determine the implementation, it does nothing. I am not getting any exceptions.
Dozer can't do it out of the box but you could write a helper that would determine destination class by source class. You can get this information from DozerBeanMapper.getMappingMetadata().getClassMappings* methods. These methods return list of ClassMappingMetadata that contains destination class. You just only need to chech whether destination class is inherited from abstractClassDTO. This check can be omitted if you only have one mapping for one VO.
For bi-directional mapping you should additionally check ClassMappingMetadata.MappingDirection field.

Design patterns for type-safe integers?

I have an application that works with a entities that all have an integer ___ID primary key (e.g. StudentID, CourseID...etc)
I want to add a bit of type safety to the program, so for example a function that takes as input a StudentID, cannot be accidentally passed a CourseID.
First idea that came to my mind is to create simple empty classes like this:
public class StudentID extends java.util.Integer {}
public class CourseID extends java.util.Integer {}
This doesn't work since java.util.Integer is final and can't be extended.
Second idea is to have a data class that only holds an integer:
public class StudentID {
private final int id;
public int get() { return id; }
}
Though it would be a lot of boilerplate code.
Third idea is like second idea but to save on boilerplate code by having one base class that defines the get method and empty classes that inherit from it:
public abstract class AbstractID {
private final int id;
public int get() { return id; }
}
public class StudentID extends AbstractID{};
public class CourseID extends AbstractID{};
Are there any other/better known patterns for this problem?
How about ID<T>? If you want to restrict some argument to a function, I think you can do as following:
void foo (ID<? extends Student> param);

Categories