Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Spring MVC and exception handlers

  1. #1
    Join Date
    Aug 2004
    Location
    France - Saint Nazaire
    Posts
    79

    Default Spring MVC and exception handlers

    Hi,

    I try to develop an handler to catch all exceptions from my service layer to convert them ( with i18n ) to errors in order to show them in the current page.
    Is there already this mechanism implemented in Spring MVC? Is there classes to represent errors ( like Errors for the validation )?
    Thanks for your help,
    Thierry

  2. #2

    Default

    This is how we are doing this. We extend RuntimeException and store

    /** key to error text found in messages.properties file */
    private String errorProperty;
    /** Object array that will be used if there are any variables in the error text */
    private Object[] values;
    /** If the errorProperty key is not found in messages.properties this default value will be used as the error text instead */
    private String defaultMessage;

    public String getErrorMessage(int index, javax.servlet.http.HttpServletRequest request)
    {
    ResourceBundleMessageSource r = new ResourceBundleMessageSource();
    r.setBasename("messages");
    Locale locale = RequestContextUtils.getLocale(request);
    return r.getMessage(errorProperty,values,defaultMessage,l ocale);
    }

    In the Error Handler code we just call getErrorMessage on the error to get the correct message.

  3. #3
    Join Date
    Aug 2004
    Location
    France - Saint Nazaire
    Posts
    79

    Default

    Thanks for your answer.
    How can I configure a SimpleMappingExceptionResolver in Spring XML configuration file? Which class must I implement?
    As a matter of fact I'm looking for a complete example...
    Thierry

  4. #4

    Default

    public class ApplicationErrorHandler implements HandlerExceptionResolver, Ordered
    {
    protected final Log logger = LogFactory.getLog(getClass());
    private int order;

    /**
    * <p>Handles all unhandled ApplicationErrors</p>
    * <p>Displays error messages and a back link</p>
    */
    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response,
    Object handler,
    Exception e)
    {
    if (e instanceof ApplicationError)
    {
    ApplicationError x = (ApplicationError)e;
    Map myModel = new HashMap();
    int size = x.getErrorMsgSize();
    ArrayList messages = new ArrayList();
    for (int i = 0; i < size; i++)
    {
    messages.add(x.getErrorMessage(i,request));
    }
    myModel.put("messages", messages);
    return new ModelAndView("Message", "model", myModel);
    }
    else
    return null;
    }

    /**
    * Used by spring configuration to decide the order that the handler will be invokes
    * in relation to other handlers
    */
    public int getOrder()
    {
    return order;
    }

    public void setOrder(int order)
    {
    this.order = order;
    }
    }

    In your config xml file...

    <bean id="handler1" class="com.scsis.presentation.common.ApplicationEr rorHandler">
    <property name="order"><value>1</value></property>
    </bean>

  5. #5
    Join Date
    Aug 2004
    Location
    France - Saint Nazaire
    Posts
    79

    Default

    Hi bobmanc,

    Thanks a lot for your answer. That's exactly what I need...
    Thierry

  6. #6
    Join Date
    Oct 2004
    Location
    Kuala Lumpur
    Posts
    7

    Default

    Hi,
    is there any way how to direct the error handler to the same view (eg if the exception was thrown after submission of a form, display the errors in the view with the form)?

    Thank you very much

    Peter

  7. #7
    Join Date
    Aug 2004
    Location
    France - Saint Nazaire
    Posts
    79

    Default

    Hi Peter,

    I think that it's to you to develop it ;-)

    The object that resolveException gives you, is the instance of the controler where exception occurs.

    public class MyExceptionHandler implements
    HandlerExceptionResolver,Ordered {
    private int order;

    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response,Object handler,Exception e) {
    ...
    }
    ...
    }

    I think that you can use an interface on your controler that must implements to give the name of the return of the form. Depending on the thrown exception ( or you want to do ), you can put it in ModelAndView objet with the description of the exception.
    If the controler doesn't implement the interface, you can forward on a default page to show errors and / or exceptions messages.
    Hope it helps you,
    Thierry

  8. #8
    Join Date
    Oct 2004
    Location
    Kuala Lumpur
    Posts
    7

    Default

    Hi Thierry,
    thanks for hints - I will check it out and try to figure out the returning view based on that.

    Anyways, this is only a part of my bigger question about the business layer validation. I wouldn't want to couple business logic validation (e.g. checking credit status for customer who placed the order, etc.) with the presentation layer. However, I am not sure how to invoke a validation object (implementing Validator) from business layer and (mainly) propagate the possible 'rejections' to the presentation layer.

    All the examples use just overly simple validation testing only if the value is present (which is okay to invoke from presentation layer), however, I need to figure out where to put the 'real' validation in order to go WITH the Spring architecture and not against it

    Thanks for help

    Peter

  9. #9
    Join Date
    Aug 2004
    Posts
    109

    Default

    your last question is quite different one from what was asked originally and should probably be addresses on the architecture forum.

    But here are a few thoguhts:

    Your business layer should throw 2 kinds of exceptions, checked and unchecked.

    If your BL is throwing a checked exception, it usually means that the user is capable of fixing the error by providing different parameters on the request (hopefully thru a form you designed). In this case you should be able to report to the user what was the problem and redisplay the form for resubmission.

    If your BL throws the runtime exception (unchecked), there is really nothing you can do about ... from your presentation layer developer's perspective. So, just design an exception page and inform the user of the fact that there is something wrong with the system they should try again later or relogin and try again the same operation or design your own way of dealing with the situation.

    Now back to your question about BL validation. We have to look here at the kinds of validations you would regularly perform on your presentation layer (PL) and on your business layer. If you think about it, it is quite obvious they are very different.

    PL validations are lightweight (by this I mean they usually need no db connection, no server-side resources, etc.) and they can very often be performed on the client side alltogether, without the need for roundtrip to the server. Theese are validations for required fields and dates being in an acceptable format, and required fields if another field is specified, etc. That is the reason you see examples of them, that seemingly not giving you the real life examples. They actually are real life but only for PL of your system. Now if you turn to the BL of your system that is what's usuall missing from the examples or maybe not emphasized enough.

    BL validation is different, because you really need to make sure that for example you can add a new item to the collection that is owned by some containing entity. Another good example would be to check for the validity of the email address by contacting the mail server of the destination email server and asking if the email is valid (note: this will not always work, because some servers are not online all the time :-)). Contrast this with the validation of the email by simply looking for the @ sign to be there and ending in (.com, .edu ...), which is obviously a PL validation. BL can validate against simple stuff just like the PL did, but not neccesarily so, since if you have your BL collocated with your PL you will know for sure that the PL already did the validation so you can skip it in BL. However, if the BL is accessible by different PLs (think of web PL, rich client PL or some B2B agent accessing your business layer), you can not trust the validity of the data sent to you (think of the B2B agent), you will have to include the simple validation in your BL too. This is where optimization you talked about (propagating the validations to the BL) would be usefull.

    So, to wrap up the post it basically all boils down to what is the architecture of your system. Where each of the parts are and how much you can trust the agent that is accessing you BL. My guess is that the majority of the projects is probably falling into the category of collocated PL and BL so no duplication of validations needed, and spring is pretty good at this kind of stuff. If you have a different design you will need to think of what are the validation that you will have to perform and where to place your optimizations

    HTH
    Thanks,
    Alex.

  10. #10
    Join Date
    Aug 2004
    Location
    France - Saint Nazaire
    Posts
    79

    Default

    Quote Originally Posted by bpolka
    your last question is quite different one from what was asked originally and should probably be addresses on the architecture forum.

    But here are a few thoguhts:

    Your business layer should throw 2 kinds of exceptions, checked and unchecked.

    If your BL is throwing a checked exception, it usually means that the user is capable of fixing the error by providing different parameters on the request (hopefully thru a form you designed). In this case you should be able to report to the user what was the problem and redisplay the form for resubmission.

    If your BL throws the runtime exception (unchecked), there is really nothing you can do about ... from your presentation layer developer's perspective. So, just design an exception page and inform the user of the fact that there is something wrong with the system they should try again later or relogin and try again the same operation or design your own way of dealing with the situation.

    Now back to your question about BL validation. We have to look here at the kinds of validations you would regularly perform on your presentation layer (PL) and on your business layer. If you think about it, it is quite obvious they are very different.

    PL validations are lightweight (by this I mean they usually need no db connection, no server-side resources, etc.) and they can very often be performed on the client side alltogether, without the need for roundtrip to the server. Theese are validations for required fields and dates being in an acceptable format, and required fields if another field is specified, etc. That is the reason you see examples of them, that seemingly not giving you the real life examples. They actually are real life but only for PL of your system. Now if you turn to the BL of your system that is what's usuall missing from the examples or maybe not emphasized enough.

    BL validation is different, because you really need to make sure that for example you can add a new item to the collection that is owned by some containing entity. Another good example would be to check for the validity of the email address by contacting the mail server of the destination email server and asking if the email is valid (note: this will not always work, because some servers are not online all the time :-)). Contrast this with the validation of the email by simply looking for the @ sign to be there and ending in (.com, .edu ...), which is obviously a PL validation. BL can validate against simple stuff just like the PL did, but not neccesarily so, since if you have your BL collocated with your PL you will know for sure that the PL already did the validation so you can skip it in BL. However, if the BL is accessible by different PLs (think of web PL, rich client PL or some B2B agent accessing your business layer), you can not trust the validity of the data sent to you (think of the B2B agent), you will have to include the simple validation in your BL too. This is where optimization you talked about (propagating the validations to the BL) would be usefull.

    So, to wrap up the post it basically all boils down to what is the architecture of your system. Where each of the parts are and how much you can trust the agent that is accessing you BL. My guess is that the majority of the projects is probably falling into the category of collocated PL and BL so no duplication of validations needed, and spring is pretty good at this kind of stuff. If you have a different design you will need to think of what are the validation that you will have to perform and where to place your optimizations

    HTH

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •