Is there any way to avoid duplicating attributes in this code? - java

Hi i want to know if exist a way to avoid duplicate code in this code. Now i have an action class named CustomerAction this class handle the behaviour of the request (it's like a controller) and i have a CustomerPOJO with attributes like id, name, last_name etc. Now i have to add attributes to CustomerAction to handle the data submited from the form. Is there any way to bypass the action with my CustomerPOJO ?
public class CustomerAction {
private String nombre;
private String apellido;
private String dni;
private String fechaNac;
private String obraSocial;
private String nroAsociado;
private String plan;
private String password;
private String email;
private String telParticular;
private String telCelular;
private static final Log log = LogFactory
.getLog(CustomerAction.class);
public String execute() throws Exception {
if ("cancelar".equals(this.getAccion())) {
log.debug("Executing 'cancelar' action");
return "login";
}
if ("registro".equals(accion)) {
log.debug("Executing 'registro' action");
IReferenceDataBusinessDelegate ud = new ReferenceDataBusinessDelegate();
ud.signCustomer(this.getNombre(), this.getApellido(),
this.getDni(), this.getCorreo(), this.getContrasena());
return "login";
}
}
public class Customers implements java.io.Serializable {
private long id;
private String dni;
private String name;
private String lastName;
private String email;
private String password;
private String phone;
private String cellphone;
private Date birthDate;
private Date creationDate;
private Date lastAccessDate;
private byte active;
private Set<Profesionales> profesionaleses = new HashSet<Profesionales>(0);
private Set<Pacientes> pacienteses = new HashSet<Pacientes>(0);
public Customers() {
}
}

Yes, use ModelDriven, and use a Customers as the model.
http://struts.apache.org/2.x/docs/model-driven.html
You'll need to make sure the "modelDriven" interceptor is in your stack.
How/where to initialize the model depends on your particular usage scenario; you can do it in a getter as shown in the docs, in a prepare() method if you need to reload it from the DB, etc.
I'm not sure what you mean by "bypass the action."
Please note that the ad-hoc dispatch mechanism implemented here with the accion parameter duplicates functionality provided by Struts 2 using the method attribute of the action configuration. I don't recommend using ad-hoc dispatch mechanisms as it makes understand program flow more difficult than necessary.

Related

vavr add nested validations with validations combine

I have an input object as
class Person {
private String name;
private String email;
private String phone;
private Address address;
public static class Address {
private String city;
private String pincode;
private String street;
private AddrDetails details;
public static class AddrDetails {
private String state;
private String country;
}
}
}
I am using vavr Validations to validate the input
public static Validation<Seq<ConstraintViolation>, PersonDetailsModel> validatePerson(PersonDetailsRequest request) {
Validation
.combine(
validateName("name", request.getName()),
validateEmail("email", request.getEmail()),
validatePhone("phone", request.getPhone()),
validateAddress(request.getAddress())
).ap((name, email, phone, address) -> new PersonDetailsModel(name, email, phone, address);
}
public static Validation<Seq<ConstraintViolation>, Person.Address> validateAddress(
Person.Address request) {
return Validation
.combine(..
).ap((..) -> new Person.Address(..);
}
In the second function, it returns Seq of ConstraintViolation while validatePerson expects only ConstraintViolation which is why it is failing although I have to add one more level of nesting of validations for AddrDetails. How to handle nested objects validations with this approach.
I am not sure about how shall I go ahead?
In our project we call .mapError(Util::flattenErrors) after .ap. I have the feeling that there is a better way, but this at least solves the nesting.
The method in the Util class looks like this :
public static Seq<ConstraintViolation> flattenErrors(final Seq<Seq<ConstraintViolation>> nested) {
return nested
.flatMap(Function.identity())
.distinct(); // duplicate removal
}

Parsing to Object api fields like eMail, bNumber, iKindCd causes null value

I try to parse reponse from Api to my custom object.
Most fields are parsed correctly, except fields named like: eMail, iKindName, bNumber, uTypeName, iStartDT, iKindCd, uTypeCd (first small, second capital letter)
In fields like that I have null values if I use my custom object ResponseV2.
If I use Object type instead of ResponseV2 - fields eMail, iKindName, bNumber, uTypeName, iStartDT, iKindCd, uTypeCd are not null
Whats wrong with that fields (with pattern: first small and second capital letter) in my ReponseV2? Should I use some annotations, like #JsonProperty here?
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
#Data
public class ResultV2 implements Serializable {
private String country;
private String federationNumber;
private String city;
private String regon;
private String managerSurname;
private String countryCd;
private String pib;
private String institutionUuid;
private String lNumber;
private String siTypeName;
private String managerName;
private String ministryNumber;
private String eMail;
private String supervisingInstitutionID;
private String nip;
private String street;
private String www;
private String espAddress;
private String voivodeship;
private String id;
private String iKindName;
private String federationComposition;
private String lastRefresh;
private String postalCd;
private String bNumber;
private String panNumber;
private List<BranchesV2> branches;
private String krs;
private String supervisingInstitutionName;
private String iLiqStartDT;
private String eunNumber;
private String uTypeName;
private String institutionUid;
private String phone;
private String iStartDT;
private String iLiqDT;
private String name;
private String iKindCd;
private String siTypeCd;
private String yearPib;
private String uTypeCd;
private String dataSource;
private String voivodeshipCode;
private String status;
private String statusCode;
}
I have solution: it works if I have
#JsonProperty ("eMail") private String eMail;
instead of
private String eMail;
But why?
Lombok #Data annotation is generating setter method as
public void setEMail(final String eMail) {
this.eMail = eMail;
}
However json mapper expects the setter method to be with lower case letter e like in example below, so it could not find the method.
public void seteMail(final String eMail) {
this.eMail = eMail;
}
Just use JsonProperty like #JsonProperty("eMail") on those fields. It would work fine.
Here is a detailed explanation on why it work like this: Why does Jackson 2 not recognize the first capital letter if the leading camel case word is only a single letter long?

Morphia - custom field with custom reader and writer

I want to add a custom type of field that will have a default behaviour.
my purpose is to handle all type of secret fields:
for example:
I have password field on user class, and I want password field to be encrypted on some way, so instead of:
#Entity
public static class User {
String name;
String pwd;
String pwdToken
public User() {
}
public User( string name, string password ) {
super();
this.pwd = password;
}
}
and then managing the decrypt and encrypt from outside - service or controller
I would have something like that:
#Entity
public static class User {
String name;
SecretField pwd;
public User() {
}
public User( string name, string password ) {
super();
this.name = name;
// this.pwd.set(password)
}
}
public final class SecretField implements Serializable {
private static final long serialVersionUID = 1L;
private String encryptedContent;
private String token;
public SecretField(String content) {
this.token = generateToken();
this.encryptedContent = decrypt(content, this.token);
}
// when especially called the decrypted pwd will be returned
public decrypt(){
decrypt(encryptedContent, token)
}
//here I should override the default output object - return this.encryptedContent instead of whole object
//???
}
This way, every time I have a secret field I can just use this class and the encrypting will be done automatically, And I won't need to manage the on each controller seperatly.
On update and insert, the password will be sent as decrypted string from client and on get the enrypted string will be returned.
Is it possible with morphia?
You can write a custom codec in 2.0 to do that for you. Prior to that you could write a life cycle event handler to do that. The docs for that can be found at https://morphia.dev

How can I avoid DTOs duplication without inheritance?

I am connecting with many social networks for login in my application.
I have one DTO for each social network response.
public class GoogleUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private AgeRange ageRange;
// more specific fields
}
public class FacebookUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private String picture;
// more specific fields
}
public class AppleUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private Boolean emailVerified;
// more specific fields
}
In each social network connector, I make similar steps to fetch the information, so I thought I could go with some DTO as follows:
public class SocialNetworkInfo {
protected String id;
protected String firstName;
protected String lastName;
protected String email;
}
Social networks DTOs could extend this to obtain the common fields. Then I could use this generic DTO to implement an abstract connector that deals with all the duplicate logic between connectors (make request, parse response, etc...):
abstract class AbstractConnector {
abstract SocialNetworkInfo fetchUserInfo(String networkId);
...
}
But I realized that above, in my service layer, I would need those specific fields to make some changes and operations.
SocialNetworkInfo networkUserInfo = facebookConnector.fetchUserInfo(facebookId);
facebookService.updatePicture(networkUserInfo.getPicture()); // can't access this specific field
What do you think that's the best way to go through this situation without casting and avoiding logic or DTO duplication?
Would love to hear your thoughts.
Thanks!
According to your situation, all social network models have the same nature, so it's ok if you move common attributes to shared class like CommonSocialInfo. Then I would recommend to provide interface for the connectors like:
interface SocialNetworkConnector<T extends SocialNetworkInfo> {
T fetchUserInfo(String userId);
}
Of course for common functionality(for connectors) is great idea to define common abstract class that implements interface above (implement Template pattern). I see that you are using FacebookService and related connector separately. I think that good idea to use composition in this case and make SocialNetworkService dependent on it connector. In short, FacebookService depends on FacebookConnecter and so on. Just a quick example:
public class FacebookService implements SocialNetworkService {
private final SocialNetworkConnector<FacebookSocialInfo> connector;
...
}
And if you need to implement multiple social service, you can use Factory pattern to produce required service, quick example:
interface SocialNetworkServiceFactory {
SocialNetworkService getFacebookService();
...
}
If you need more detailed help or you have troubles with understanding of the idea - feel free to ask!
If you don't want to use inheritance, I'd suggest to consider composition. The code can look as follows:
public class SocialNetworkInfo {
private String id;
private String firstName;
private String lastName;
private String email;
}
public class GoogleUserInfo {
private SocialNetworkInfo socialNetworkInfo;
private AgeRange ageRange;
// more specific fields
}
public class FacebookUserInfo {
private SocialNetworkInfo socialNetworkInfo;
private String picture;
// more specific fields
}
public class AppleUserInfo {
private SocialNetworkInfo socialNetworkInfo;
private Boolean emailVerified;
// more specific fields
}

JUNIT Test for partial update with java springboot mongodb

Hello I am new to JUnit test and Mockito and my question is how can I write a unit test for this custom partial update method in my customArticleRepository, which has no return parameter?
I have a POJO object named Article and I would like to partially update it. The REST endpoint PUT get a DTO Object Classification Mask with the specific updated value as request body, call the Service layer ArticleService, which call my CustomArticleRepository method.
this is my Article object
public class Article {
private String id;
#Field("_cls")
private String inheritance;
private String title;
private Date published;
private String content;
private String link;
private String summary;
private String description;
private Date updated;
private String primary;
private String[] secondary;
private String category;
private String[] categories;
private String person;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
private Date deleted_date;
private Boolean is_new;
private Boolean edited;
private Aws aws;
this is my DTO Object
public class ClassificationMask {
private String id;
private String title;
private String content;
private String primary;
private String[] secondary;
private Float sentiment_positive;
private Float sentiment_negative;
private Float sentiment_neutral;
private Float sentiment_mixed;
private String category;
private String person;
private Boolean is_new;
private Datasource datasource;
and this is my partialupdate method in the repository
public void partialUpdateMask(String id, ClassificationMask articleUpdate) {
Query query = new Query(where("id").is(id));
Update update = new Update();
if(articleUpdate.getPrimary() !=null) { update.set("primary", articleUpdate.getPrimary()); }
if(articleUpdate.getSecondary() !=null){ update.set("secondary", articleUpdate.getSecondary());}
if(articleUpdate.getCategory() !=null){ update.set("category", articleUpdate.getCategory());}
if(articleUpdate.getPerson() !=null){ update.set("person",articleUpdate.getPerson());}
if(articleUpdate.getIs_new() !=null){ update.set("is_new",articleUpdate.getIs_new()); }
update.set("edited",true);
mongoTemplate.updateFirst(query,update ,Article.class);
}
Testing void method we could have:
Method that modifies the status of the object under test: so you can verify that the state of the sut is consistent with your aspectative
Method doesn't modify the status of the SUT but, for example, writes data on the DB so you can verify that your DAO is invoked
This is the second case and you can have something like this:
Mockito.verify(mongoTemplate).updateFirst(query, update, Article.class);
In this manner you're testing that
the method really calls updateFirst
the method calss updateFirst using the right parameters

Categories