Ignore Java Object's Selected fields while Sending it as JSON - java

I am new to Spring-MVC.
I am sending data to my view as JSON, and there I am deserializing it to a string, but I want to pass only selected fields, I don't want all fields to send there but how to ignore selected fields I don't know.
My class POJO code :
public class account{
private Integer userId;
private String userName;
private String emailId;
//getter - setter
}
In some activity I don't want some fields so I want to avoid that fields so any idea on this confusing situation ?

Add the annotation #JsonIgnoreProperties("fieldname") to your POJO.
or you can use #JsonIgnore also before field name that you want to ignore while deserializing JSON.
example :
#JsonIgnore
#JsonProperty(value = "user_password")
public java.lang.String getUserPassword()
{
return userPassword;
}
Here Is my Answer for Similar Question.

Related

How can I add an additional json parent node when mapping a DTO?

I'm working on some data product mapping, and I stumbled across an issue I'm not sure how to solve.
Suppose I have a HumanMood data product. I'm receiving pushed data (HumanMoodInputDto) through a POST request method received by WebFlux controller.
The HumanMoodInputDto DTO:
#Data
public class HumanMoodInputDto {
#JsonProperty("human_mood")
#NotNull(message = "Human mood can't be null ")
private String humanMood;
#JsonProperty("last_update")
#Pattern(regexp = "([0-9]{4})-([0-9]{2})-([0-9]{2})", message = "Date format must be YYYY-MM-DD")
#NotNull(message = "Last update can't be null ")
private String lastUpdate;
}
I'm using MapStruct to map the data product. And the response that my controller is returning is based on this HumanMoodOutputDto:
#Data
#JsonRootName(value = "data")
public class HumanMoodOutputDto {
#JsonProperty("human_mood")
private String humanMood;
#JsonProperty("last_update")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate lastUpdate;
#JsonProperty("updated_by")
private String updatedBy;
}
The #PostMapping for WebFlux controller:
#PostMapping("humanMood")
public Mono<HumanMoodOutputDto> getHumanMood(
#Valid #RequestBody
Mono<HumanMoodInputDto> humanMoodInputDto) {
return humanMoodService.create(humanMoodInputDto.map(mapper::dtoToPushedInput))
.map(mapper::outputToDto);
}
So at the moment I'm getting response that looks like this:
{
"data":{
"human_mood":"good",
"last_update":"2021-08-19",
"update_by":null
}
}
What I want to accomplish is to add an additional json parent node called "data_flags", which would hold ArrayList<String> values, that would describe any errors or warnings when mapping the data. So in the end I want my output to look like this:
{
"data":{
"human_mood":"good",
"last_update":"2021-08-19",
"update_by":null
}
"data_flags":[
]
}
Should I create a seperate DTO and then another one which which would contain data from both of them, or is there a more simple way to enrichen the data product?
The simplest way in my opinion is to build a separate DTO that would have the following attributes:
private HumanMoodOutputDto data;
#JsonProperty("data_flags")
private HumanMoodMappingWarningOutputDto dataFlags;
This would allow you to get rid of #JsonRootName(value = "data") in HumanMoodOutputDto.

JAX-RS serialize only few properties

We have a DTO like below
public class Student {
private String name;
private String id;
private ExamResults results;
private Address residentialAddress;
private Address permanentAddress;
// setter and getter methods
}
The same DTO is used by multiple endpoints like student/details/{studId}, student/details/{studId}/results
In student/details/{studId} endpoint we dont populate results property. But still it is being returned as null in the response.
Similarly, in student/details/{studId}/results we dont populate permanentAddress and residentialAddress, but still these are being returned as null in the response.
Basically, I would like to control what properties are serialized based on the endpoint irrespective of whether they are null or not.
Thanks.
You can try to use
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Student {

Spring MongoDB - Difference between #Indexed and #Field annotations

I am trying to understand how the two different annotations of #Indexed and #Field differ while defining a model in Java Spring Boot.
public class Notation {
#Id
private String id;
#Field("value")
private String value;
#Field("description")
private String description;
#Field("frequency")
private int frequency;
}
public class Notation {
#Id
private String id;
#Indexed("value")
private String value;
#Indexed("description")
private String description;
#Field("frequency")
private int frequency;
}
My use case is to finally implement a search from the repository based on both value and description fields, so it would be good to get an idea of how the data is structured in the two and what are the various options one can use from these annotations.
#Indexed annotation is will add an index that on that field in your mongo server. It takes an optional string parameter, which will be the index name and nothing to do with the field name. You should have only those fields indexed which will be used for filtering out documents.
#Field is used if you want to have different names in your java code and MongoDB collection.
For eg.
#Field("desc")
private String description;
In this case, in your MongoDB collection, you will find field name as "desc" while in your java code you will be referencing it as "description"
#Field("description")
private String description;
In the above case, there is no need for using #Field annotation

Jackson use getter for a specific property

I have a JPA transient property in an entity which has a calculated value based on multiple fields in the POJO. All these calculations are done in the GETTER of that property.
But, Jackson doesnt seem to be using the GETTER when creating the JSON for that POJO.
How do I configure Jackson to use getter for the property?
My POJO looks something like below
#Entity
public class ProductSummaryEntity implements Serializable {
#Basic
private String field1;
// GETTER and SETTER for Field1
#Basic
private String field2;
// GETTER and SETTER for Field2
#Transient
private String field3;
public String getField3(){
setField3(field1 + field2);
return this.field3;
}
public void setField3(String temp){
this.field3=temp;
}
}
This link to a blog by #sghill has been posted on SO before and shows you how to customize the serialization process: https://www.sghill.net/how-do-i-write-a-jackson-json-serializer-deserializer.html
Essentially, annotate your POJO with #JsonSerialize(using = CustomSerializer.class) and then implement a class CustomSerializer that's extending from JsonSerializer. In your implementation you can build the JSON however you like and calculate values on the fly or call your getters.
No, I don't think you can serialize transient field unless there is something latest is there.

GSON equivalent for #JsonIgnoreProperties in Jackson

In Jackson you can ignore the properties by giving annotation #JsonIgnoreProperties at class level and the properties which are not in the actual JSON are not serialized/deserialized from/to the Java class. What is the equivalent of it if we are using GSON?
You can get a similar effect with the GSON #Expose annotation using GsonBuilder.excludeFieldsWithoutExposeAnnotation().
E.g.
public class User {
#Expose private String firstName;
#Expose(serialize = false) private String lastName;
#Expose (serialize = false, deserialize = false) private String emailAddress;
private String password;
}
If you use Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() with the above class, then the toJson() and fromJson() methods will completely ignore the password field as it doesn't have an #Expose annotation.
(Note you also get finer-grained control here as you can control whether GSON serializes/deserializes fields as well).
Reference: https://github.com/google/gson/blob/master/UserGuide.md#TOC-Gson-s-Expose
In GSON, you can also declare the field as transient. It will have the same effect as opposite to marking other fields as #Expose. But, you will not have finer grained control of serialization/deserialization as that of #Expose. However, if you have 100s of fields spanned across multiple classes, and you only need to exclude one field, it is far more convenient to mark the field as transient. Moreover, this works on the default setting of GSON. E.g.
public class User {
String firstName;
String lastName;
private String emailAddress;
private transient String password;
}
Reference: https://github.com/google/gson/blob/master/UserGuide.md#finer-points-with-objects

Categories