JDBC Spring-mvc 中的异常处理
JDBC exception handling in Spring-mvc
我正在实施一个 REST api 网络服务,它从 MySql 数据库中获取数据。上面写着 here 我们不需要显式处理数据库异常。我在 Service 层中有 catch 块。我有以下问题。
1- 如何从 catch 块向相应的模型视图发送适当的错误消息?
2- Service 是捕获异常的正确层吗?
我有以下代码
控制器
@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;
}
服务
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());
}
}
您想将特定于 Web 的行为与服务层和数据层隔离开来,我认为最好的方法是抛出一个新的、经过检查的、特定于域的 Exception
匹配您希望在 Controller 中以不同方式处理的每种情况的含义。
例如,DuplicateUserException
、SystemUnavailableException
。然后控制器捕获这些并将正确的案例添加到模型中。
@dbreaux 的回答是correct.You 应该自定义一个例外。
public class UserException extends RuntimeException {
// You can add some custom variables
// such as error codes, error types, etc.
}
那么,你应该定义一个ControllerAdvice来处理这个异常:
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());
}
}
最后,您可以在您的服务中抛出 UserException
。
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");
}
}
我正在实施一个 REST api 网络服务,它从 MySql 数据库中获取数据。上面写着 here 我们不需要显式处理数据库异常。我在 Service 层中有 catch 块。我有以下问题。
1- 如何从 catch 块向相应的模型视图发送适当的错误消息?
2- Service 是捕获异常的正确层吗?
我有以下代码
控制器
@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;
}
服务
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());
}
}
您想将特定于 Web 的行为与服务层和数据层隔离开来,我认为最好的方法是抛出一个新的、经过检查的、特定于域的 Exception
匹配您希望在 Controller 中以不同方式处理的每种情况的含义。
例如,DuplicateUserException
、SystemUnavailableException
。然后控制器捕获这些并将正确的案例添加到模型中。
@dbreaux 的回答是correct.You 应该自定义一个例外。
public class UserException extends RuntimeException {
// You can add some custom variables
// such as error codes, error types, etc.
}
那么,你应该定义一个ControllerAdvice来处理这个异常:
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());
}
}
最后,您可以在您的服务中抛出 UserException
。
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");
}
}