SpringMVC学习(五)

一、SpringMVC的异常处理

1.异常处理思路

Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。

2.SpringMVC的异常处理代码

2.1controller代码
java 复制代码
package com.qcby.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 *
 * 老师
 * 模拟异常
 */
@Controller
@RequestMapping("/role")
public class RoleController {

    /**
     * 自己处理异常
     * @return
     */
    /*
    @RequestMapping("/findAll.do")
    public String findAll(){

        try {
            System.out.println("执行了...");
            // 模拟异常
            int a = 10/0;
        } catch (Exception e) {
            e.printStackTrace();
            // 跳转到友好提示页面
        }

        return "suc";
    }
    */

    /**
     * 使用异常处理器方式
     * @return
     */
    @RequestMapping("/findAll.do")
    public String findAll(){
        System.out.println("执行了...");
        // 模拟异常
        int a = 10/0;
        return "suc";
    }

}
2.2自定义异常类
java 复制代码
package com.qcby.demo;

public class SysException extends Exception {

    // 提示消息
    private String message;

    @Override
    public String getMessage() {
        return message;
    }

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

    public SysException(String message) {
        this.message = message;
    }

}

自定义异常处理器

java 复制代码
<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!-- 扫描包 -->
<context:component-scan base-package="com.qcby.demo" />

<!-- 注解驱动 -->
<mvc:annotation-driven />

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
</bean>

<!-- 注册全局异常处理器 -->
<bean id="sysExceptionResolver" class="com.qcby.demo.SysExceptionResolver" />

</beans>
2.3配置异常处理器

springmvc.xml

java 复制代码
<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!-- 扫描包 -->
<context:component-scan base-package="com.qcby.demo" />

<!-- 注解驱动 -->
<mvc:annotation-driven />

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
</bean>

<!-- 注册全局异常处理器 -->
<bean id="sysExceptionResolver" class="com.qcby.demo.SysExceptionResolver" />

</beans>
2.4error.jsp页面代码
java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>错误提示页面</title>
</head>
<body>

<h3>错误的友好提示页面</h3>

${errorMsg}

</body>
</html>

二、SpringMVC框架中的拦截器

1.拦截器的概述

1.1springMVC框架中的拦截器用于对处理器进行预处理和后处理的技术
1.2可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
1.3拦截器和过滤器的功能比较类似,有区别
  1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
  2. 拦截器是SpringMVC框架独有的。
  3. 过滤器配置了/*,可以拦截任何资源。
  4. 拦截器只会对控制器中的方法进行拦截。
1.4拦截器也是AOP思想的一种实现方式
1.5想要自定义拦截器,需要实现HandlerInterceptor接口。

2. 自定义拦截器步骤

2.1controller代码
java 复制代码
package com.qcby.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 测试拦截器
 */
@Controller
@RequestMapping("/dept")
public class DeptController {

    /**
     * 测试方法
     * @return
     */
    @RequestMapping("/findAll.do")
    public String findAll() {
        System.out.println("controller方法执行了...");
        return "suc";
    }

    @RequestMapping("/login.do")
    public String find() {
        System.out.println("controller方法执行了...");
        return "suc";
    }

}
2.2创建类,实现HandlerInterceptor接口,重写需要的方法
java 复制代码
package com.qcby.demo;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 老师
 * 拦截器类
 */
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 拦截controller中方法。放行了,执行controller中方法。
     * return true 放行
     * return false 拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器preHandle方法执行了...");
        // 手动跳转页面
        // request.getRequestDispatcher("/index.jsp").forward(request,response);
        // 拦截,不放行
        // return false;
        // 放行
        return true;
    }

}
2.3在springmvc.xml中配置拦截器类
java 复制代码
<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描包 -->
    <context:component-scan base-package="com.qcby.demo" />

    <!-- 注解驱动 -->
    <mvc:annotation-driven />

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 配置拦截器们 -->
    <mvc:interceptors>
        <!-- 配置拦截器 -->
        <mvc:interceptor>
            <!-- 该拦截器拦截哪些资源 -->
            <mvc:mapping path="/dept/**"/>
            <!-- 哪些资源不想拦截 -->
            <mvc:exclude-mapping path="/dept/login.do"/>
            <!-- 拦截器对象(注意包路径要与Controller一致) -->
            <bean class="com.qcby.demo.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

</beans>

3. HandlerInterceptor接口中的方法

3.1preHandle方法是controller方法执行前拦截的方法
  1. 可以使用request或者response跳转到指定的页面
  2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
  3. return false不放行,不会执行controller中的方法。
3.2postHandle是controller方法执行后执行的方法,在JSP视图执行前。
  1. 可以使用request或者response跳转到指定的页面
  2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。

3.3afterCompletion方法是在JSP执行后执行

  1. request或者response不能再跳转页面了
java 复制代码
package com.qcby.demo;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 老师
 * 拦截器类
 */
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 拦截controller中方法。放行了,执行controller中方法。
     * return true 放行
     * return false 拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器preHandle方法执行了...");
        // 手动跳转页面
        // request.getRequestDispatcher("/index.jsp").forward(request,response);
        // 拦截,不放行
        // return false;
        // 放行
        return true;
    }

    /**
     * controller方法执行后,要拦截的方法
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法执行了...");
        // 也是可以进行页面的跳转
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

    /**
     * controller跳转的jsp页面都执行完成了,最后执行该方法
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion方法执行了...");
    }

}

3. 配置多个拦截器

3.1再编写一个拦截器的类
java 复制代码
package com.qcby.demo;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器类
 */
public class MyInterceptor2 implements HandlerInterceptor {

    /**
     * 拦截controller中方法。放行了,执行controller中方法。
     * return true 放行
     * return false 拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2的preHandle方法执行了...");
        // 放行
        return true;
    }

    /**
     * controller方法执行后,要拦截的方法
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor2的postHandle方法执行了...");
    }

    /**
     * controller跳转的jsp页面都执行完成了,最后执行该方法
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor2的afterCompletion方法执行了...");
    }

}
3.2配置2个拦截器
java 复制代码
<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描包 -->
    <context:component-scan base-package="com.qcby.demo" />

    <!-- 注解驱动 -->
    <mvc:annotation-driven />

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 配置拦截器们 -->
    <mvc:interceptors>
        <!-- 配置拦截器 -->
        <mvc:interceptor>
            <!-- 该拦截器拦截哪些资源 -->
            <mvc:mapping path="/dept/**"/>
            <!-- 哪些资源不想拦截 -->
            <mvc:exclude-mapping path="/dept/login.do"/>
            <!-- 拦截器对象(注意包路径要与Controller一致) -->
            <bean class="com.qcby.demo.MyInterceptor"/>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.qcby.demo.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

</beans>
相关推荐
largecode1 小时前
如何让电话显示店名?来电显示店铺名称,提升有效接通率
java·开发语言·spring·百度·学习方法·业界资讯·twitter
Aurorar0rua1 小时前
CS50 x 2024 Notes C -11
c语言·开发语言·学习方法
Dlrb12111 小时前
C语言-指针
c语言·开发语言
炽烈小老头1 小时前
【每天学习一点算法 2026/05/15】被围绕的区域
学习·算法·深度优先
计算机安禾1 小时前
【c++面向对象编程】第22篇:输入输出运算符重载:<< 与 >> 的友元实现
java·前端·c++
zhangzhi19798155921 小时前
Agent Skills
开发语言·python
旷世奇才李先生1 小时前
Java虚拟线程原理与实践
java
中屹指纹浏览器1 小时前
2026平台集群式风控溯源体系研究与浏览器环境适配应对方案
经验分享·笔记
秋雨梧桐叶落莳1 小时前
iOS——ZARA仿写项目
学习·macos·ios·objective-c·cocoa