`
NeverFlyAway
  • 浏览: 69322 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Spring controller异常的统一处理

阅读更多

网站的异常处理最好是解耦的,并且都放在一个地方集中管理。

比如访问权限不够,跳转到指定页面,比如访问的页面不存在,或者404 500之类的错误。

本文介绍Spring的@ControllerAdvice来对这些异常统一进行处理。

 

 

import java.io.IOException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;

@ControllerAdvice(annotations = {RestController.class})
public class ExceptionReaper {
	
	private static final Logger logger = LogManager.getLogger(ExceptionReaper.class);

	@ExceptionHandler(value = { IOException.class , RuntimeException.class })
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ModelAndView exception(Exception exception, WebRequest request) {
		logger.info("Catch an exception", exception);
		return  new ModelAndView("error/errorPage");
	}
	
	@ExceptionHandler(value = { NoHandlerFoundException.class })
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public ModelAndView noMapping(Exception exception, WebRequest request) {
		logger.info("No mapping exception", exception);
		return  new ModelAndView("error/notFound");
	}

}

 

 

网上大部分的异常处理大致分为这么几种

 

1.web.xml配置对404和500之类的错误进行处理,比如访问不存在页面时跳转到一个静态页面,缺点是必须静态页面而且不太好用

 

<error-page>
    <error-code>404</error-code>
    <location>/building.jsp</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/error.jsp</location>
</error-page>

 

 

2.配置exception handler,这样的话每个controller都要配置异常处理,或者在一个super controller里配置异常处理,所有controller继承他,缺点也是显而易见的。

 

@Controller  
public class MyController {  
      @ExceptionHandler(RuntimeException.class)  
      @ResponseBody  
      public String runtimeExceptionHandler(RuntimeException runtimeException) {  
            logger.error("error", runtimeException);  
            return "error";  
      }  
}  

 

 

3.在applicationContext里面配置SimpleMappingExceptionResolver

 

@Bean
public SimpleMappingExceptionResolver exceptionResolver() {
   SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
   Properties exceptionMappings = new Properties();
   exceptionMappings.put("java.lang.Exception", "error/errorPage");
   exceptionMappings.put("java.lang.RuntimeException", "error/errorPage");
   exceptionResolver.setExceptionMappings(exceptionMappings);
   Properties statusCodes = new Properties();
   statusCodes.put("error/404", "404");
   statusCodes.put("error/error", "500");
   exceptionResolver.setStatusCodes(statusCodes);
   return exceptionResolver;
}

 

 

上面这三种处理方法比较常见,但是我觉得都不如@ControllerAdvice来的方便好用

完全可以把@ExceptionHandler放在@ControllerAdvice统一处理,不用每个controller都配置

 

import java.io.IOException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;

@ControllerAdvice(annotations = {RestController.class})
public class ExceptionReaper {
	
	private static final Logger logger = LogManager.getLogger(ExceptionReaper.class);

	@ExceptionHandler(value = { IOException.class , RuntimeException.class })
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ModelAndView exception(Exception exception, WebRequest request) {
		logger.info("Catch an exception", exception);
		return  new ModelAndView("error/errorPage");
	}
	
	@ExceptionHandler(value = { NoHandlerFoundException.class })
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public ModelAndView noMapping(Exception exception, WebRequest request) {
		logger.info("No mapping exception", exception);
		return  new ModelAndView("error/notFound");
	}

}

@ControllerAdvice(annotations = {RestController.class}) 配置你需要拦截的类,

 

@ControllerAdvice(basePackages = "com.demo") 这也可以

 

然后下面放@ExceptionHandler作为全局的异常处理

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 告诉浏览器这是什么错误类型

最后就可以记录日志,根据需求做一些处理,返回对应的ModelAndView跳转到对应的错误页面

 

需要注意的是,上面这些配置,只能配置你的程序中抛出的错误

1.如果是用户请求了一个不存在的页面,没有对应的@RequestMapping,此时Spring的DispatcherServlet就会处理掉返回404,不会进入任何一个controller

2.还有比如spring security之类的权限管理模块,如果用户的密码正确,但是该账户的权限组没有权限访问当前页面,此时权限模块会有自己的AccessDeniedHandler处理,也不会进入刚才配置的@ControllerAdvice

 

所以对于2中的情况,一般通过权限管理模块提供的方法去处理异常

比如spring security中

 

        @Override
	protected void configure(HttpSecurity http) throws Exception {
		
		http
			.authorizeRequests()
				.antMatchers("/resources/**")
				.permitAll()
			.anyRequest()
				.authenticated()
				.and()
			.exceptionHandling()
				.accessDeniedPage("/error/accessDenied.html")
				.and()
			.formLogin()
				.loginPage("/login")
				.permitAll()
				.and()
			.logout()
				.permitAll();
	
	}

 

 

对于1中的情况,我们可以配置Spring在没有对应的@RequestMapping时,不要自行处理,让他抛出一个NoHandlerFoundException的异常,从而让我们配置的@ControllerAdvice进行统一处理

如果是xml风格的配置,可以在DispatcherServlet对应的配置文件中配置

如果是之前介绍的class风格的配置,可以这样配置:

dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);//for NoHandlerFoundException

 

 

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class WebInit implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext container) throws ServletException {
	// Create the 'root' Spring application context
	AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
	rootContext.scan("com.demo");
	// Manage the lifecycle of the root application context
	container.addListener(new ContextLoaderListener(rootContext));
	// Listener that exposes the request to the current thread
	container.addListener(new RequestContextListener());
	// Create the dispatcher servlet's Spring application context
	AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
	// Register and map the dispatcher servlet
	DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherContext);
	dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);//for NoHandlerFoundException
	ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher",	dispatcherServlet);
	dispatcher.setLoadOnStartup(1);
	dispatcher.addMapping("/");
	}

}

 

 

网站的异常处理基本都能实现了

以上

1
0
分享到:
评论

相关推荐

    spingmvc+mybatis+统一异常处理机制

    唯一不同的加入了统一错误处理,为了方便开发人员开发,所有错误码用一张表存在数据库中,然后由应用将整表缓存,缓存采用的spring自带的cache,开发中所有错误包括系统异常在Controller直接抛出即可。之所以缓存...

    springmvc 异常统一处理的三种方式详解.docx

    在Spring MVC框架中,异常处理是一项关键任务,它确保了应用程序在遇到错误或异常时能够以优雅的方式响应,提供统一的错误信息,并保持代码的整洁和模块化。本篇文章将详细探讨Spring MVC处理异常的三种主要方法:...

    spring mvc异常简单处理

    通过这种方式,我们可以为整个应用程序提供统一的异常处理策略,而无需在每个控制器中重复代码。 此外,Spring MVC还支持使用`HandlerExceptionResolver`接口来自定义异常解析器。实现这个接口并将其注册到Spring的...

    Spring Boot统一异常处理最佳实践(拓展篇)

    Spring Boot 统一异常处理最佳实践拓展篇 在 Spring Boot 中,统一异常处理是非常重要的,今天我们将介绍 Spring Boot 统一异常处理最佳实践的拓展篇。之前我们已经了解了基本的统一异常处理思路,现在我们将继续...

    SpringBoot逻辑异常统一处理方法

    SpringBoot逻辑异常统一处理方法 在本文中,我们将探讨 SpringBoot 逻辑异常统一处理方法,该方法主要介绍了如何在 SpringBoot 项目中实现逻辑异常的统一处理。通过示例代码,我们将展示如何创建一个异常处理核心子...

    Spring Boot中使用AOP统一处理web层异常的方法

    "Spring Boot中使用AOP统一处理web层异常的方法" 本文主要介绍了在Spring Boot中使用AOP(Aspect-Oriented Programming,面向方面编程)来统一处理web层异常的方法。该方法可以使得系统在出现异常时能够正确地处理...

    Spring MVC Controller配置方式

    通过 @ExceptionHandler 或自定义 ExceptionResolver,可以统一处理 Controller 中抛出的异常。 总结: Spring MVC 中的 Controller 配置方式主要有注解式和 XML 配置两种。随着 Spring 的发展,注解式配置因其简洁...

    Spring Boot统一异常处理详解

    Spring Boot作为一款流行的Java开发框架,提供了便捷的方式来实现统一异常处理。本文将深入探讨如何在Spring Boot中进行全局异常处理。 首先,Spring Boot默认提供了一个“error”映射,但其提供的错误页面并不适合...

    Maven+SpringMVC实现统一异常处理

    统一异常处理就是将所有可能抛出的异常集中处理,提供一个全局的、一致的错误反馈,提高用户体验并简化代码结构。 1. **Maven配置** Maven的pom.xml文件是项目的核心,它定义了项目的依赖关系。为了使用SpringMVC...

    SpringMVC中一个Controller多个方法

    还有`@ExceptionHandler`用于全局处理异常,提供统一的错误页面或API响应。 综上所述,Spring MVC的Controller支持在一个类中定义多个方法,每个方法对应不同的HTTP请求。这使得代码组织清晰,易于维护。通过灵活...

    浅谈Spring Boot 异常处理篇

    局部异常处理机制可以在 Controller 中使用 @ExceptionHandler 注解来处理异常。例如,我们可以定义一个 ResponseBean 对象来统一响应异常,定义一个 ExceptionEnum 枚举来表示不同的异常类型。 五、优雅地使用异常...

    Spring MVC Controller返回值及异常的统一处理方法

    主要给大家介绍了关于Spring MVC Controller返回值及异常的统一处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring MVC具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    Spring Boot处理全局统一异常的两种方法与区别

    Spring Boot默认使用`BasicErrorController`来处理未被捕获的异常,产生如“Whitelabel Error Page”所示的错误页面。我们可以自定义一个`ErrorController`来覆盖默认行为: ```java @Slf4j @RestController public...

    pring异常处理共5页.pdf.zip

    在Spring中,异常处理主要是通过AOP(面向切面编程)来实现的,它允许我们在不修改原有业务代码的情况下,对程序运行过程中的异常进行统一管理。 【描述】:“Spring异常处理共5页.pdf.zip” 描述中的“共5页”...

    Spring MVC之Controller层的常用注解

    当Controller方法抛出异常时,标注了`@ExceptionHandler`的方法会被调用,可以统一处理错误并返回合适的响应。 10. `@InitBinder`:允许在请求处理之前对数据绑定进行自定义配置,如设置日期格式、排除某些字段等。...

    ControllerAdvice spring mvc 3.2 错误统一控制

    在Spring MVC框架中,错误处理是一项重要的功能,它能够帮助我们统一处理应用中的异常情况,从而为用户提供更加友好的错误信息和用户体验。在Spring MVC 3.2版本中,`@ControllerAdvice`注解的引入极大地简化了全局...

    STS创建Spring Boot项目实战(Rest接口、数据库、用户认证、分布式Token JWT、Redis操作、日志和统一异常处理)

    创建一个全面的Spring Boot应用,涵盖了多个关键领域,包括RESTful接口、数据库交互、用户认证、分布式Token的实现(JWT)、Redis缓存操作、日志记录以及统一异常处理。下面将详细阐述这些知识点。 1. **Spring ...

    spring boot exception handler.zip

    在实际项目中,处理异常是必不可少的一部分,Spring Boot为此提供了强大的异常处理机制。本篇将深入探讨Spring Boot的异常处理器,帮助你更好地理解和运用。 1. **Spring Boot异常处理基础** Spring Boot默认提供...

Global site tag (gtag.js) - Google Analytics