J'ai un passeur personnalisé dans mon POJO basé à Lombok:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
public void setPassword(String password) {
Assert.notNull(password);
this.password = ENCODER.encode(password);
}
mais quand j'utilise le constructeur généré par Lombok:
User user = User.builder()
.password(password)
.build();
mon configurateur personnalisé n'est pas appelé et le mot de passe n'est donc pas codé. Cela me rend triste.
Mon configurateur personnalisé est, bien sûr, appelé lorsque je l’utilise directement:
public void changePassword(String password, User user) {
user.setPassword(password);
}
Que puis-je faire pour que le constructeur de Lombok utilise mon configurateur personnalisé?
Per la documentation pour @Builder
: Définissez juste assez de squelette vous-même. En particulier, Lombok générera une classe UserBuilder
, des champs reflétant les champs User
et des méthodes de générateur, que vous pourrez fournir vous-même.
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String username;
private String password;
public static class UserBuilder {
public UserBuilder password(String password) {
this.password = ENCODER.encode(password);
return this;
}
}
}
J'ai accepté la réponse de chrylis mais pour être complet, voici quelques moyens de minimiser la personnalisation et la duplication.
Installateur et constructeur personnalisés avec assistant statique
Un assistant statique peut être utilisé pour partager la plupart des fonctionnalités définies du mot de passe via la méthode personnalisée User.UserBuilder::password
Et la commande personnalisée User::setPassword
méthode:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
public void setPassword(String password) {
this.password = _encodePassword(password);
}
public static class UserBuilder {
public UserBuilder password(String password) {
this.password = _encodePassword(password)
return this;
}
}
private static String _encodePassword(String password) {
Assert.notNull(password);
return ENCODER.encode(password);
}
}
configurateur et constructeur personnalisés
Un constructeur personnalisé peut utiliser User::setPassword
Qui est appelé par le User.UserBuilder::build()
généré par Lombok:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
User(String password) {
setPassword(password);
}
public void setPassword(String password) {
Assert.notNull(password);
this.password = ENCODER.encode(password);
}
}
Installateur et constructeur personnalisés avec assistant statique
Ou, un peu plus élégamment, avec un constructeur personnalisé et une méthode d'assistance statique:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
User(String password) {
_encodePassword(password, this);
}
public void setPassword(String password) {
_encodePassword(password, this);
}
private static _encodePassword(String password, User user) {
Assert.notNull(password);
user.password = ENCODER.encode(password);
}
}
Vous utilisez setPassword plutôt que la méthode set du générateur.
Voici ce qui a fonctionné pour moi:
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class User {
private String username;
private String password;
public static class UserBuilder {
private String password;
public UserBuilder password(String password ) {
this.password ="ENCRIYP " + password;
return this;
}
}
public static void main(String[] args) {
System.out.println(User.builder().username("This is my username").password("Password").build().toString());
}
}
Le résultat était: User(username=This is my username, password=ENCRIYP Password)