2

I have created an application in Spring MVC for testing the rollback and commit functionality. I am using Transaction using. Here in the service i have created another contact objects without specifying employee id which is a required field. The application works fine when exception is comming while saving and rollback is working.

But the problem is the Exception is printing in my jsp page.

Can anyone please tell me some solution for preventing displaying he exception in te view

Controller

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status)
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    contactsDAO.save(contact);
    status.setComplete();
    return "redirect:viewAllContacts.do";
}

Service

public int save(Contacts contact)
{
    int i = 0;
    try
    {
        i = (Integer) sessionFactory.getCurrentSession().save(contact);
        Contacts contacts =new Contacts();
        contacts.setAddress("ABCD");
        contacts.setMobile("8181");
        i = (Integer) sessionFactory.getCurrentSession().save(contacts);
    }
    catch(Exception exception)
    {
        exception.printStackTrace();
    }
    return i;
}

EDIT

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status) throws SQLException
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    try {
        contactsDAO.save(contact); 
    }
    catch (Exception ex) {
        System.out.println("enrtered");
        result.reject("DUPKEY");
        ex.printStackTrace();
        return "redirect:saveContact.do";
    } 
    status.setComplete();
    return "redirect:viewAllContacts.do";
}
5
  • Check/configure spring exception resolver Commented Jun 12, 2014 at 11:26
  • @user3145373ツ Actually as i said i have cretead a exception to check the rollback functionality Commented Jun 12, 2014 at 11:28
  • Could you explain what is the exception, if it is the one that you catch in your service (and how it is rethrown then) and what means : printing in my jsp ? Does it appears in the middle of the expected page or instead of the expected page ? Commented Jun 13, 2014 at 13:59
  • @SergeBallesta see here exception is not the issue, the thing is say we are having some exception during a transaction since i am using @Transactional there is no need of defining Transaction explicitly. so when exception occurs it throws out and shows that exception to the user, rather how can i tell user that some thing has went wrong Commented Jun 13, 2014 at 14:21
  • @SergeBallesta just the same like Hibernate, Spring, @Transactional - surround with try/catch? But i am not getting any solution for this, can you please specify some code relevant for the above code Commented Jun 13, 2014 at 14:52

2 Answers 2

4

You should never let an exception thrown in service layer arrive directly in user browser. As suggested by Vinit Prajapati you can configure a HandlerExceptionResolver that will display appropriate views in case of an exception. You can also have a per controller exception handling mechanisme with one or more @ExceptionHandler annotated method(s) that will be fired in case of a configured exception and that can be used almost like @RequestMapping annotated methods. At a last ressort you can have explicit try-catch blocks in controller methods.

Extracts from Spring Framework Reference Manual : You use the @ExceptionHandler method annotation within a controller to specify which method is invoked when an exception of a specific type is thrown during the execution of controller methods ... The @ExceptionHandler value can be set to an array of Exception types. If an exception is thrown matches one of the types in the list, then the method annotated with the matching @ExceptionHandler will be invoked ... Much like standard controller methods annotated with a @RequestMapping annotation, the method arguments and return values of @ExceptionHandler methods are very flexible... The return type can be a String, which is interpreted as a view name or a ModelAndView object.

In my own code, I use @ExceptionHandler for general errors such as unaccessible database, but use try-catch blocs in controller if I want to deal with exceptions really caused by business rules and for which I prefere to use <form:errors> tags in the view, explicitely calling Errors.reject() in controller.

EDIT: concrete examples

Suppose you want to display special view in case of DataIntegrityViolationException

In controller

@ExceptionHandler(value = {DataIntegrityViolationException.class})
public ModelAndViewexceptionHandler(Exception ex, Locale locale) {
    String msg = ex.getMessage();
    // or if you have a I18n app : String msg = messageSource.getMessage("DUPKEY", null, locale);
    return new ModelAndView("duplicate", "msg", msg);
}

with "duplicate"leading to a jsp where ${msg} will display the exception message. Of course for that to work, your service must throw a DataIntegrityViolationException ...

If you prefere the error to be displayed in normal view, you can do instead

@RequestMapping(value="/saveContact", method=RequestMethod.POST)
public String create(@ModelAttribute("newContact")Contacts contact, BindingResult result, SessionStatus status)
{
    validator.validate(contact, result);
    if (result.hasErrors()) 
    {               
        return "newContact";
    }
    try {
        contactsDAO.save(contact);
    }
    catch (DataIntegrityViolationException ex) {
        result.reject("DUPKEY");
        return "newContact";
    }
    status.setComplete();
    return "redirect:viewAllContacts.do";
}

With that last construct you will display the error message corresponding to DUPKEY in your configured MessageSourcebean like other global errors in your jsp view through the tag <form:errors/> with no path in it.

<form:form>
      <%-- Show global errors (notably DUPKEY) --%>
      <form:errors/>
      <table>
          <tr>
              <td>Address:</td>
              <td><form:input path="address" /></td>
              <%-- Show errors for address field --%>
              <td><form:errors path="address" /></td>
          </tr>
...
</form:form>
Sign up to request clarification or add additional context in comments.

13 Comments

Can you show me an example in related to my application as shown above
here can you please tell me what is the use of @ExceptionHandler and its block , since what i feel is that even you have put a try catch within that contactsDAO.save(contact); so whenever an exception occurs it will be catched and within that catch block if we return back to the newContact or viewAllContacts views with the corresponding error message
Just added instead at the introduction of the second example. The examples are exclusive : either you use a @ExceptionHandler with a view dedicated to exception display, or you use a catch block and keep displaying error in same view.
that means when some exception occurs if we want to display that to a dedicated common exception view we can use @ExceptionHandler otherwise if we want to display within that same view we can return through the catch itself.
Thanks!!, one more thing , i.e if we want to pass an error message from the catch block to the same view we render, how can we do that through BindingResult or any other way
|
4

Create a base controller class (which your others extend), and for example try this method (although you'll want to handle different errors with different methods, but this will get you started):

    /*
 * Default exception handler, catches all exceptions, redirects to friendly
 * error page and send e-mail does not catch request mapping errors
 */
@ExceptionHandler (Exception.class)
public String myExceptionHandler(final Exception e) {
    final StringWriter sw = new StringWriter();
    final PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    final String strStackTrace = sw.toString(); // stack trace as a string
    logger.error(strStackTrace); // send to logger first
    emailService.sendAlertMail(strStackTrace);
    return "exception"; // default friendly exception message for user
}

2 Comments

But from my service how will I control the exception through this
Can you show me an example in related to my application as shown above

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.