way to changes displayed names using MappingJacksonJsonView - java

I have a POJO class Result,
public class Result {
private String someName;
private String someOtherName;
}
which is returned in my model and displayed as a json in the output:
{"result":
{"someName":"value",
"someOtherName":"value"}}
I can not find a way to display them as some_name and some_other_name, do you know what kind of mapping has to be set up to do this?

You can use the #JsonProperty annotation
public class Result {
#JsonProperty(value = "some_name")
private String someName;
#JsonProperty(value = "some_other_name")
private String someOtherName;
}
The value attribute javadoc states
Defines name of the logical property, i.e. JSON object field name to
use for the property. If value is empty String (which is the default),
will try to use name of the field that is annotated. Note that there
is no default name available for constructor arguments, meaning that
Empty String is not a valid value for constructor arguments.

Related

How I can manage optional values in Firebase Firestore and avoid empty fields in database?

In my context, there is the possibility of optional values.
For example, in this database, the field iVisperas can be empty in multiple cases. I think is a bad practice to keep empty fields (?).
Into my code, I map the snapshot to one class.
I don't want to keep the field iVisperas as an empty field in Firestore but I don't know how to determine from the model class if this field exists or not.
How I can achieve this. This is my model class from the document. Actually, at getTituloVisperas method I check if field iVisperas is empty. If I want to create iVisperas field only when it contains data, how I can manage that into the model class?
public class MetaLiturgia {
private String fecha;
private int tiempo;
private String semana;
private String mensaje;
private String salterio;
private int color;
private String meta;
private String titulo;
private String iVisperas;
private int weekDay;
public MetaLiturgia() {
}
public String getTituloVisperas() {
if (iVisperas.equals("")){
return titulo;
}else{
return iVisperas;
}
}
//...
}
For example, in this database the field iVisperas can be empty in multiple cases.
Seeing that all the fields in your MetaLiturgia class are set to private, I assume that you are using a constructor and public getters. If you want that your iVisperas property not to hold any value then simply do not instantiate it in the constructor or create another constructor without it.
If I want to create iVisperas field only when it contains data, how I can manage that into the model class?
In that case, you should use a Map and update that document only when the value for your iVisperas property is available.
I think is a bad practice to keep empty fields (?).
There is no benefit in keeping empty fields as long as are not needed. Remember, every property count in that 1 MiB (1,048,576 bytes) maximum size for a document.
According to Suhas Ch's answer, please also note that a property of type String which is empty ("") and a property which holds null, occupy the same amount of space in a document.
Edit:
Another possible solution is to assign a default value, in this case, 0, right inside the model (MetaLiturgia) class.
While creating field, set the type for iVisperas as null
and in the model class
public class MetaLiturgia {
private String fecha;
private int tiempo;
private String semana;
private String mensaje;
private String salterio;
private int color;
private String meta;
private String titulo;
private String iVisperas;
private int weekDay;
public MetaLiturgia() {
}
public String getTituloVisperas() {
if (iVisperas.equals(null)){
return titulo;
}else{
return iVisperas;
}
}
//...
}
When do you know if the field is empty?
You could delete attribute from your model class and create another class which inherits fro your model class.
There you can add the value. When it comes to saving the object, you wont write the field if its not used.
But I dont know if this is worth the effort, since you will have to create a newObject of the subclass once your attribute is used.

Diff two classes fields names and structure

My task
Force two classes to have the same (or similar) field names (and their types)
Description
I have an entity and Data Transfer Objects (DTO).
How do I force that if someone adds / removes / changes a field in entity, a test will fail, so DTO class matches the entity class by fields names and if possible by fields structure.
class City {
private String name;
private CityDetails cityDetails;
private Mayor mayor;
}
class Mayor {
private String name;
private LocalDate electionFrom;
private LocalDate electionTo;
}
class CityDto {
private String name;
private CityDetailsDto cityDetails;
private MayorDto mayor;
}
class MayorDto {
private String name;
// The client of the end-point of such DTO does not care about the mayor election.
}
CityDetails and CityDetailsDto can be different or not necessary. I would like to have their diff.
Approaches
Using so called diff tool
Let's imagine a diff tool which has input parameters - two objects and output parameter - Map, where Diff is a structure oldValue, newValue. This tool returns difference between input arguments.
public Map<String, Diff> diff(final Object first, final Object second) {
// This is implemented.
return innerDiff(first, second, otherParameters); //
}
public class Diff {
private String oldValue;
private String newValue;
// getters, setters, constructor.
}
// To achieve this, we used Guava Plain map. It works well!
How do I achieve the same for classes. I want to diff two classes and have their fields as difference.
public Map<String, FieldDiff> diff(Class<?> type1, Class<?> type2) {
// How?
}
One idea is to use reflection and iterate though all fields of the class.
How about using toString and compare?
As an alternative, we define toString() methods in both and then compare.
How to do that if some fields are missing?
Serialize into JSON
Similar to the previous one, but serializing both objects into JSON and then compare their classes by json field names. However, if our entity have already annotation DoNotSerializeNulls with is equal to #JsonInclude(JsonInclude.Include.NON_NULL) #JsonIgnoreProperties(ignoreUnknown = true), then how to do that?
References
https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

How to use the getter method which is stored in mongodb for some other POJO class?

I am having one class which is having getter and setter methods i am storing that getter method in mongodb with some other collection. After getting the method name from DB how to access that method. Whether it is possible to do like this or not?
public class MappingAlgorithmScoreGenerationRules {
#Field(value = FieldNames.CATEGORY)
private String category;
#Field(value = FieldNames.ATTRIBUTE_NAME)
private MappingScoreGenerationLogic attributeName;
#Field(value = FieldNames.PRIORITY)
private Integer priority;
#Field(value = FieldNames.ATTRIBUTE_SCORE)
private Integer attributeScore;
#Field(value = FieldNames.FINAL_THRESHOLD)
private Integer finalThreshold;
#Field(value = FieldNames.RESULT_COUNT)
private Integer resultCount;
#Field(value = FieldNames.NORMALIZED_VALUE)
private Integer normalizedValue;
#Field(value = FieldNames.GETTER_METHOD)
private String getterMethod;
}
This is the class where i am storing the method name.
public class MatchEntry {
private double matchedWeight;
public double getMatchedWeight() {
return matchedWeight;
}
public void setMatchedWeight(double matchedWeight) {
this.matchedWeight = matchedWeight;
}
}
getMatchedWeight is the method name i am going to store in the DB MappingAlgorithmScoreGenerationRules.
After getting the method name how to access the method name?
I want to access like
For example: MatchEntry.(the value get from db)
Use reflection API - https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html
Method methodToInvoke
= MatchEntry.class.getMethod("methodName", methodParams,..);
methodToInvoke.invoke(matchEntryInstance, params,..);
In Java you can achieve method access by name using reflection (https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html).
This is a tutorial you may be able to use to lean more about this language feature: https://www.geeksforgeeks.org/reflection-in-java/
In your example, let's say you have loaded an instance of MappingAlgorithmScoreGenerationRules from the database, whose getterMethod attribute returns "getMatchedWeight".
Let's also assume that you have an instance of MatchEntry.
You would then access as follows:
MappingAlgorithmScoreGenerationRules rules = ....; //load from DB
MatchEntry entry = ...; //wherever it comes from
String getterMethodName = rules.getGetterMethod();
Method getter = MatchEntry.class.getMethod(getterMethodName);
Object value = getter.invoke(entry);
This code snippet omits Exceptions, in particular NoSuchMethodException and InvocationTargetException.
Please note that if you choose this approach, and depending heavily on the rest of your domain model, you will also need to be very careful with assumptions about the return type of the actual value (unless you can somehow guarantee that they are all the same, in which case you could cast the value).
Code that uses reflection is also inherently brittle and prone to failure as soon as you refactor. Imagine you have a populated database with these rules, and during a code review a couple of methods are renamed. Inoccuous change? Or will your entire setup break on the next deploy?
A (type-)safer approach might be to ensure all entries and related objects derive from an interface that standardises the return type on a getValue(String attributeName) method, so instead of messing with reflection you might do:
MappingAlgorithmScoreGenerationRules rules = ....; //load from DB
MatchEntry entry = ...; //wherever it comes from
String attributeName = rules.getAttribute(); //instead of 'getterMethod'
Object value = entry.getValue(attributeName);
where MatchEntry.getValue might be defined as:
public Object getValue(String attribute) {
switch(attribute) {
case "matchedWeight": return getMatchedWeight();
default: return null; //or you could throw an exception
}
}
This would easily survive any kind of method name refactoring and reorganisation, but adds the overhead of adding a case to the switch for every new attribute.
This problem could be partially solved with a runtime annotation that essentially binds an attribute name to a getter method, e.g.:
public class MatchEntry implements Matchable {
private double matchedWeight;
#MyCustomAnnotation("matchedWeight")
public double getMatchedWeight() {
return matchedWeight;
}
public void setMatchedWeight(double matchedWeight) {
this.matchedWeight = matchedWeight;
}
}
public interface Matchable {
default Object getValue(String attributeName) {
//read methods annotated with 'MyCustomAnnotation's in current class and call the one with matching value
}
}
Your getValue(String attributeName) would be tasked with reading these annotations and dynamically figuring out which getter to call. Still requires the annotation to be added everywhere it's needed, but at least it's with the getter and not hidden in some switch that's potentially duplicated across multiple class definitions.
Instead you just need a single default definition in the parent interface, as hinted above.

Proper way to construct a Test object with a mutable member variable

What would be the proper way to construct a Test object with a member variable testName?
I want to support the ability to set the value of this attribute when it is constructed, and allow it to be mutable via a setter methods:
public class Test {
private String testName;
public Test( String name ) {
this.testName = name;
}
public setTestName( String name ) {
this.testName = name;
}
}
To create objects, you call their constructor. In your case, that's Test(String name):
Test myTestObject = new Test("and you must provide a string as a parameter");
now, because of the implementation of the constructor (this.testName = name;), the object's member value of testName will be "and you must provide a string as a parameter".
Then you can set it to something different using the setter in the class:
myTestObject.setTestName("here you also need to provide a string as a parameter");
This way, when the object is constructed, there's some value in testName, and after that it is changed to something else.
This outlines how you can change the value of testName whenever you want, and to whatever you want. All you need to do is pass the wanted string as a parameter to the function.
You can read some more info here and here.

Jackson mapping: Deserialization of JSON with different property names

I have a server that returns a json string:
{"pId": "ChIJ2Vn0h5wOlR4RsOSteUYYM6g"}
Now, I can use jackson to deserialize it into an object with the variable called pId, but I don't want the variable to be called pId, I would rather deserialize it to placeId.
Current object in android java:
public class Place {
private String pId;
}
What I want the object to look like:
public class Place {
private String placeId;
}
If I change the object's variable to placeId, jackson will not be able to deserialize the JSON as the property names no longer matches.
Is there a jackson annotation I can used to map the "placeId" variable in the java object to the JSON string variable "pId" returned back from the server?
Use #JsonProperty annotation:
public class Place {
#JsonProperty("pId")
private String placeId;
}
For more information you can see the related javadoc.

Categories