`
rensanning
  • 浏览: 3536465 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:37925
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:606293
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:680849
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:88583
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401119
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69504
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91341
社区版块
存档分类
最新评论

Spring MVC 中的异常捕获

 
阅读更多
代码内可以通过try/catch捕获已知异常(checked exception),但未知异常(unchecked exception)却不同时机以不同形式随机出现。异常抛出时系统需要特殊处理捕获异常友好提示,而不是把服务器端异常信息发动到客户端。并且记录异常发生的各项指标信息以方便开发人员调试代码。

可以通过以下方式实现共通的全局处理:
  • ServletRequestListener :请求的开始和结束时执行,Spring的RequestContextListener等
  • Filter :Servlet的开始和结束时执行,Spring的CharacterEncodingFilter、HiddenHttpMethodFilter等
  • HandlerInterceptor  :Controller方法的开始和结束时执行,Spring的LocaleChangeInterceptor等
  • Spring AOP(AspectJ) :面向切面,任意注入处理。


这里只介绍 Spring MVC 内置的异常处理机制:
  • @ResponseStatus
  • @ExceptionHandler
  • @ControllerAdvice
  • HandlerExceptionResolver

(1)Controller内的异常捕获

通过注解@ExceptionHandler来实现异常的捕获处理。
@Controller
public class FooController {
    @ExceptionHandler
    @ResponseStatus(NOT_FOUND)
    public void notFound(ResourceNotFoundException ex) {
        // N/A
    }
}

也可以通过实现HandlerExceptionResolver来实现异常的捕获处理。
@Controller
public class FooController implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
        // N/A
    }
}


(2)被@ResponseStatus注解标记的异常
会被 ResponseStatusExceptionResolver 自动处理。
@ResponseStatus(value = NOT_FOUND, reason = "Resource is not found.")
public class ResourceNotFoundException extends RuntimeException {
    // ...
}


(3)全局异常捕获

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    @RespnseStatus(NOT_FOUND) 
    public void notFound(ResourceNotFoundException ex) {
        // N/A
    }
}

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<Error> handle(RuntimeException ex, HttpServletResponse res){
        // N/A
        res.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}


API和页面共存的时候,全局异常捕获可以通过再次forward来返回不同的内容。
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String error(HttpServletRequest req, Exception ex){
        // N/A
        String baseUrl = getBaseUrl(req);
        return "forward:" + baseUrl + "/error";
    }
}

@Controller
public class GeneralErrorHandlerController {

  @RequestMapping("/admin/error")
  public String screenError(HttpServletRequest req, Model model) {
    // N/A
    return "screen/admin/error";
  }

  @RequestMapping(value = "/api/internal/error")
  @ResponseBody
  public ErrorResponse apiError(HttpServletRequest req) {
    // N/A
    return ErrorResponse.build(e);
  }

}

***** 不能自动设置status code,需要自己设置
***** 不能捕获所有异常,比如表示层,404错误等

@ControllerAdvice注解内的@ExceptionHandler、@InitBinder、@ModelAttribute方法会被应用到所有的@RequestMapping注解的方法。上边@ExceptionHandler是最常见的,而@InitBinder也会用到,比如:

1)默认SpringMVC对空字段设置值为空字符串而不是null。通过以下定义可以将空字符串设置成null,并且会对字符串进行自动trim处理。
还可以传入需要过滤的字符:StringTrimmerEditor(String charsToDelete, boolean emptyAsNull)
@ControllerAdvice
public class NullValidAdvice {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }

}


2)设置JSONP的返回参数
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {

    public JsonpAdvice() {
        super("callback");
    }

}


(4)web.xml中的error-page
这部分本身不归Spring处理,是ServletContainer处理范围。
把所有未能捕获的异常再次跳转到一个指定mapping。

<error-page>
    <location>/error</location>
</error-page>


@Controller
class GeneralErrorHandlerController {
    @RequestMapping("error")
    public String otherError(HttpServletRequest req, Model model) {
      // N/A
    }
}


(5)自定义404相应
设置throwExceptionIfNoHandlerFound为true
<servlet>
    <servlet-name>rest-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>throwExceptionIfNoHandlerFound</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>


@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<Error> handle(NoHandlerFoundException ex){
        // N/A
    }
}


(6)自定义错误页面
定制将异常映射为视图 SimpleMappingExceptionResolver

@Bean
public SimpleMappingExceptionResolver exceptionResolver(){
    SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
    Properties exceptions = new Properties();
    exceptions.put(ArithmeticException.class, "error");
    resolver.setExceptionMappings(exceptions);
    return resolver;
}


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring MVC Exception Handling</title>
</head>
<body>

<h1>Spring MVC Exception Handling</h1>

${exception.message}

</body>
</html>

***** 测试开发环境可以在页面打印出异常堆栈,方便调试。

Spring MVC 异常处理顺序:
ExceptionHandlerExceptionResolver :被@ExceptionHandler注解标记的异常
->
ResponseStatusExceptionResolver :被@ResponseStatus注解标记的异常
->
DefaultHandlerExceptionResolver :Spring的标准异常处理
->
自定义的Resolver

标准异常处理 DefaultHandlerExceptionResolver
引用
  BindException 400 (Bad Request)
  ConversionNotSupportedException 500 (Internal Server Error)
  HttpMediaTypeNotAcceptableException 406 (Not Acceptable)
  HttpMediaTypeNotSupportedException 415 (Unsupported Media Type)
  HttpMessageNotReadableException 400 (Bad Request)
  HttpMessageNotWritableException 500 (Internal Server Error)
  HttpRequestMethodNotSupportedException 405 (Method Not Allowed)
  MethodArgumentNotValidException 400 (Bad Request)
  MissingPathVariableException 500 (Internal Server Error)
  MissingServletRequestParameterException 400 (Bad Request)
  MissingServletRequestPartException 400 (Bad Request)
  NoHandlerFoundException 404 (Not Found)
  NoSuchRequestHandlingMethodException 404 (Not Found)
  TypeMismatchException 400 (Bad Request)


参考:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
http://memorynotfound.com/spring-mvc-exception-handling/
http://www.journaldev.com/2651/spring-mvc-exception-handling-controlleradvice-exceptionhandler-handlerexceptionresolver
http://www.roytuts.com/exception-handling-best-practices-in-java/
https://speakerdeck.com/sinsengumi/spring-boot-application-infrastructure
https://github.com/jirutka/spring-rest-exception-handler
http://qiita.com/kazuki43zoo/items/757b557c05f548c6c5db
http://cgs1999.iteye.com/blog/1547197
http://www.cnblogs.com/xinzhao/p/4934247.html
  • 大小: 154.1 KB
分享到:
评论

相关推荐

    spring mvc异常处理

    本文将深入探讨Spring MVC中的异常处理机制,帮助你更好地理解如何优雅地处理错误和异常。 1. **Spring MVC 异常处理概述** Spring MVC 提供了一种统一的方式来处理应用程序中抛出的异常。它通过`@...

    spring mvc异常简单处理

    在Spring MVC框架中,异常处理是一项关键任务,它确保了应用程序在遇到错误或异常时能够优雅地响应。本文将深入探讨Spring MVC中的异常处理机制,包括如何配置、自定义异常处理器以及异常转换策略。 首先,Spring ...

    spring mvc

    13. **异常处理**: 通过@ControllerAdvice和@ExceptionHandler,可以全局捕获并处理应用程序中的异常,提供统一的错误页面或JSON响应。 14. **Internationalization (i18n) & Localization (l10n)**: Spring MVC ...

    最简单的用户登录与注册系统 spring mvc spring jdbc

    了解如何在Spring MVC中捕获和处理异常是必要的。 通过这个项目,初学者可以深入理解Spring MVC和Spring JDBC的集成,以及它们在实际应用中的工作原理。同时,也可以学习到Web开发的基本流程,包括前后端交互、...

    一个入门的spring mvc demo,基于eclipse maven

    在Spring MVC的生命周期中,当用户发起HTTP请求时,DispatcherServlet首先捕获请求,然后根据请求映射找到合适的HandlerMapping,接着调用对应的Controller进行业务逻辑处理。Controller处理完成后,会返回一个...

    spring mvc 参数绑定漏洞

    1. **类型转换异常**:当用户提交的数据不符合预期的数据类型时,Spring MVC会尝试进行类型转换。如果转换失败,可能会抛出异常,暴露敏感信息或导致应用逻辑错误。 2. **未校验输入**:如果没有对用户输入进行适当...

    Spring+Spring mvc+Hibernate+Bootstrap、企业级员工信息管理系统

    01. 采用后台及前台的 Spring + ... 通过自定义处理器 ExceptionIntercept 实现 Spring mvc的全局异常捕获 10. 系统中包含了企业中采用的开发工具类的集合 11. AbstractDao 父类实现了Dao中针对单个对象的常用操作

    综合spring mvc + spring + hibernate + bootstrap开发图书管理系统

    在本项目中,我们利用了Java技术栈中的四个核心组件:Spring MVC、Spring、Hibernate以及Bootstrap,构建了一个全面的图书管理系统。这个系统旨在提供高效、用户友好的图书管理功能,涵盖了从图书入库、检索到借阅、...

    Spring MVC 学习笔记 九 json格式的输入和输出

    在这个学习笔记中,我们将深入探讨如何在Spring MVC中处理JSON格式的数据,包括输入和输出。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛应用于前后端数据传输。 1. **JSON格式简介** ...

    spring mvc入门示例

    2. DispatcherServlet(前端控制器)捕获请求,它是Spring MVC的核心组件,负责调度请求到合适的处理器。 3. HandlerMapping(处理器映射器)根据请求的URL查找对应的Handler(控制器方法)。 4. HandlerAdapter...

    外文翻译Spring的MVC构架模式-CSDN下载

    Spring MVC是Spring框架中的一个核心组件,主要用于构建Web应用程序的模型-视图-控制器(Model-View-Controller)架构。它为开发者提供了灵活且强大的工具来处理HTTP请求、数据绑定、验证和视图渲染。本文将深入探讨...

    spring mvc过程详解

    2. **异常处理**:Spring MVC 提供了多种机制来处理异常,可以通过自定义异常处理控制器来捕获并处理全局异常。 3. **单元测试**:Spring MVC 的控制器可以轻松地与 JUnit 结合进行单元测试,无需启动整个应用环境...

    spring mvc 核心jar包

    11. **ExceptionHandler**:Spring MVC 提供了异常处理机制,可以通过 `@ExceptionHandler` 注解的方法捕获和处理特定类型的异常。 12. **MVC 注解驱动开发**:通过启用 `@EnableWebMvc` 或配置 `WebMvcConfigurer`...

    spring mvc demo

    【Spring MVC 框架详解】 Spring MVC 是 Spring 框架的一个重要模块,它为构建基于Java的Web应用程序提供了一个...通过这个示例项目,开发者可以深入理解Spring MVC的工作原理,学习如何在实际项目中有效利用其功能。

    第11章Spring MVC常用参数的使用可运行源码 Spring MVC简单应用

    在 Spring MVC 中,使用 `@Controller` 注解标记类作为控制器。控制器类包含处理 HTTP 请求的方法,这些方法通常使用 `@RequestMapping` 注解进行映射。 4. **@RequestMapping 注解** `@RequestMapping` 注解用于...

    Spring MVC 教程,快速入门,深入分析

    全局异常处理是Spring MVC的一个重要特性,通过@ControllerAdvice和@ExceptionHandler注解来实现异常的全局捕获和处理。异常处理后,还可以将异常信息记录到日志中,便于后续的分析和跟踪。 单元测试在软件开发中不...

    Spring MVC step-by-step 源码

    Spring MVC 是一个强大的Java Web开发框架,用于构建高效、可维护的Web应用程序。它基于Spring框架,提供了模型-视图-控制器(MVC)架构,简化了开发过程。本资源"Spring MVC step-by-step 源码"是针对初学者准备的...

    spring mvc 实例

    【Spring MVC 框架详解】 Spring MVC 是 Spring 框架的重要组成部分,专注于构建Web应用程序的模型-视图-控制器(MVC)结构。它提供了丰富的特性,以简化开发流程,包括高度可配置的架构、与其他Web框架的无缝集成...

Global site tag (gtag.js) - Google Analytics