在spring mvc 3中,处理异常的是试用exceptionresolver去做异常,先来个简单DEMO看下:
1) 自定义异常类
public class SpringException extends RuntimeException{
private String exceptionMsg;
public SpringException(String exceptionMsg) {
this.exceptionMsg = exceptionMsg;
}
public String getExceptionMsg(){
return this.exceptionMsg;
}
public void setExceptionMsg(String exceptionMsg) {
this.exceptionMsg = exceptionMsg;
}
}
2) 一个简单的控制器,其中用到了注解
@Controller
public class StudentController {
@RequestMapping(value = "/student", method = RequestMethod.GET)
public ModelAndView student() {
return new ModelAndView("student", "command", new Student());
}
@RequestMapping(value = "/addStudent", method = RequestMethod.POST)
@ExceptionHandler({SpringException.class})
public String addStudent( @ModelAttribute("HelloWeb")Student student,
ModelMap model) {
if(student.getName().length() < 5 ){
throw new SpringException("Given name is too short");
}else{
model.addAttribute("name", student.getName());
}
}
}
3 在传统的xxxx-servlet.xml中配置SimpleMappingExceptionResolver
<bean class="org.springframework.web.servlet.handler.
SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.tutorialspoint.SpringException">
ExceptionPage
</prop>
</props>
</property>
<property name="defaultErrorView" value="error"/>
其中 ExceptionPage.jsp得定义出来,如下页面:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<title>Spring MVC Exception Handling</title>
</head>
<body>
<h2>Spring MVC Exception Handling</h2>
<h3>${exception.exceptionMsg}</h3>
</body>
</html>
这样当有异常的话,就出现ExceptionPage.jsp的页面了;
注意一下,使用:
@ExceptionHandler(IOException.class)
public ModelAndView handleIOException(IOException ex) {
则凡是IOException的子类异常的话,也会用handleIOException方法去处理的喔';
可以看到,其实在spring mvc3中,如果使用
@ExceptionHandler(IOException.class)
public ModelAndView handleIOException(IOException ex) {
这个方法,其弊端在于,一个controller只能搭配响应一类异常,也就是说,
只能处理同一个controller中出现的ioexception;在最新的spring mvc 3.2中,比如DEMO如下:
@Controller
public class UserCreditCardController {
private static final Logger logger = LoggerFactory.getLogger(UserCreditCardController.class);
@RequestMapping(value = "userdetails", method = RequestMethod.GET)
public String getCardDetails(Model model) throws IOException {
logger.info("This will throw an IOException");
boolean throwException = true;
if (throwException) {
throw new IOException("This is my IOException");
}
return "home";
}
}
还有一个controller:
@Controller
public class UserAddressController {
private static final Logger logger = LoggerFactory.getLogger(UserAddressController.class);
@RequestMapping(value = "useraddress", method = RequestMethod.GET)
public String getUserAddress(Model model) throws IOException {
logger.info("This will throw an IOException");
boolean throwException = true;
if (throwException) {
throw new IOException("This is my IOException");
}
return "home";
}
}
两个controller都抛出了IOException的异常,则统一处理的为:
@ControllerAdvice
public class MyControllerAdviceDemo {
private static final Logger logger = LoggerFactory.getLogger(MyControllerAdviceDemo.class);
@Autowired
private UserDao userDao;
@ExceptionHandler(IOException.class)
public ModelAndView handleIOException(IOException ex) {
logger.info("handleIOException - Catching: " + ex.getClass().getSimpleName());
return errorModelAndView(ex);
}
private ModelAndView errorModelAndView(Exception ex) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("name", ex.getClass().getSimpleName());
modelAndView.addObject("user", userDao.readUserName());
return modelAndView;
}
}
这样一来,使用了@ControllerAdvice标签,则无论应用中有多少个controller,只要
其中一个抛出IOException,都会使用 MyControllerAdviceDemo 去处理了;