spring mvc异常统一处理(使用ControllerAdvice注解)

1、配置

spring 版本:
  1. <org.springframework-version>4.1.9.RELEASE</org.springframework-version>  
<org.springframework-version>4.1.9.RELEASE</org.springframework-version>
spring-servlet.xml,注意必须开启注解,即xml要有<annotation-driven />
  1. <annotation-driven />  
<annotation-driven />
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans:beans xmlns="http://www.springframework.org/schema/mvc"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
  6.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  8.   
  9.     <!-- DispatcherServlet Context: defines this servlet's request-processing   
  10.         infrastructure -->  
  11.   
  12.     <!-- Enables the Spring MVC @Controller programming model -->  
  13.     <annotation-driven />  
  14.   
  15.     <!-- Handles HTTP GET requests for /resources/** by efficiently serving   
  16.         up static resources in the ${webappRoot}/resources directory -->  
  17.     <resources mapping="/resources/**" location="/resources/" />  
  18.   
  19.     <!-- Resolves views selected for rendering by @Controllers to .jsp resources   
  20.         in the /WEB-INF/views directory -->  
  21.     <beans:bean  
  22.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  23.         <beans:property name="prefix" value="/WEB-INF/views/" />  
  24.         <beans:property name="suffix" value=".jsp" />  
  25.     </beans:bean>  
  26.     <context:component-scan base-package="org.as.asjee" use-default-filters="false">  
  27.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  28.     </context:component-scan>  
  29.   
  30. </beans:beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	<context:component-scan base-package="org.as.asjee" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

</beans:beans>

2、异常统一处理类

  1. package org.as.asjee.core.exception;  
  2.   
  3. import java.sql.SQLException;  
  4.   
  5. import javax.servlet.http.HttpServletRequest;  
  6.   
  7. import org.as.asjee.core.log.AsJEELogger;  
  8. import org.as.asjee.core.log.AsJEELoggerFactory;  
  9. import org.springframework.web.bind.annotation.ControllerAdvice;  
  10. import org.springframework.web.bind.annotation.ExceptionHandler;  
  11. import org.springframework.web.bind.annotation.ResponseBody;  
  12. import org.springframework.web.servlet.ModelAndView;  
  13.   
  14. /** 
  15.  * 捕获异常统一处理 
  16.  * @description TODO 
  17.  * @author chen.gs 
  18.  * @create date 2016年4月28日 
  19.  * @modified by  
  20.  * @modify date 
  21.  * @version v1.0 
  22.  */  
  23. @ControllerAdvice  
  24. public class GlobalExceptionHandler {  
  25.       
  26.     private final static AsJEELogger LOG = AsJEELoggerFactory.getLogger(GlobalExceptionHandler.class);  
  27.       
  28.     private final static String EXPTION_MSG_KEY = "message";  
  29.       
  30.     @ExceptionHandler(BusinessException.class)  
  31.     @ResponseBody  
  32.     public void handleBizExp(HttpServletRequest request, Exception ex){  
  33.         LOG.info("Business exception handler  " + ex.getMessage() );  
  34.         request.getSession(true).setAttribute(EXPTION_MSG_KEY, ex.getMessage());  
  35.     }  
  36.       
  37.     @ExceptionHandler(SQLException.class)  
  38.     public ModelAndView handSql(Exception ex){  
  39.         LOG.info("SQL Exception " + ex.getMessage());  
  40.         ModelAndView mv = new ModelAndView();  
  41.         mv.addObject("message", ex.getMessage());  
  42.         mv.setViewName("sql_error");  
  43.         return mv;  
  44.     }  
  45.   
  46. }  
package org.as.asjee.core.exception;

import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;

import org.as.asjee.core.log.AsJEELogger;
import org.as.asjee.core.log.AsJEELoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 捕获异常统一处理
 * @description TODO
 * @author chen.gs
 * @create date 2016年4月28日
 * @modified by 
 * @modify date
 * @version v1.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {
	
	private final static AsJEELogger LOG = AsJEELoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	private final static String EXPTION_MSG_KEY = "message";
	
	@ExceptionHandler(BusinessException.class)
	@ResponseBody
	public void handleBizExp(HttpServletRequest request, Exception ex){
		LOG.info("Business exception handler  " + ex.getMessage() );
		request.getSession(true).setAttribute(EXPTION_MSG_KEY, ex.getMessage());
	}
	
	@ExceptionHandler(SQLException.class)
	public ModelAndView handSql(Exception ex){
		LOG.info("SQL Exception " + ex.getMessage());
		ModelAndView mv = new ModelAndView();
		mv.addObject("message", ex.getMessage());
		mv.setViewName("sql_error");
		return mv;
	}

}
自定义异常类BussinessException.java
  1. package org.as.asjee.core.exception;  
  2.   
  3. /** 
  4.  * 业务异常 
  5.  * @description TODO 
  6.  * @author chen.gs 
  7.  * @create date 2016年4月28日 
  8.  * @modified by  
  9.  * @modify date 
  10.  * @version v1.0 
  11.  */  
  12. public class BusinessException extends Exception{  
  13.   
  14.     private static final long serialVersionUID = 1L;  
  15.       
  16.     //业务类型  
  17.     private String bizType;  
  18.     //业务代码  
  19.     private int bizCode;  
  20.     //错误信息  
  21.     private String message;  
  22.       
  23.     public BusinessException(String bizType, int bizCode, String message){  
  24.         super(message);  
  25.         this.bizType = bizType;  
  26.         this.bizCode = bizCode;  
  27.         this.message = message;  
  28.     }  
  29.   
  30.     public BusinessException(String message){  
  31.         super(message);  
  32.         this.bizType = "";  
  33.         this.bizCode = -1;  
  34.         this.message = message;  
  35.     }  
  36.   
  37.     public BusinessException(String bizType, String message){  
  38.         super(message);  
  39.         this.bizType = bizType;  
  40.         this.bizCode = -1;  
  41.         this.message = message;  
  42.     }  
  43.       
  44.     public BusinessException(int bizCode, String message){  
  45.         super(message);  
  46.         this.bizType = "";  
  47.         this.bizCode = bizCode;  
  48.         this.message = message;  
  49.     }  
  50.   
  51.     public String getBizType() {  
  52.         return bizType;  
  53.     }  
  54.   
  55.     public void setBizType(String bizType) {  
  56.         this.bizType = bizType;  
  57.     }  
  58.   
  59.     public int getBizCode() {  
  60.         return bizCode;  
  61.     }  
  62.   
  63.     public void setBizCode(int bizCode) {  
  64.         this.bizCode = bizCode;  
  65.     }  
  66.   
  67.     public String getMessage() {  
  68.         return message;  
  69.     }  
  70.   
  71.     public void setMessage(String message) {  
  72.         this.message = message;  
  73.     }  
  74.   
  75. }  
package org.as.asjee.core.exception;

/**
 * 业务异常
 * @description TODO
 * @author chen.gs
 * @create date 2016年4月28日
 * @modified by 
 * @modify date
 * @version v1.0
 */
public class BusinessException extends Exception{

	private static final long serialVersionUID = 1L;
	
	//业务类型
	private String bizType;
	//业务代码
	private int bizCode;
	//错误信息
	private String message;
	
	public BusinessException(String bizType, int bizCode, String message){
		super(message);
		this.bizType = bizType;
		this.bizCode = bizCode;
		this.message = message;
	}

	public BusinessException(String message){
		super(message);
		this.bizType = "";
		this.bizCode = -1;
		this.message = message;
	}

	public BusinessException(String bizType, String message){
		super(message);
		this.bizType = bizType;
		this.bizCode = -1;
		this.message = message;
	}
	
	public BusinessException(int bizCode, String message){
		super(message);
		this.bizType = "";
		this.bizCode = bizCode;
		this.message = message;
	}

	public String getBizType() {
		return bizType;
	}

	public void setBizType(String bizType) {
		this.bizType = bizType;
	}

	public int getBizCode() {
		return bizCode;
	}

	public void setBizCode(int bizCode) {
		this.bizCode = bizCode;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

}

3、controller

  1. package org.as.asjee.core.security.web;  
  2.   
  3. import java.sql.SQLException;  
  4.   
  5. import javax.annotation.Resource;  
  6.   
  7. import org.as.asjee.core.exception.BusinessException;  
  8. import org.as.asjee.core.security.model.User;  
  9. import org.as.asjee.core.security.service.UserService;  
  10. import org.as.asjee.core.service.ServiceFacade;  
  11. import org.as.asjee.core.web.AbstractController;  
  12. import org.springframework.stereotype.Controller;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14.   
  15. @Controller  
  16. @RequestMapping("/security/user")  
  17. public class UserController  extends AbstractController<User>{  
  18.   
  19.     @Resource  
  20.     private UserService userService;  
  21.     @Resource  
  22.     private ServiceFacade serviceFacade;  
  23.   
  24.     @RequestMapping("login")  
  25.     public String login() {   
  26.         return "login";  
  27.     }  
  28.       
  29.     @RequestMapping("login2")  
  30.     public String login2() throws Exception {  
  31.         throw new SQLException("出错鸟。。。。。。。。。");  
  32.     }     
  33.       
  34.     @RequestMapping("login3")  
  35.     public String login3() throws Exception {   
  36.         throw new BusinessException("业务执行异常");  
  37.     }  
  38.       
  39.     //此方法抛出的异常不是由GlobalExceptionHandler处理  
  40.     //而是在catch块处理  
  41.     @RequestMapping("login4")  
  42.     public String login4() {   
  43.         try {  
  44.             throw new BusinessException("业务执行异常");  
  45.         } catch (BusinessException e) {  
  46.             e.printStackTrace();  
  47.         }  
  48.         return "login";  
  49.     }  
  50.       
  51. }  
package org.as.asjee.core.security.web;

import java.sql.SQLException;

import javax.annotation.Resource;

import org.as.asjee.core.exception.BusinessException;
import org.as.asjee.core.security.model.User;
import org.as.asjee.core.security.service.UserService;
import org.as.asjee.core.service.ServiceFacade;
import org.as.asjee.core.web.AbstractController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/security/user")
public class UserController  extends AbstractController<User>{

	@Resource
	private UserService userService;
	@Resource
	private ServiceFacade serviceFacade;

	@RequestMapping("login")
	public String login() { 
		return "login";
	}
	
	@RequestMapping("login2")
	public String login2() throws Exception {
		throw new SQLException("出错鸟。。。。。。。。。");
	}	
	
	@RequestMapping("login3")
	public String login3() throws Exception { 
		throw new BusinessException("业务执行异常");
	}
	
	//此方法抛出的异常不是由GlobalExceptionHandler处理
	//而是在catch块处理
	@RequestMapping("login4")
	public String login4() { 
		try {
			throw new BusinessException("业务执行异常");
		} catch (BusinessException e) {
			e.printStackTrace();
		}
		return "login";
	}
	
}

4、JSP页面

sql_error.jsp
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" %>  
  2. <!DOCTYPE html">  
  3. <html>  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6. <title>Insert title here</title>  
  7. </head>  
  8. <body>  
  9.     <h1>ERROR MESSAGE</h1>  
  10.     <p>${message}</p>  
  11. </body>  
  12. </html>  
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>ERROR MESSAGE</h1>
	<p>${message}</p>
</body>
</html>

5、简要说明

在Controller中抛出的异常,当没有被catch处理时,GlobalExceptionHandler中定义的处理方法可以起作用,在方法写明注解@ExceptionHandler,并注明其异常类即可。此种方法不仅可以作用于Controller,同样的在DAO层、service层也可,都可以由GlobalExceptionHandler进行处理。此种写法减少代码的入侵,值得推荐。
异常的统一处理只是注解ControllerAdvice用处之一,有兴趣了解更多的,请到spring官网查阅。
展开阅读全文

没有更多推荐了,返回首页