SpringMVC 异常处理机制
目录
Spring提供了一系列健全的异常处理框架。我们可以采用@ResponseStatus,@ExceptionHandler,HandlerExceptionResolver以及 @ControllerAdvice处理异常。
- @ResponseStatus:指定状态码
- @ExceptionHandler:注解异常处理方法
- @ControllerAdvice:全局异常处理
- HandlerExceptionResolver:定义异常类型与 view 的映射
可以用在定义的类或者controller方法上,它包含两个元素,value和reason。Value用于设置response的状态码,例如404,200等,reason用于响应,可以是内容语句。
被注解的方法可以有Exception,HttpServletRequest,HttpServletResponse,Session,WebRequest等任何顺序的参数类型,方法返回值可以是ModelAndView, Model,Map, View, String, @ResponseBody甚至void类型。
该注解是在classpath扫描时自动检测的,用于全局异常处理。
在Spring MVC中,所有用于处理在请求处理过程中抛出的异常,都要实现HandlerExceptionResolver接口。它只能处理请求过程中抛出的异常,异常处理本身所抛出的异常和视图解析过程中抛出的异常它是不能处理的。
package com.concretepage.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Keyword")
public class KeywordNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public KeywordNotFoundException(String key){
super(key+" not available");
}
}
package com.concretepage.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.concretepage.exception.KeywordNotFoundException;
@Controller
@RequestMapping("/keyword")
public class KeywordController {
@RequestMapping("/info")
public String info(@RequestParam(value="key") String key, Model model) {
if ("key101".equals(key)) {
model.addAttribute("msg", "Hello Key World!");
} else {
throw new KeywordNotFoundException(key);
}
return "success";
}
}
package com.concretepage.controller;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/myworld")
public class MyWorldExceptionController {
@ResponseStatus(value=HttpStatus.CONFLICT, reason="Data already present")
@ExceptionHandler(SQLException.class)
public void dataConflict() {
System.out.println("----Caught SQLException----");
}
@ExceptionHandler(FileNotFoundException.class)
public ModelAndView myError(Exception exception) {
System.out.println("----Caught FileNotFoundException----");
ModelAndView mav = new ModelAndView();
mav.addObject("exc", exception);
mav.setViewName("myerror");
return mav;
}
@RequestMapping("/check")
public String myInfo(@RequestParam(value="id") String id, Model model) throws Exception {
if ("1".equals(id)) {
throw new SQLException();
}else if ("2".equals(id)) {
throw new FileNotFoundException("File not found.");
}else if ("3".equals(id)) {
throw new IOException("Found IO Exception");
}else {
model.addAttribute("msg", "Welcome to My World.");
}
return "success";
}
package com.concretepage.controller;
import java.io.IOException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import com.concretepage.exception.KeywordNotFoundException;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IOException.class)
public ModelAndView myError(Exception exception) {
System.out.println("----Caught IOException----");
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("globalerror");
return mav;
}
@ExceptionHandler(KeywordNotFoundException.class)
public String notFound() {
System.out.println("----Caught KeywordNotFoundException----");
return "404";
}
}
package com.concretepage.config;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
@Configuration
@ComponentScan("com.concretepage.controller")
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
@Bean
public UrlBasedViewResolver urlBasedViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
@Bean
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties errorMaps = new Properties();
errorMaps.setProperty("ElectricityNotFoundException", "error");
errorMaps.setProperty("NullPointerException", "error");
resolver.setExceptionMappings(errorMaps);
resolver.setDefaultErrorView("globalerror");
resolver.setExceptionAttribute("exc");
return resolver;
}
}
package com.concretepage.exception;
public class ElectricityNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ElectricityNotFoundException(String villageName) {
super(villageName+":Electricity not available");
}
}
package com.concretepage.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.concretepage.exception.ElectricityNotFoundException;
@Controller
@RequestMapping("/myvillage")
public class VillageController {
@RequestMapping("/info")
public String myInfo(@RequestParam(value="vid") String vid, Model model) throws Exception {
if ("111".equals(vid)) {
throw new ElectricityNotFoundException("Dhananajaypur");
}else if ("222".equals(vid)) {
throw new NullPointerException("Data not found.");
}else {
model.addAttribute("msg", "Welcome to My Village.");
}
return "success";
}
}