SpringMVC异常处理

2022-09-15 13:58:49 浏览数 (1)

1、springMVC异常处理概述

1.1、springMVC中的异常

在程序开发中,不管是那层的业务,都会不可避免的出现异常处理。如果每层单独处理异常,那么系统的代码的耦合度就会提高。而且工作量也会加大,不好处理。

而springMVC将所有类型的异常从各层解耦出来,进行异常的统一处理和维护。

springMVC异常处理有三种:

简单异常处理器 SimpleMappingExceptionResolver。

异常处理接口 HandlerExceptionResolver 自定义自己的异常处理器。

@ExceptionHandler 注解实现异常处理。

1.2、异常处理结构图

1.3、异常处理前的准备

1.3.1、需求

完成springMVC异常处理,创建三层架构(daoserviceview)

1.3.2、创建新项目

创建一个maven项目smvc005

1.3.3、导入jar包

pom.xml

代码语言:javascript复制
 <properties>
    <spring.version>5.2.2.RELEASE</spring.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
  </dependencies>
1.3.4、配置web.xml

web.xml

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
  <display-name>Archetype Created Web Application</display-name>
  <!--配置SpringMVC核心,前置控制器DispatcherServlet -->
  <servlet>
    <servlet-name>SpringMVCDispathcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--配置初始化参数,用来读取springmvc.xml文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/springmvc.xml</param-value>
    </init-param>
    <!--配置servlet的对象的创建时间点:应用加载时创建。取值只能是非0正整数,表示启动顺序-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!--前置控制器,映射所有地址-->
  <servlet-mapping>
    <servlet-name>SpringMVCDispathcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
1.3.5、配置springmvc.xml

springmvc.xml

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="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">
    <!--配置扫描器,扫描注解-->
    <context:component-scan base-package="com.tyschool.smvc004"></context:component-scan>
    <!--配置视图解析器,配置前缀和后缀-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
1.3.6、启动服务

http://localhost:8080/smvc004/index.jsp

2、配置各层异常

2.1、自定义异常类

DemoException.java

代码语言:javascript复制
public class DemoException extends Exception {
    public DemoException(){}
    public DemoException(String message){
        super(message);
    }
}

2.2、dao层

ExceptionDao.java

代码语言:javascript复制
package com.tyschool.smvc004.dao;

import com.tyschool.smvc004.utils.DemoException;
import org.springframework.stereotype.Repository;

import java.sql.SQLException;

@Repository("exceptionDao")
public class ExceptionDao {
    public void dbDao() throws Exception{
        throw new SQLException("数据库异常-dao");
    }
    public void myDao() throws Exception{
        throw new DemoException("自定义异常-dao");
    }
    public void noDao() throws Exception{
        throw new SQLException("未知异常-dao");
    }
}

2.3、service层

IExceptionService.java

代码语言:javascript复制
public interface IExceptionService {
    public void myService()throws Exception;
    public void dbService()throws Exception;
    public void noService()throws Exception;
    public void myDao()throws Exception;
    public void dbDao()throws Exception;
    public void noDao()throws Exception;
}

ExceptionServiceImpl.java

代码语言:javascript复制
import com.tyschool.smvc004.dao.ExceptionDao;
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.SQLException;

@Service("exceptionServiceImpl")
public class ExceptionServiceImpl implements IExceptionService {
    @Autowired
    private ExceptionDao exceptionDao;

    @Override
    public void myService() throws Exception {
        throw new DemoException("自定义异常-Service");
    }

    @Override
    public void dbService() throws Exception {
        throw new SQLException("数据库异常-Service");
    }

    @Override
    public void noService() throws Exception {
        throw new SQLException("未知异常-Service");
    }

    @Override
    public void myDao() throws Exception {
        exceptionDao.myDao();
    }

    @Override
    public void dbDao() throws Exception {
        exceptionDao.dbDao();
    }

    @Override
    public void noDao() throws Exception {
        exceptionDao.noDao();
    }
}

2.4、控制器controller

ExceptionController.java

代码语言:javascript复制
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.sql.SQLException;

@Controller("exceptionController")
public class ExceptionController {
    @Autowired
    @Qualifier("exceptionServiceImpl")
    private IExceptionService exceptionService;

    @RequestMapping("/db")
    public void db() throws Exception{
        throw new SQLException("数据库异常-Controller");
    }
    @RequestMapping("/my")
    public void my() throws Exception{
        throw new DemoException("自定义异常-Controller");
    }
    @RequestMapping("/no")
    public void no() throws Exception{
        throw new SQLException("未知异常-Controller");
    }

    @RequestMapping("/dbS")
    public void dbService() throws Exception{
        exceptionService.dbService();
    }
    @RequestMapping("/myS")
    public void myService() throws Exception{
        exceptionService.myService();
    }
    @RequestMapping("/noS")
    public void noServcie() throws Exception{
        exceptionService.noService();
    }

    @RequestMapping("/dbD")
    public void dbDao() throws Exception{
       exceptionService.dbDao();
    }
    @RequestMapping("/myD")
    public void myDao() throws Exception{
       exceptionService.myDao();
    }
    @RequestMapping("/noD")
    public void noDao() throws Exception{
       exceptionService.noDao();
    }
}

3、创建view层

3.1、首页

index.jsp

代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
</head>
<body>
<h3><a href="${pageContext.request.contextPath }/dbD"> 处理dao中数据库异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/myD"> 处理dao中自定义异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/noD"> 处理dao未知异常</a></h3>
<hr>
<h3><a href="${pageContext.request.contextPath }/dbS">处理 service中数据库异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/myS">处理 service中自定义异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/noS">处理 service未知异常</a></h3>
<hr>
<h3><a href="${pageContext.request.contextPath }/db">处理 controller中数据库异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/my">处理 controller中自定义异常</a></h3>
<h3><a href="${pageContext.request.contextPath }/no">处理 controller未知异常</a></h3>
<hr>
<!-- 在 web.xml中配置404 -->
<h3>
<a href="${pageContext.request.contextPath }/404">404 错误</a>
</h3>
</body>
</html>

3.2、404

404.jsp

代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>404</title>
</head>
<body>
没能找到资源!
</body>
</html>

3.3、error

/pages/error.jsp

代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>error</title>
</head>
<body>
<H1>未知错误:</H1><%=exception %>
<H2>错误内容:</H2>
<%
    exception.printStackTrace(response.getWriter());
%>
</body>
</html>

3.4、my-error

/pages/my-error.jsp

代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>my-error</title>
</head>
<body>
<H1>自定义异常错误:</H1><%=exception %>
<H2>错误内容:</H2>
<%
    exception.printStackTrace(response.getWriter());
%>
</body>
</html>

3.5、sql-error

/pages/sql-error.jsp

代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>sql-error</title>
</head>
<body>
<H1>数据库异常错误:</H1><%=exception %>
<H2>错误内容:</H2>
<%
    exception.printStackTrace(response.getWriter());
%>
</body>
</html>

3.6、测试

http://localhost:8080/smvc004/index.jsp

4、SimpleMappingExceptionResolver

org.springframework.web.servlet.handler.SimpleMappingExceptionResolver

springmvc.xml

代码语言:javascript复制
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面,当该异常类型注册时使用 -->
        <property name="defaultErrorView" value="error"></property>
        <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
        <property name="exceptionAttribute" value="exception"></property>
        <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
        <property name="exceptionMappings">
            <props>
                <prop key="com.tyschool.smvc004.utils.DemoException">my-error</prop>
                <prop key="java.sql.SQLException">sql-error</prop>
                <!-- 在这里还可以继续扩展对不同异常类型的处理 -->
            </props>
        </property>
    </bean>

404配置

代码语言:javascript复制
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

5、HandlerExceptionResolver

org.springframework.web.servlet.HandlerExceptionResolver

5.1、加入jar包

代码语言:javascript复制
<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
</dependency>

5.2、MyExceptionHandler

MyExceptionHandler.java

代码语言:javascript复制
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class MyExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        Map<String,Object> model=new HashMap<String,Object>();
        model.put("exception",e);
        if(e instanceof DemoException){
            return new ModelAndView("my-error",model);
        }else if(e instanceof SQLException){
            return new ModelAndView("sql-error",model);
        }else{
            return new ModelAndView("error",model);
        }
    }
}

5.3、配置bean

Springmvc.xml

代码语言:javascript复制
 <bean class="com.tyschool.smvc004.utils.MyExceptionHandler"></bean>

5.4、测试

http://localhost:8080/smvc004/index.jsp

6、@ExceptionHandler

6.1、创建异常处理类

BaseController.java

代码语言:javascript复制
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;

public class BaseController {
    /** 基于@ExceptionHandler异常处理 */
    @ExceptionHandler
    public String exception(HttpServletRequest request, Exception ex) {
        request.setAttribute("exception", ex);
        // 根据不同错误转向不同页面,即异常与view的对应关系
        if (ex instanceof SQLException) {
            return "sql-error";
        } else if (ex instanceof DemoException) {
            return "my-error";
        } else {
            return "error";
        }
    }
}

6.2、创建新控制器

TestExceptionController.java

代码语言:javascript复制
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.sql.SQLException;
@Controller("testExceptionController")
public class TestExceptionController extends BaseController {
    @Autowired
    @Qualifier("exceptionServiceImpl")
    private IExceptionService exceptionService;

    @RequestMapping("/db")
    public void db() throws Exception{
        throw new SQLException("数据库异常-Controller");
    }
    @RequestMapping("/my")
    public void my() throws Exception{
        throw new DemoException("自定义异常-Controller");
    }
    @RequestMapping("/no")
    public void no() throws Exception{
        throw new SQLException("未知异常-Controller");
    }

    @RequestMapping("/dbS")
    public void dbService() throws Exception{
        exceptionService.dbService();
    }
    @RequestMapping("/myS")
    public void myService() throws Exception{
        exceptionService.myService();
    }
    @RequestMapping("/noS")
    public void noServcie() throws Exception{
        exceptionService.noService();
    }

    @RequestMapping("/dbD")
    public void dbDao() throws Exception{
        exceptionService.dbDao();
    }
    @RequestMapping("/myD")
    public void myDao() throws Exception{
        exceptionService.myDao();
    }
    @RequestMapping("/noD")
    public void noDao() throws Exception{
        exceptionService.noDao();
    }
}

6.3、测试

http://localhost:8080/smvc004/index.jsp

0 人点赞