I want to add #JsonIgnore of Jackson On the Password property of User domain such that I must be able to send the Json With password and It saves my data in Database but in response I don't want to show the password.
How can I acheive this please help me.
I tried to use it at the Domain level of the User where the properties are defined but it Totally Ignore the property in the getter and setter methods.
I have tried this
private String password;
#JsonIgnore
public String getPassword() {
return this.password;
}
Try using both #JsonIgnore and #JsonProperty in your class like this:
private String password;
#JsonIgnore
public String getPassword() {
return password;
}
#JsonProperty
public void setPassword(String password) {
this.password = password;
}
You can do it this way too if you don't want to manually create the getters/setters (eg.
when using lombok's #Data)
#JsonProperty(access = Access.WRITE_ONLY)
private String password;
I think you should use DTO Pattern to set / change password.
In my case it helped to do it like that:
#JsonProperty
private String password;
#JsonIgnore
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
Try using the access property of #JsonProperty as below.
This will avoid deserialization but since write access is provided, the password can be saved.
#JsonProperty(access = Access.WRITE_ONLY)
#Column(name = "encrypted_password")
private String password;
Access setting that means that the property may only be written (set)as part of deserialization (using "setter" method, or assigning to Field, or passed as Creator argument)but will not be read (get) for serialization, that is, the value of the property is not included in serialization.
Related
How can I hide some sensitive data on this example. I'm testing APIs in rest client (Postman), when I call Api List of Bills, I want to hide some data. In BillsDto I want to hide username, password and user age fields. Is it possible to do this in my BillsDto class (not in UserDto). I know I can hide some fields using #JsonProperty but how to do it for some fields belonging to another class?
***BillsDto***
public class BillsDto {
private String numberBills;
private double amount;
private Date deadlinePayment
private UserDto user; // try to hide username, password, age from BillsDto
}
***UserDto***
public class UserDto {
private String number_id;
private String username;
private String password;
private String firstName;
private String lastName;
private String age;
}
I know I can hide some fields using #JsonProperty but how to do it for some fields belonging to another class?
The fact that you're using UserDto as a nested object somewhere, doesn't change the serialization policy that you can express through data binding annotations in the UserDto.
If you can change UserDto, apply #JsonProperty with it's property access set to JsonProperty.Access.WRITE_ONLY on the fields want to hide during serialization.
public class UserDto {
private String number_id;
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String username;
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
private String firstName;
private String lastName;
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String age;
}
If for some reason, you want to achieve this by editing BillsDto only, then you can implement a custom serializer for UserDto and apply it by making use of the #JsonSerialize. But to ensure that you're not disclosing the sensitive data somewhere, it would be better to apply this policy in one place - in the UserDto, because you or one of your colleagues might simply forget to #JsonSerialize in some of the classes which uses UserDto.
This is definitely not a duplicate of Only using #JsonIgnore during serialization, but not deserialization. The problem is the same but in the context of Immutables.
When a model(DTO/DAO) is decorated as an Immutable, I am not able to selectively #JsonIgnore one of the properties during serialization. Suppose that we have a UserDto which is defined as an Immutable as follow
#Value.Immutable
#Value.Style(defaults = #Value.Immutable(copy = false), init = "set*")
#JsonSerialize(as = ImmutableUserDto.class)
#JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {
#JsonProperty("id")
#Value.Default
public int getId() {
return 0;
}
#JsonProperty("username")
public abstract String getUsername();
#JsonProperty("email")
public abstract String getEmail();
#JsonProperty("password")
public abstract String getPassword();
}
I believe it is fair to expect that during serialization we would want to ignore the password from the response of the service.
Without using Immutables if we were working with a simple class, then there are many ways to accomplish this. For example - annotate only the getter with #JsonIgnore. Or if possible define a different accessor method (something that doesn't have the get prefix) and only define the regular setter method... and so on.
If I try the same on the Immutables accessor method for the password as shown below:
#Value.Immutable
#Value.Style(defaults = #Value.Immutable(copy = false), init = "set*")
#JsonSersonIgnoreialize(as = ImmutableUserDto.class)
#JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {
....
#JsonProperty("password")
#JsonIgnore
public abstract String getPassword();
}
then, the generated ImmutableUserDto adds the #JsonIgnore on both the getter and setter as shown below.
#Generated(from = "UserDto", generator = "Immutables")
#SuppressWarnings({"all"})
#ParametersAreNonnullByDefault
#javax.annotation.Generated("org.immutables.processor.ProxyProcessor")
#Immutable
#CheckReturnValue
public final class ImmutableUserDto extends UserDto {
...
...
private final String password;
...
...
/**
* #return The value of the {#code password} attribute
*/
#JsonProperty("password")
#JsonIgnore
#Override
public String getPassword() {
return password;
}
...
...
...
#Generated(from = "UserDto", generator = "Immutables")
#NotThreadSafe
public static final class Builder {
...
...
private String password;
#JsonProperty("password")
#JsonIgnore
public final Builder setPassword(String password) {
this.password = password;
return this;
}
}
}
Serialization will work as expected. The password attribute will be excluded from the JSON. But when I try to de-serialize, I get the following error:
java.lang.IllegalStateException: Cannot build UserDto, some of the required attributes are not set [password]
Which is obvious as Immutables added the #JsonIgnore to the setter as well.
The documentation isn't of much help. In their Things to be aware of section, it just mentions the following regarding #JsonIgnore
If using #JsonIgnore, you should explicitly make an attribute
non-mandatory. In Immutables, an attribute can be declared as
non-mandatory via #Nullable, Optional or #Value.Default which are all
different in their effect and we do not derive anything automatically.
Using #Nullable or Optional or #Value.Default is not of any use in case of fields like password.
I have gone through the issue list on their GitHub page and there is a similar issue but the user was asking for a slightly different use case and using #Nullable could solve the problem which doesn't work in my case.
I have also tried to use one of the answers here. Still resulted in the same error.
It looked like this is not supported by Immutables library. I have created a new issue myself. Once I get some feedback from users on SOF, I will probably create a sscce.
I had to use the suggestion given by #benarena in this comment. However I had to explicitly specify the value attribute of the property along with the Access attribute.
#JsonProperty(value = "password", access = JsonProperty.Access.WRITE_ONLY) solved the problem.
The Immutable class would look like:
#Value.Immutable
#Value.Style(defaults = #Value.Immutable(copy = false), init = "set*")
#JsonSersonIgnoreialize(as = ImmutableUserDto.class)
#JsonDeserialize(builder = ImmutableUserDto.Builder.class)
public abstract class UserDto {
....
#JsonProperty(value = "password", access = JsonProperty.Access.WRITE_ONLY)
public abstract String getPassword();
}
I'm still new in mongodb, If I have a class like below and I want to set a property Role which is Object Type Property, how can I achieve it ? please check the class below
#Document(collection="User")
public class UserBean {
#Id
private String id;
private String userName;
private String password;
private RoleBean role;
}
#Document(collection="Role")
public class RoleBean {
#Id
private String id;
private String roleID;
private String roleName;
}
I need to set the UserBean's role property. So what is the best way to achieve it? Thanks.
Spring Mongo Template not saving the list of custom objects to MongoDb please see if this quation is already answered, or answer satisfies your requirements.
I'm building a rest API using Spring Boot rest services.
I have a Java class:
class Person{
int id;
#notNull
String name;
#notNull
String password;
}
And I want to make an API to create a Person object. I will recieve a POST request with json body like:
{
"name":"Ahmad",
"password":"myPass",
"shouldSendEmail":1
}
As you can see there are an extra field "shouldSendEmail" that I have to use it to know if should I send an email or not after I create the Person Object.
I am using the following API:
#RequestMapping(value = "/AddPerson", method = RequestMethod.POST)
public String savePerson(
#Valid #RequestBody Person person) {
personRepository.insert(person);
// Here I want to know if I should send an email or Not
return "success";
}
Is there a method to access the value of "shouldSendEmail" while I using the autoMapping in this way?
There's many options for you solve. Since you don't want to persist the shouldSendEmail flag and it's ok to add into you domain class, you can use the #Transient annotation to tell JPA to skip the persistence.
#Entity
public class Person {
#Id
private Integer id;
#NotNull
private String name;
#NotNull
private String password;
#Transient
private Boolean shouldSendEmail;
}
If you want more flexible entity personalizations, I recommend using DTO`s.
MapStruct is a good library to handle DTO`s
You will need an intermediary DTO, or you will otherwise have to modify person to include a field for shouldSendEmail. If that is not possible, the only other alternative is to use JsonNode and manually select the properties from the tree.
For example,
#Getter
public class PersonDTO {
private final String name;
private final String password;
private final Integer shouldSendEmail;
#JsonCreator
public PersonDTO(
#JsonProperty("name") final String name,
#JsonProperty("password") final String password,
#JsonProperty("shouldSendEmail") final Integer shouldSendEmail
) {
this.name = name;
this.password = password;
this.shouldSendEmail = shouldSendEmail;
}
}
You can use #RequestBody and #RequestParam together as following
.../addPerson?sendEmail=true
So send the “sendEmail” value as request param and person as request body
Spring MVC - Why not able to use #RequestBody and #RequestParam together
You have mutli solutions
1 - You can put #Column(insertable=false, updatable=false) above this property
2 - send it as request param #RequestParam
#RequestMapping(value = "/AddPerson", method = RequestMethod.POST)
public String savePerson(
#Valid #RequestBody Person person, #RequestParam boolean sendMail) {}
3- use DTO lets say PersonModel and map it to Person before save
I have a user object that is sent to and from the server. When I send out the user object, I don't want to send the hashed password to the client. So, I added #JsonIgnore on the password property, but this also blocks it from being deserialized into the password that makes it hard to sign up users when they don't have a password.
How can I only get #JsonIgnore to apply to serialization and not deserialization? I'm using Spring JSONView, so I don't have a ton of control over the ObjectMapper.
Things I've tried:
Add #JsonIgnore to the property
Add #JsonIgnore on the getter method only
Exactly how to do this depends on the version of Jackson that you're using. This changed around version 1.9, before that, you could do this by adding #JsonIgnore to the getter.
Which you've tried:
Add #JsonIgnore on the getter method only
Do this, and also add a specific #JsonProperty annotation for your JSON "password" field name to the setter method for the password on your object.
More recent versions of Jackson have added READ_ONLY and WRITE_ONLY annotation arguments for JsonProperty. So you could also do something like:
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
Docs can be found here.
In order to accomplish this, all that we need is two annotations:
#JsonIgnore
#JsonProperty
Use #JsonIgnore on the class member and its getter, and #JsonProperty on its setter. A sample illustration would help to do this:
class User {
// More fields here
#JsonIgnore
private String password;
#JsonIgnore
public String getPassword() {
return password;
}
#JsonProperty
public void setPassword(final String password) {
this.password = password;
}
}
Since version 2.6: a more intuitive way is to use the com.fasterxml.jackson.annotation.JsonProperty annotation on the field:
#JsonProperty(access = Access.WRITE_ONLY)
private String myField;
Even if a getter exists, the field value is excluded from serialization.
JavaDoc says:
/**
* Access setting that means that the property may only be written (set)
* for deserialization,
* but will not be read (get) on serialization, that is, the value of the property
* is not included in serialization.
*/
WRITE_ONLY
In case you need it the other way around, just use Access.READ_ONLY.
In my case, I have Jackson automatically (de)serializing objects that I return from a Spring MVC controller (I am using #RestController with Spring 4.1.6). I had to use com.fasterxml.jackson.annotation.JsonIgnore instead of org.codehaus.jackson.annotate.JsonIgnore, as otherwise, it simply did nothing.
Another easy way to handle this is to use the argument allowSetters=truein the annotation. This will allow the password to be deserialized into your dto but it will not serialize it into a response body that uses contains object.
example:
#JsonIgnoreProperties(allowSetters = true, value = {"bar"})
class Pojo{
String foo;
String bar;
}
Both foo and bar are populated in the object, but only foo is written into a response body.
"user": {
"firstName": "Musa",
"lastName": "Aliyev",
"email": "klaudi2012#gmail.com",
"passwordIn": "98989898", (or encoded version in front if we not using https)
"country": "Azeribaijan",
"phone": "+994707702747"
}
#CrossOrigin(methods=RequestMethod.POST)
#RequestMapping("/public/register")
public #ResponseBody MsgKit registerNewUsert(#RequestBody User u){
root.registerUser(u);
return new MsgKit("registered");
}
#Service
#Transactional
public class RootBsn {
#Autowired UserRepository userRepo;
public void registerUser(User u) throws Exception{
u.setPassword(u.getPasswordIn());
//Generate some salt and setPassword (encoded - salt+password)
User u=userRepo.save(u);
System.out.println("Registration information saved");
}
}
#Entity
#JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String country;
#Column(name="CREATED_BY")
private String createdBy;
private String email;
#Column(name="FIRST_NAME")
private String firstName;
#Column(name="LAST_LOGIN_DATE")
private Timestamp lastLoginDate;
#Column(name="LAST_NAME")
private String lastName;
#Column(name="MODIFICATION_DATE")
private Timestamp modificationDate;
#Column(name="MODIFIED_BY")
private String modifiedBy;
private String password;
#Transient
private String passwordIn;
private String phone;
#Column(name="RECORD_DATE")
private Timestamp recordDate;
private String salt;
private String status;
#Column(name="USER_STATUS")
private String userStatus;
public User() {
}
// getters and setters
}
You can use #JsonIgnoreProperties at class level and put variables you want to igonre in json in "value" parameter.Worked for me fine.
#JsonIgnoreProperties(value = { "myVariable1","myVariable2" })
public class MyClass {
private int myVariable1;,
private int myVariable2;
}
You can also do like:
#JsonIgnore
#JsonProperty(access = Access.WRITE_ONLY)
private String password;
It's worked for me
I was looking for something similar. I still wanted my property serialized but wanted to alter the value using a different getter. In the below example, I'm deserializing the real password but serializing to a masked password. Here's how to do it:
public class User() {
private static final String PASSWORD_MASK = "*********";
#JsonIgnore
private String password;
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public String setPassword(String password) {
if (!password.equals(PASSWORD_MASK) {
this.password = password;
}
}
public String getPassword() {
return password;
}
#JsonProperty("password")
public String getPasswordMasked() {
return PASSWORD_MASK;
}
}
The ideal solution would be to use DTO (data transfer object)