spring web应用的异常处理
来源:互联网 发布:大话西游手游藕丝数据 编辑:程序博客网 时间:2024/05/22 16:20
针对RESTful返回json的异常处理
@ControllerAdvice和@ExceptionHandler
字面理解
ControllerAdvice:控制增强
ExceptionHandler:异常处理程序
spring有一个类专门处理异常的基类,已经写好了一些默认的异常处理方法,如果需要可以直接继承这个类:ResponseEntityExceptionHandler,如果不能满足需求可以自己重写某些方法(例:方法3)或者直接自己捕获异常(例:方法1/方法2)
@ControllerAdvicej avadoc定义是:
/*** Indicates the annotated class assists a "Controller".** <p>Serves as a specialization of {@link Component @Component}, allowing for* implementation classes to be autodetected through classpath scanning.** <p>It is typically used to define {@link ExceptionHandler @ExceptionHandler},* {@link InitBinder @InitBinder}, and {@link ModelAttribute @ModelAttribute}* methods that apply to all {@link RequestMapping @RequestMapping} methods.** @author Rossen Stoyanchev* @since 3.2*/
即把@ControllerAdvice注解内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法。
理解:
1. @ControllerAdvice:是必须加的
2. @ExceptionHandler:是指定捕获的异常类型的(可以不指定类型)
3. 这是开始执行@RequestMapping方法时发生的异常,执行方法之前的异常是无法捕捉的(例:404)
例1:
@ControllerAdvice public class ControllerAdviceTest { @ModelAttribute public User newUser() { System.out.println("============应用到所有@RequestMapping注解方法,在其执行之前把返回值放入Model"); return new User(); } @InitBinder public void initBinder(WebDataBinder binder) { System.out.println("============应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器"); } @ExceptionHandler(UnauthenticatedException.class) @ResponseStatus(HttpStatus.UNAUTHORIZED) public String processUnauthenticatedException(NativeWebRequest request, UnauthenticatedException e) { System.out.println("===========应用到所有@RequestMapping注解的方法,在其抛出UnauthenticatedException异常时执行"); return "viewName"; //返回一个逻辑视图名 } }
例2:
// 可以指定类型,本例就是加了RestController注解的类@ControllerAdvice(annotations = RestController.class)public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { private final Logger logger = LoggerFactory.getLogger(this.getClass()); // 方法1:value是能够被捕获的异常类型,不同的异常调用不同的处理方法 @ExceptionHandler(value = { FatalException.class, NonFatalException.class }) protected ResponseEntity<Object> handleExceptions(Exception ex) { logger.error("Rest Exception!", ex); if (ex instanceof FatalException) { return handleFatalException((FatalException) ex); } else if (ex instanceof NonFatalException) { return handleNonFatalException((NonFatalException) ex); } else { return new ResponseEntity<Object>(ReturnJson.systemError(), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); } } // 处理非致命异常的方法 private ResponseEntity<Object> handleNonFatalException(NonFatalException ex) { return new ResponseEntity<Object>(ReturnJson.json(ex.getCode(), ex.getMessage(), null), new HttpHeaders(), HttpStatus.OK); } // 处理致命异常的方法 private ResponseEntity<Object> handleFatalException(FatalException ex) { return new ResponseEntity<Object>(ReturnJson.json(ex.getCode(), ex.getMessage(), null), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); } // 方法2:其他异常处理方法 @ExceptionHandler protected ResponseEntity<Object> handleOtherExceptions(Exception ex) { logger.error("Rest Exception!", ex); return new ResponseEntity<Object>(ReturnJson.systemError(), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); } // 方法3:父类的方法无法满足我们的需要,就要重写父类的方法 @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { logger.error("请求参数错误", ex); return new ResponseEntity<Object>(ReturnJson.fail(), new HttpHeaders(), HttpStatus.OK); }}
ResponseEntityExceptionHandler代码片段
public abstract class ResponseEntityExceptionHandler { // 捕获的异常类型,调用不同的方法处理 @ExceptionHandler(value = { NoSuchRequestHandlingMethodException.class, HttpRequestMethodNotSupportedException.class, HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class, MissingServletRequestParameterException.class, ServletRequestBindingException.class, ConversionNotSupportedException.class, TypeMismatchException.class, HttpMessageNotReadableException.class, HttpMessageNotWritableException.class, MethodArgumentNotValidException.class, MissingServletRequestPartException.class, BindException.class, NoHandlerFoundException.class }) public final ResponseEntity<Object> handleException(Exception ex, WebRequest request) { HttpHeaders headers = new HttpHeaders(); if (ex instanceof NoSuchRequestHandlingMethodException) { HttpStatus status = HttpStatus.NOT_FOUND; return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, headers, status, request); } 。 。 。 else { logger.warn("Unknown exception type: " + ex.getClass().getName()); HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; return handleExceptionInternal(ex, null, headers, status, request); } } // 异常处理的方法 protected ResponseEntity<Object> handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { pageNotFoundLogger.warn(ex.getMessage()); return handleExceptionInternal(ex, null, headers, status, request); } protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) { request.setAttribute("javax.servlet.error.exception", ex, WebRequest.SCOPE_REQUEST); } return new ResponseEntity<Object>(body, headers, status); }}
对于使用模板渲染HTML的应用
1.在执行@RequestMapping之后遇到的异常
@Componentpublic class ExceptionHandler implements HandlerExceptionResolver { private static Logger log = LoggerFactory.getLogger(ExceptionHandler.class); @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) { // 异常处理逻辑 goes here log.info("got exception: {}", ex.getClass()); return new ModelAndView("pc/500"); }}
异常的处理逻辑:
DispatcherServlet中如果产生了异常,则接下来会在processDispatchResult()方法中查询当前容器中是否有HandlerExceptionResolver接口的实现类,如果有则调用它的resolveException()方法,得到返回的View,如果没有则使用框架默认的异常处理类。
2.在执行@RequestMapping之前遇到的异常
这个是spring-boot才有的
我们要写一个@Controller,并实现ErrorController接口:
@Controller public class MainsiteErrorController implements ErrorController { private static final String ERROR_PATH = "/error"; @RequestMapping(value=ERROR_PATH) public String handleError(){ return "pages/404"; } @Override public String getErrorPath() { return ERROR_PATH; }}
- Spring Boot Web应用的异常处理
- spring web应用的异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- Spring Boot中Web应用的统一异常处理
- spring mvc web应用异常处理
- spring web flow 全局异常的处理
- Spring Boot学习(六)之Web应用的统一异常处理
- Web应用中设置了异常统一处理页面,捕捉指定异常时的处理问题
- Spring-Web项目中的异常处理
- spring mvc 的异常处理
- spring mvc的异常处理
- spring mvc的异常处理
- Spring MVC 的 异常处理
- docker版nexus安装及使用
- elasticsearch学习第一天
- ImagLoder和 ViiewPager 适配器
- Python 必须凑够3个线程,才一起执行
- 转]SpringMVC Controller介绍及常用注解
- spring web应用的异常处理
- 欢迎使用CSDN-markdown编辑器
- Sublime Text3 3143 注册码
- kafka 认证
- java变量类型之间的转换关系
- java使用socket实现一个多线程web服务器
- Mysql 绑定内部IP的设置方法
- nodejs使用body-parser解析表单数据
- UVALive