Daim
Daim

Reputation: 57

JDBC exception handling in Spring-mvc

I am implementing a REST api webservice which is fetching data from a MySql database. It is written here that we dont need to handle database exception explicitly. I have catch blocks in the Service layer. I have the following questions.

1- How do i send the appropriate error message to the respective model view from the catch block?

2- Is Service the right layer to catch the exception?

I have the following code

Controller

    @RequestMapping(value = "/saveUser", method = RequestMethod.POST)
    public ModelAndView saveUser(@ModelAttribute User user, BindingResult result) 
    {
       ModelAndView mv = new ModelAndView();

       validator.validate(user, result);
       if(result.hasErrors()) {
           mv.setViewName("addUser");
       }
       else {
           service.saveUser(user);
           mv.setViewName("redirect:/users/listAllUsers");
       }
       return mv;
    }

Service

public void saveUser(User user) {
    try {
        userDao.saveUser(user);
    } catch(DuplicateKeyException e) {
        //Here i want to send "User already exist"
    } catch(DataAccessException e) {
        //Here i want to send "Databae unreachable"
    }
}

UserDAO

public void saveUser(User user) {
        String sql = "INSERT INTO User (fname, lname, address, phone)"
                    + " VALUES (?, ?, ?, ?)";
            jdbcTemplate.update(sql, user.getFname(), user.getLname(),
                    user.getAddress(), user.getPhone()); 
    }
}

Upvotes: 0

Views: 5279

Answers (2)

王瑞环
王瑞环

Reputation: 44

@dbreaux 's answer is correct.You should customize an exception.

public class UserException extends RuntimeException {
      // You can add some custom variables
      // such as error codes, error types, etc.
}

Then,you should define a ControllerAdvice to handle this Exception:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class UserControllerAdvice{

    @ExceptionHandler(value = UserException.class)
    public ModelAndView handleUserException(UserException ex){

        // Generate corresponding results(ModelAndView) based on exception.
        // example: Put the error message to model. 
        return new ModelAndView("prompt_page",ex.getMessage());
    }
}

Last,you can throws UserException in your Service.

public void saveUser(User user) {
    try {
        userDao.saveUser(user);
    } catch(DuplicateKeyException e) {
        throw new UserException("User already exist");
    } catch(DataAccessException e) {
        throw new UserException("Databae unreachable");
    }
}

Upvotes: 3

Doug Breaux
Doug Breaux

Reputation: 5115

You want to isolate the web-specific behaviors from the service layer, and from the data layer, and I think the best way to do that is to throw a new, checked, domain-specific Exception that matches the meaning of each case you want to handle differently in the Controller.

For example, DuplicateUserException, SystemUnavailableException. Then the Controller catches those and adds the correct case to the Model.

Upvotes: 1

Related Questions