Spring 学习小记(十八)

67 篇文章 0 订阅
Spring MVC异常处理
 
本小记学习目标
  1. SimpleMappingExceptionResolver
  2. HandlerExceptionResolver接口
  3. @ExceptionHandler注解
 
Spring MVC开发中,不管是对数据库操作、业务层操作、控制器层操作都有可能产生各种异常需要处理,对于异常的处理如果散落在各处,则它的耦合性则太高,从而加大了工作量并且处理方式不好统一。Spring MVC框架为了解决这个问题提供了相应的解决方案。
我们有三种式方式来统一处理异常:
第一、Spirng MVC提供的简单异常处理器SimpleMappingExceptionResolver
第二、Spring的异常处理接口HandlerExceptionResolver接口
第三、@ExceptionHandler注解
 
一、SimpleMappingExceptionResolver
实例说明
1.新增一个Maven的war工程,在pom.xml中导入如下jar依赖
< dependencies >
             <!-- context -->
             < dependency >
                   < groupId >org.springframework </ groupId >
                   < artifactId >spring-context </ artifactId >
                   < version >5.0.2.RELEASE </ version >
             </ dependency >
          <!-- Spring MVC -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring- webmvc </ artifactId >
             < version >5.0.2.RELEASE </ version >
          </ dependency >
         
          <!-- Spring web -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring-web </ artifactId >
             < version >5.0.2.RELEASE </ version >
             </ dependency >
         
          <!-- commons-logging -->
          < dependency >
             < groupId >commons-logging </ groupId >
             < artifactId >commons-logging </ artifactId >
             < version >1.2 </ version >
          </ dependency >
         
          <!-- spring- aop -->
          < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring- aop </ artifactId >
             < version >5.0.2.RELEASE </ version >
          </ dependency >
         
             < dependency >
             < groupId >javax.servlet </ groupId >
             < artifactId > jstl </ artifactId >
             < version >1.2 </ version >
             </ dependency >
       </ dependencies >
2.新增一个自己定义的异常类com.xiaoxie.exception.MyException
package com.xiaoxie.exception;
public class MyException extends Exception{
       private static final long serialVersionUID = 1L;
       public MyException() {
             super();
      }
      
       public MyException(String message) {
             super( message);
      }
}
3.新增一个Dao,com.xiaoxie.dao.ExceptionDao
package com.xiaoxie.dao;
import java.sql.SQLException;
import org.springframework.stereotype.Repository;
import com.xiaoxie.exception.MyException;
@Repository( "exceptionDao")
public class ExceptionDao {
       public void daoDBException() throws SQLException {
             throw new SQLException( "Dao中数据库异常!");
      }
      
       public void daoMyException() throws MyException {
             throw new MyException( "Dao中自定义的异常!");
      }
      
       public void daoUnknownException() throws Exception {
             throw new Exception( "Dao中未知异常!");
      }
}
4.新增一个service接口和service的实现类,com.xiaoxie.service.ExceptionService、com.xiaoxie.service.impl.ExceptionServiceImpl
ExceptionService:
package com.xiaoxie.service;
public interface ExceptionService {
       void serviceMyException() throws Exception;
       void serviceDBException() throws Exception;
       void serviceUnknownException() throws Exception;
      
       void daoMyException() throws Exception;
       void daoDBException() throws Exception;
       void daoUnknownException() throws Exception;
}
ExceptionServiceImpl:
package com.xiaoxie.service.impl;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xiaoxie.dao.ExceptionDao;
import com.xiaoxie.exception.MyException;
import com.xiaoxie.service.ExceptionService;
@Service( "exceptionService")
public class ExceptionServiceImpl implements ExceptionService{
       @Autowired
       private ExceptionDao exceptionDao;
      
       @Override
       public void serviceMyException() throws Exception {
             throw new MyException( "service中自己定义异常!");
      }
       @Override
       public void serviceDBException() throws Exception {
             throw new SQLException( "service中数据库异常!");
      }
       @Override
       public void serviceUnknownException() throws Exception {
             throw new Exception( "service中未知异常!");
      }
       @Override
       public void daoMyException() throws Exception {
             exceptionDao.daoMyException();
      }
       @Override
       public void daoDBException() throws Exception {
             exceptionDao.daoDBException();
      }
       @Override
       public void daoUnknownException() throws Exception {
             exceptionDao.daoUnknownException();
      }
}
5.新增Controller类:com.xiaoxie.controller.ExceptionController
package com.xiaoxie.controller;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xiaoxie.exception.MyException;
import com.xiaoxie.service.ExceptionService;
@Controller
public class ExceptionController {
       @Autowired
       private ExceptionService exceptionService;
      
       @RequestMapping( "/db")
       public void controllerDBExcepton() throws Exception {
             throw new SQLException( "控制器中数据库异常!");
      }
      
       @RequestMapping( "/my")
       public void controllerMyException() throws Exception {
             throw new MyException( "控制器中自定义异常!");
      }
      
       @RequestMapping( "/no")
       public void controllerUnknownException() throws Exception {
             throw new Exception( "控制器中未知异常!");
      }
      
      
       @RequestMapping( "/servicedb")
       public void serviceDBExcepton() throws Exception {
             exceptionService.serviceDBException();
      }
      
       @RequestMapping( "/servicemy")
       public void serviceMyException() throws Exception {
             exceptionService.serviceMyException();
      }
      
       @RequestMapping( "/serviceno")
       public void serviceUnknownException() throws Exception {
             exceptionService.serviceUnknownException();
      }
      
      
       @RequestMapping( "/daodb")
       public void daoDBExcepton() throws Exception {
             exceptionService.daoDBException();
      }
      
       @RequestMapping( "/daomy")
       public void daoMyException() throws Exception {
             exceptionService.daoMyException();
      }
      
       @RequestMapping( "/daono")
       public void daoUnknownException() throws Exception {
             exceptionService.daoUnknownException();
      }
}
6.定义视图:index.jsp,404.jsp,error.jsp,my-error.jsp,sql-error.jsp(注意:这里的视图都是定义在webcontent下的,这里的位置与配置视图解析器时有关系)
index.jsp:
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >index </ title >
</ head >
< body >
       < a href= "${pageContext.request.contextPath } /daodb" >处理 dao中数据库异常 </ a >
       < a href= "${pageContext.request.contextPath } /daomy" >处理 dao中自定义异常 </ a >
       < a href= "${pageContext.request.contextPath } /daono" >处理 dao中未知异常 </ a >
       < hr />
       < a href= "${pageContext.request.contextPath } /servicedb" >处理service中数据库异常 </ a >
       < a href= "${pageContext.request.contextPath } /servicemy" >处理service中自定义异常 </ a >
       < a href= "${pageContext.request.contextPath } /serviceno" >处理service中未知异常 </ a >
       < hr />
       < a href= "${pageContext.request.contextPath } /db" >处理controller中数据库异常 </ a >
       < a href= "${pageContext.request.contextPath } /my" >处理controller中自定义异常 </ a >
       < a href= "${pageContext.request.contextPath } /no" >处理controller中未知异常 </ a >
       < hr />
       < a href= "${pageContext.request.contextPath } /404" >404错误 </ a >
</ body >
</ html >
404.jsp:
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" isErrorPage= "true" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >404 </ title >
</ head >
< body >
      资源不存在!
</ body >
</ html >
error.jsp:
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" isErrorPage= "true" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >未知异常 </ title >
</ head >
< body >
      程序出现未知错误: <%=exception %>
       < br />
      错误内容:
       < br />
       <%
            exception.printStackTrace(response.getWriter());
       %>
</ body >
</ html >
my-error.jsp:
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" isErrorPage= "true" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >自定义异常 </ title >
</ head >
< body >
      自定义异常错误: <%=exception %>
       < br />
      错误内容:
       < br />
       <%
            exception.printStackTrace(response.getWriter());
       %>
</ body >
</ html >
sql-error.jsp:
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" isErrorPage= "true" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
< html >
< head >
< meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
< title >Insert title here </ title >
</ head >
< body >
      数据库异常错误: <%=exception %>
       < br />
      错误内容:
       < br />
       <%
            exception.printStackTrace(response.getWriter());
       %>
</ body >
</ html >
注意:几个异常jsp页面中定义了isErrorPage="true",否则不可以使用exception对象
7.web.xml配置
<? xml version= "1.0" encoding= "UTF-8" ?>
<!-- 全局的异常处理页面 -->
< error-page >
       < error-code >404 </ error-code >
       < location >/404. jsp </ location >
</ error-page >
<!-- 前端核心 servlet 的配置(DispatcherServlet) -->
       < servlet >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < servlet-class >org.springframework.web.servlet.DispatcherServlet </ servlet-class >
             < init-param >
                   < param-name >contextConfigLocation </ param-name >
                   < param-value >classpath:springmvc.xml </ param-value >
             </ init-param >
             < load-on-startup >1 </ load-on-startup >
       </ servlet >
       <!-- Map all requests to the DispatcherServlet for handling -->
       < servlet-mapping >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < url-pattern >/ </ url-pattern >
       </ servlet-mapping >
      
       <!-- 配置解决 psot 请求中文乱码问题 -->
       < filter >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < filter-class >org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
             < init-param >
                   < param-name >encoding </ param-name >
                   < param-value > utf-8 </ param-value >
             </ init-param >
             < init-param >
                   < param-name >forceEncoding </ param-name >
                   < param-value >true </ param-value >
             </ init-param >
       </ filter >
       < filter-mapping >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < url-pattern >/* </ url-pattern >
       </ filter-mapping >
</ web-app >
注意:404的配置,当出现404的错误时定位到404.jsp,由于404.jsp这个页面是在webcontent目录下,所以配置时使用/404.jsp
8.在classpath下新增spring的配置文件springmvc.xml
<? xml version= "1.0" encoding= "UTF-8" ?>
       xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context= "http://www.springframework.org/schema/context"
       <!-- spring自动扫描 -->
       < context:component-scan base-package= "com.xiaoxie.controller" />
       < context:component-scan base-package= "com.xiaoxie.service" />
       < context:component-scan base-package= "com.xiaoxie.dao" />
      
       <!-- 配置视图解析器 -->
       < bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" id= "internalResourceViewResolver" >
             <!-- 前缀 -->
             < property name= " prefix" value= "/" />
             <!-- 后缀 -->
             < property name= " suffix" value= ".jsp" />
       </ bean >
      
       <!-- 配置SimpleMappingExceptionResolver(异常与视图的对应关系) -->
       < bean class= "org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id= "simpleMappingExceptionResolver" >
             <!-- 定义默认的异常处理页面 -->
             < property name= " defaultErrorView" value= "error" />
             <!-- 定义异常处理页面用来获取异常信息的变量名称 ,默认为exception -->
             < property name= " exceptionAttribute" value= "ex" />
             <!-- 定义需要特殊处理的异常 -->
             < property name= " exceptionMappings" >
                   < props >
                         < prop key= "com.xiaoxie.exception.MyException" >my-error </ prop >
                         < prop key= "java.sql.SQLException" > sql-error </ prop >
                   </ props >
             </ property >
       </ bean >
</ beans >
注意:这个配置文件中的关键是配置了SimpleMappingExceptionResolver这个bean,从与把产生的异常与对应的视图关联起来
 
二、HandlerExceptionResolver接口实现异常的统一处理
org.springframework.web.servlet.HandlerExceptionResolver接口用于解析请求处理过程中所产生的异常,我们可以实现这个接口来对异常做统一的处理。
1.在com.xiaoxie.exception包下新增一个实现类MyExceptionHandler
package com.xiaoxie.exception;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class MyExceptionHandler implements HandlerExceptionResolver{
       @Override
       public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                  Exception ex) {
            Map<String,Object> model = new HashMap<String,Object>();
             model.put( "ex", ex);
             //根据不同的异常来转到不同的页面
             if( ex instanceof MyException) {
                   return new ModelAndView( "my-error", model);
            } else if( ex instanceof SQLException) {
                   return new ModelAndView( "sql-error", model);
            } else {
                   return new ModelAndView( "error", model);
            }
      }
}
2.在Spring的配置文件中托管MyExceptionHandler,对实例中的SimpleMappingExceptionResolver进行注释,并在后面添加如下配置进行MyExceptionHandler的托管
<!-- Spring托管MyExceptionHandler -->
< bean class= "com.xiaoxie.exception.MyExceptionHandler" />
 
三、@ExceptionHandler注解声明异常处理方法
1.定义一个抽象类:BaseExceptionController类
package com.xiaoxie.controller;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.xiaoxie.exception.MyException;
public abstract class BaseExceptoinController {
       @ExceptionHandler
       public String exception(HttpServletRequest request,Exception ex) {
             //request.setAttribute(" ex ", ex );
             if( ex instanceof MyException) {
                   return "my-error";
            } else if( ex instanceof SQLException) {
                   return "sql-error";
            } else {
                   return "error";
            }
      }
}
2.对于controller实现类extends BaseExceptionController
3.把实例中对MyExceptionHandler托管的配置进行注释
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值