Announcement Announcement Module
Collapse
No announcement yet.
Using springframework.validation instead of throwing exception (not in MVC) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using springframework.validation instead of throwing exception (not in MVC)

    If this is in the wrong forum, please point me to the right one.

    I'm considering using Spring's validation framework at my service layer, instead of throwing exceptions. I like the idea because it allows multiple exception cases to be reported at once, and because of the Errors class's support for resolvable error codes.

    e.g. my methods are going to be

    Code:
    doJob(Object argument, Errors errors)
    instead of

    Code:
    doJob(Object arguments) throws JobException
    But I have two questions:

    - Has this been proven to work in real life? The validation class javadoc keeps referring to web objects, like "usually your form controller does this for you", so has the validation been proven for usability without web dependencies? Does it scale, such that other machine clients (as opposed to web users) can run the methods efficiently?

    - How does Spring suggest I create an Errors instance, when calling these methods? Is there anything cleaner than:

    Code:
    Greeting greeting = new Greeting("hello");
    DataBinder dataBinder = new DataBinder(greeting);
    Errors errors = dataBinder.getBindingResult();
    doJob(greeting, errors);
    And is it really a good idea to make the consumer do that work? Does it tend to work better if the service method creates its own Errors object (and then, probably, wraps it in an Exception and throws it)?

    If anyone has already gone down this road, I would very much appreciate the wisdom of experience.

    Thanks,
    - Travis

  • #2
    Originally posted by trav View Post
    Has this been proven to work in real life? The validation class javadoc keeps referring to web objects, like "usually your form controller does this for you", so has the validation been proven for usability without web dependencies? Does it scale, such that other machine clients (as opposed to web users) can run the methods efficiently?
    Spring validation is not tied to web environment at all. If you keep your validators stateless there is no issue with scaling.

    Originally posted by trav View Post
    And is it really a good idea to make the consumer do that work? Does it tend to work better if the service method creates its own Errors object (and then, probably, wraps it in an Exception and throws it)?
    I would not add a framework class or interface (Errors in this case) to the service interface (doJob()). Did you take AOP for validation into consideration?

    Joerg

    Comment


    • #3
      I would not add a framework class or interface (Errors in this case) to the service interface (doJob()). Did you take AOP for validation into consideration?
      Do you have AOP code for this example in mind, or could you point to an example? All I can think is that AOP would provide a looser coupling between the service method and its validation output, but it's a coupling nonetheless. Somehow the consumer (at compile time) needs to know how to access and read error output.

      In this case, I imagine the AOP code would be pretty tricky, because a lot of other services (persistence, etc.) need to be invoked in order to determine whether the input is valid.

      Comment


      • #4
        Originally posted by trav View Post
        Do you have AOP code for this example in mind, or could you point to an example?
        No, it was only an idea based on the dislike to couple validation to service, especially coupling the validation framework to the service. I worked on code where validation happens on the beginning of the service method - just because of the validation this code was mostly not reusable.

        Originally posted by trav View Post
        All I can think is that AOP would provide a looser coupling between the service method and its validation output, but it's a coupling nonetheless.
        First the service has no idea of validation and especially it has no idea of the validation framework. These are major advantages. I wonder what exactly you consider as coupling with this approach.

        Originally posted by trav View Post
        Somehow the consumer (at compile time) needs to know how to access and read error output.
        My idea is probably not thought out What are your choices with the AOP approach? I see two, either throwing an unchecked (otherwise you'll get a UndeclaredThrowableException) exception with the complete validation results (Errors object) as parameter or storing the validation results in a ThreadLocal validation context from where you can access it from what you call consumer.

        Originally posted by trav View Post
        In this case, I imagine the AOP code would be pretty tricky, because a lot of other services (persistence, etc.) need to be invoked in order to determine whether the input is valid.
        Can't follow on this one.

        Joerg

        Comment


        • #5
          I think this is what I'm failing to convey:

          I'm not just talking about making sure a field isn't blank. I'm talking about a request like buying an item in a store, where the request can be invalid for a number of stateful reasons (item is out of stock, user doesn't have enough money in account, can't ship the item to the user's country, etc.).

          This means that the error reporting objects must communicate with the service logic. It means that the service needs to consult other state (quantity in stock, user's money balance, user's country, etc.).

          I realize this is not the purpose for which the validation piece was built. However, if you look at its design you'll see that it's perfectly suited to do what I'm trying to do. What I'm still trying to figure out is how to invoke the validation objects. An AOP invocation framework may not be suitable _because_ the validation pieces need to communicate with the service.

          This is not unusual. It happens in the most common Validation application: Spring MVC. In Spring MVC, controllers accept an Errors object when they're processing (not validating) the form. Controllers do their business, and if an error happens, they can report it via the Errors object.

          I can use a similar model here, except I don't have the benefit of internal Spring code to instantiate and consume the Errors object itself. So of course I'm concerned whether the lifecycles of the Errors objects (and related objects) are easy to control with code. _How_ to inject that control code -- in AOP, XML files, OOP, etc -- may be another discussion.

          Does that make sense?

          Comment


          • #6
            As far as I understand your requirements go far beyond validation to actual business logic. What you really want to do is just to reuse the validation or error reporting framework. Considering this I think your approach makes indeed much sense. In this case you can just pass the controllers Errors instance to the service though. I don't see why you need to create your own.

            Joerg

            Comment


            • #7
              You seem to have better understood my intent now, but I must reiterate the "(not in MVC)" part of the title. As I understand it, having a "controllers Errors instance" means I'm part of a controller. What if I'm not?

              Surely if the validation framework is intended to exist outside of MVC, the ability for end consumers to create Errors objects must have been considered.

              Even if I am an MVC controller, my Errors object is bound to a target Object, which is probably a web-layer bean, and I have no reason to believe that the service method wants an Errors that's bound to the same target Object.

              So, still looking for the prescribed simple way to construct an Errors instance.

              Comment


              • #8
                So did it work ?

                Hello Travis,

                Sorry to jump on an old thread, but I have a similar idea in mind, wanted to know if you were successful in implementing the soln, pointers would be helpful. Thank you in advance

                Comment

                Working...
                X