When is actually a custom validator needed in Struts2? - java

We have the validate() method directly available in our action classes in which we can put our own logic to perform some kind of validations we need.
For example, if I need to validate two fields regarding date-time, I can put my own logic in the validate() method something like the following.
public final class DiscountAction extends ActionSupport implements ValidationAware, ModelDriven<Discount>
{
private Discount entity=new Discount();
#Override
public Discount getModel() {
return entity;
}
#Override
public void validate()
{
if(entity.getDiscountStartDate()!=null&&entity.getDiscountEndDate()!=null)
{
final int period=30;
final DateTime startDate=entity.getDiscountStartDate().withZone(DateTimeZone.forID("Asia/Kolkata")).withMillisOfSecond(0);
final DateTime endDate=entity.getDiscountEndDate().withZone(DateTimeZone.forID("Asia/Kolkata")).withMillisOfSecond(0);
final DateTime currentDate=new DateTime(DateTimeZone.forID("Asia/Kolkata"));
final int daysBetween = Days.daysBetween(startDate, endDate).getDays();
if(startDate.isAfter(endDate))
{
addFieldError("discountStartDate", "The start date must be earlier than the end date.");
}
else if(startDate.equals(endDate))
{
addFieldError("discountEndDate", "Both the dates can not be same.");
}
else if(DateTimeComparator.getDateOnlyInstance().compare(currentDate, endDate)==0 || endDate.isBefore(currentDate))
{
addFieldError("discountEndDate", "Can not be today's date or any day before today.");
}
else if(Days.daysBetween(startDate, endDate).getDays()<1)
{
addFieldError("discountEndDate", "There must be an interval of at least one day.");
}
else if(daysBetween>period)
{
addFieldError("discountEndDate", "The discount period is valid only upto "+period+(period==1?" day":" days")+" period which it excceds. The actual difference is "+daysBetween);
}
}
}
}
Assuming entity is an instance of the model class.
Why do we need a custom validator here? I have not yet tried a custom validator, since it is not needed yet.
Could you please show me a real situation/example where a custom validator is precisely need?

Custom validators are used when:
You want to use annotation- or XML-based validation
You want to re-use the same validation across many actions, with the caveat that...
...if the validation already exists in external logic, which it should anyway, you can re-use it in validate methods as well
The business logic for custom validators should already exist as a separate entity. It should not exist as code embedded in an action; it makes both the action, and the validation, much harder to test.
When the logic is located in its appropriate place, it's easy to use in either a validator or a validate method. The advantage is easy re-use in XML and/or annotations.

In such point-of-view, I can also claim that Struts2 is not needed too because I can implement my web application using C++. Could you accept? I think no, because using an MVC pattern such Struts2 makes your application more clean and maintainable. Also, you do not have to redo things again yourself when they're implemented already.
In same way, if you want to use already implemented and tested best practices and also if you would like to save time and money by not doing things from scratch, and if you like maintainable codes using separated concerns ... then you need to use Struts2 custom validators instead of that ugly validate method (It's ugly because aspects such validations should not mixed with business logic - see AOP).

Related

togglz annotation based approach for feature validation

I have been using the togglz since last few days.
I am trying to find out if there is annotation based approach available in togglez API.
I want to do it like below -
public class Application {
public static void main(String[] args) {
Application application = new Application();
boolean first=false;
first=application.validate1();
System.out.println(first);
}
#Togglz(feature = "FEATURE_01")
public boolean validate1() {
System.out.println("validate1");
return false;
}
}
Is there anything available in togglz.
I could not find it anywhere , if you have any idea about such annotation please help.
My requirement is to skip the method execution based on feature value passed into it
No, there is no such annotation in Togglz. You will need some framework that support interceptors for that (like Spring, CDI, EJB). Then you can implement such an interceptor yourself.
However, to be honest I'm not sure if such an annotation would make sense. What should be the result if the feature is off? What does the method return? null? Explicit feature checks using a simple if statement are more straight forward to use in theses cases. But that's just my opinion. ;-)

Where the validation should be done in a 3 layers Entity-Repository-Service application?

I am struggling to define where the validation process would be better placed in the different layers of the application? (I am not talking about user input validation here, I'm really talking about the object consistency).
A simple case:
A Blog entity which has a field List<Comment>, and a method
boolean addComment(Comment comment)
I want to check if the comment parameter of the boolean addComment(Comment comment) is null, which would return false
To me, such a check could be done in both the Service and Entity layers to ensure that everything is consistent at any layer.
But it seems redundant and something tells me that only one layer should have that responsability.
I would say the highest one in the stack, thus the Service layer should do this validation? But when I'm writing my unit tests, it feels wrong to not make that check again in the Entity layer.
My recommendation is to put these at the "public" interfaces to the services. With any public method you can't give any kind of guarantees as to the quality of input.
Here is the reasoning:
Services may present functionality to internal code clients
As well being exposed, through a controller, to a webservice.
Dao's should never be publicly exposed so they should never need entity validation. Realistically though, they will get exposed. If you make sure that only services call dao's (and only relevant services call appropriate dao's) Then you realize dao's are the wrong place
Services represent logical choke points to the code where easy validation can occurr.
The easiest way to enforce this logic is to create an aspect and put the validation code in there.
<aop:aspect ref="validator" order="3">
<aop:before method="doValidation" pointcut="execution(public * com.mycompany.myapp.services.*.*(..))"/>"/>
</aop:aspect>
So, this aspect bean example covers all public methods in the service layer.
#Aspect
public class ServiceValidator{
private Validator validator;
public ServiceValidator() {
}
public ServiceValidator(Validator validator) {
this.validator = validator;
}
public void doValidation(JoinPoint jp){
for( Object arg : jp.getArgs() ){
if (arg != null) {
// uses hibernate validator
Set<ConstraintViolation<Object>> violations = validator.validate(arg);
if( violations.size() > 0 ){
// do something
}
}
}
}
}

Using Stripes, what is the best pattern for Show/Update/etc Action Beans?

I have been wrestling with this problem for a while. I would like to use the same Stripes ActionBean for show and update actions. However, I have not been able to figure out how to do this in a clean way that allows reliable binding, validation, and verification of object ownership by the current user.
For example, lets say our action bean takes a postingId. The posting belongs to a user, which is logged in. We might have something like this:
#UrlBinding("/posting/{postingId}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
Now, for the show action, we could define:
private int postingId; // assume the parameter in #UrlBinding above was renamed
private Posting posting;
And now use #After(stages = LifecycleStage.BindingAndValidation) to fetch the Posting. Our #After function can verify that the currently logged in user owns the posting. We must use #After, not #Before, because the postingId won't have been bound to the parameter before hand.
However, for an update function, you want to bind the Posting object to the Posting variable using #Before, not #After, so that the returned form entries get applied on top of the existing Posting object, instead of onto an empty stub.
A custom TypeConverter<T> would work well here, but because the session isn't available from the TypeConverter interface, its difficult to validate ownership of the object during binding.
The only solution I can see is to use two separate action beans, one for show, and one for update. If you do this however, the <stripes:form> tag and its downstream tags won't correctly populate the values of the form, because the beanclass or action tags must map back to the same ActionBean.
As far as I can see, the Stripes model only holds together when manipulating simple (none POJO) parameters. In any other case, you seem to run into a catch-22 of binding your object from your data store and overwriting it with updates sent from the client.
I've got to be missing something. What is the best practice from experienced Stripes users?
In my opinion, authorisation is orthogonal to object hydration. By this, I mean that you should separate the concerns of object hydration (in this case, using a postingId and turning it into a Posting) away from determining whether a user has authorisation to perform operations on that object (like show, update, delete, etc.,).
For object hydration, I use a TypeConverter<T>, and I hydrate the object without regard to the session user. Then inside my ActionBean I have a guard around the setter, thus...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}
where accessible(posting) looks something like this...
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}
Then your show() event method would look like this...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}
Separately, when I use Stripes I often have multiple events (like "show", or "update") within the same Stripes ActionBean. For me it makes sense to group operations (verbs) around a related noun.
Using clean URLs, your ActionBean annotations would look like this...
#UrlBinding("/posting/{$event}/{posting}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
...where {$event} is the name of your event method (i.e. "show" or "update"). Note that I am using {posting}, and not {postingId}.
For completeness, here is what your update() event method might look like...
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}

Best design pattern to implement upload feature

I am working on a web application which is based on spring MVC. We have various screens for adding different domain components(eg. Account details, Employee details etc). I need to implement an upload feature for each of these domain components i.e. to upload Account, upload employee details etc which will be provided in a csv file (open the file, parse its contents, validate and then persist).
My question is, which design pattern should i consider to implement such a requirement so that upload (open the file, parse its contents, validate and then persist) feature becomes generic. I was thinking about using the template design pattern. Template Pattern
Any suggestions,pointers,links would be highly appreciated.
I am not going to answer your question. That said, let me answer your question! ;-)
I think that design patterns should not be a concern in this stage of development. In spite of their greatness (and I use them all the time), they should not be your primary concern.
My suggestion is for you to implement the first upload feature, then the second and then watching them for what they have that is equal and create a "mother" class. Whenever you come to a third class, repeat the process of generalization. The generic class will come naturally in this process.
Sometimes, I believe that people tend to over engineer and over plan. I am in good company: http://www.joelonsoftware.com/items/2009/09/23.html. Obviouslly, I am not advocating for no design software - that never works well. Nevertheless, looking for similarities after some stuff has been implemented and refactoring them may achieve better results (have you already read http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?ie=UTF8&qid=1337348138&sr=8-1? It is old but stiil great!).
A strategy pattern my be useful here for the uploader. The Uploader class would be a sort of container/manager class that would simply contain a parsing attribute and a persistance attribute. Both of these attributes would be defined as an abstract base class and would have multiple implementations. Even though you say it will always be csv and oracle, this approach would be future-proof and would also separate the parsing/verifying from the persistence code.
Here's an example:
class Uploader
{
private:
Parser parser_;
Persistence persistence_;
void upload() {
parser_.read();
parser_.parse();
parser_.validate();
persistence_.persist(parser_.getData());
}
public:
void setParser(Parser parser) {parser_ = parser;}
void setPersister(Persistence persistence) {persistence_ = persistence;}
};
Class Parser
{
abstract void read();
abstract void parse();
abstract void validate();
abstract String getData();
};
class Persistence
{
abstract persist(String data);
};
class CsvParser : public Parser
{
// implement everything here
};
// more Parser implementations as needed
class DbPersistence : public Persistence
{
// implement everything here
};
class NwPersistence : public Persistence
{
// implement everything here
};
// more Persistence implementations as needed
You could use an Abstract Factory pattern.
Have an upload interface and then implement it for each of the domain objects and construct it in the factory based on the class passed in.
E.g.
Uploader uploader = UploadFactory.getInstance(Employee.class);

Play 2.0/Java - Is there a way to get the validation done post request data binding?

In play 2.0 you can get the request binding with validation done (via annotations) by :
ABCForm abcForm=(ABCForm)form(ABCForm.class).bindFromRequest().get();
The problem I have is , I want to get the validation done after trimming the form values.
So is there a way to either defer or call the validation stuff post binding in play 2.0 ?
Binding and validation are combined. So validation after the binding is not possible, as far as I know. However you can create a validate() method, in which you trim your values before validating them. For example:
public class User {
public String name;
public String validate() {
name.trim
if(name == "") {
return "Name is required";
}
return null;
}
}
The validate() method will be invoked when you bind a form. So you can make sure your data is valid, but errors won't be automatically added to the Form.Field objects. So it is certainly a nice solution.
There are also pretty much discussions about Form validation in Play's Google Group, so if you want to know more about the binding/validation problems I recommend reading them: https://groups.google.com/forum/#!searchin/play-framework/%5B2.0%5D$20validation.
If you need to modify your values before validation. You can create a setter for your field and do your trims there.

Categories

Resources