June 27th 2008 05:33 pm

Challenge: how to validate in this java webapp?

Assumptions:

  1. App is built on Struts2 (S2) and Spring and Hibernate in pretty much standard way
  2. Service layer (Spring and everything behind) works independently from web layer (S2), meaning all service methods return complete needed data; TXs are closed on service method end.
  3. App is using Spring-configured TX manager, uses Springs AspectJ aspects support, S2 uses its default UI tags, all very common.

User enters some data that has to be validated. This is what is going on:

  1. On submit, S2 will take all user.* HTTP parameters and inject into FooAction.setUser(), e.g. user.email will be stored as FooAction.getUser().setEmail().
  2. Mapped action method in FooAction will do some preparing and then will call FooService.haveFunWithUser(user).
  3. Service will do its (fun:) job and return the results.
  4. FooAction will prepare output, so S2 can render the result page.

Nothing new. Now, the challenge: add transparent validation in the service layer, but don’t change much the S2 layer (or any other possible client).

Let’s do some loud thinking: if we need to add validation to the service layer, we can use some bean validation library, such as Hibernate Validator, to define validation rules on domain objects. Since domain objects are used as arguments in the service methods, we can add an aspect that will validate those arguments before proceeding with the service method. So now, the challenge is actually how to pass the error information back from this point? Since validation should be transparent, we can throw some unchecked validation exception that will holds all information about invalid values i.e. method arguments. On the S2 side, we can catch such exception in an simple interceptor and then….

… then what? If we want to use S2 up to the end, we need to add errors with addFieldError() where first argument is the field name used on HTML page (i.e. action property name). Lets say that we have some errors on email field. How to bind the returned validation errors with actual property name (’user.email’)?

Obviously, this has to be solved on web layer, since service is not aware of used client. I have few ideas how to do this, but I would like to hear some experiences on above approach?

Anyone?

If you enjoyed this post, make sure you subscribe to my RSS feed!


2 Comments »

2 Responses to “Challenge: how to validate in this java webapp?”

  1. Vladimir on 11 Jul 2008 at 12:43 pm #

    Here’s what I do…

    First, I wrap return values of service routines in a small object that contains both the service final result (true or false) and error description (String) and error cause (Object), if validation error occurs.
    So, in Web (action) layer methods i have something like this:

    ServiceResult sr = myService.myServiceRoutine (arg1, arg2, arg3,…);
    if (sr.result == false) {
    String errField = getErroneousFieldName(sr.errorCause);
    //standard error handling …..
    }

    this method, getErroneousFieldNames() takes Object that caused the error (brought to it by service layer) and performs introspection to all fields of the action class, and when it finds the field that matches the errorCause object it returns its name, or reference, or whatever needed, which is then further used for standard web layer error handling.

    In order to facilitate this error handling, I made an abstract class that all actions must extend, which in turn contains the getErroneousFieldNames() method.

    So, action classes are no longer “pure” POJOs, but this is as close to it as I was able to reach. And, of course, values injections (from web pages) work.

    All this works presuming that action method passes to service layer exatly those objects that have been injected with values, i.e. objects that contain information on error handling.

  2. Half-life of xanax. on 27 Aug 2008 at 11:56 pm #

    Xanax….

    Xanax. Xanax with 5-htp….

« SUPPORTS propagation is used by wimps |

  •  

    June 2008
    M T W T F S S
    « May    
     1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30