如果在请求处理的时候,出现了异常,那它的输出依然会是Servlet响应。异常必须要以某种方式转换为响应。
Spring提供了多种方式将异常转换为响应:
- 特定的Spring异常将会自动映射为指定的HTTP状态码;
- 异常上可以添加@ResponseStatus注解,从而将其映射为某一个HTTP状态码;
- 在方法上可以添加@ExceptionHandler注解,使其用来处理异常。
为控制器添加通知
控制器通知(Controller advice)是任意带有@ControllerAdvice注解的类,这个类会包含一个或多个如下类型的方法:
@ExceptionHandler注解标注的方法;
@InitBinder注解标注的方法;
@ModelAttribute注解标注的方法;
带有@ControllerAdvice注解的类,会运用到整个应用程序所有控制器中带有@RequestMapping注解的方法上。
@ControllerAdivce最为实用的一个场景就是将所有的@ExceptionHandler方法收集到一个类中,这样所有控制器的异常就能在一个地方进行一致的处理。
AppExceptionHandler.java
@ControllerAdvice
public class AppExceptionHandler {
@ResponseBody
@ExceptionHandler(NotNullException.class)
public Object notNullExceptionHandler(NotNullException notNullException){
ResponseResult responseResult = notNullException.getResponseResult();
return JSON.toJSONString(responseResult);
}
}
HomeController.java
@Controller
public class HomeController {
@RequestMapping(value="/" ,method = RequestMethod.GET)
public String home(){
return "home";
}
@ResponseBody
@RequestMapping(value="/save" ,method = RequestMethod.GET)
public String save(String userId){
if (userId == ""){
throw new NotNullException(new ResponseResult("01", "不能为空"));
}
return "";
}
}
NotNullException.java
public class NotNullException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
private ResponseResult responseResult;
public NotNullException(ResponseResult responseResult){
super();
this.responseResult = responseResult;
}
public ResponseResult getResponseResult() {
return responseResult;
}
public void setResponseResult(ResponseResult responseResult) {
this.responseResult = responseResult;
}
}
ResponseResult.java
public class ResponseResult implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String code = "";
private String message = "";
private Object data = "";
WebConfig.java
@Configuration
@EnableWebMvc // 启用SpringMVC
@ComponentScan("com.sosweet") // 启用组件扫描
public class WebConfig extends WebMvcConfigurerAdapter{
/** 视图解析器 */
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/"); // 运行时的目录结构
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
/** 配置静态资源的处理 */
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
/** 将StringHttpMessageConverter的默认编码设为UTF-8 避免出现乱码 */
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converters.add(stringHttpMessageConverter);
}
}