SpringMVC第三谈(请求重定向和转发、异常处理、拦截器、SSM的整合)

在这里插入图片描述

本人是一名物联网工程专业大二的学生,是互联网浪潮中一朵小小的浪花,写博客即是为了记录自己的学习历程,又希望能够帮助到很多和自己一样处于起步阶段的萌新。临渊羡鱼,不如退而结网。一起加油!
博客主页:https://blog.csdn.net/qq_44895397

SpringMVC完整般思维导图

请求重定向和转发

当处理器对请求处理完毕后,向其它资源进行跳转时,有两种跳转方式:请求转发与重定向。而根据所要跳转的资源类型,又可分为两类:跳转到页面与跳转到其它处理器。
对于请求转发的页面,可以是WEB-INF中页面;而重定向的页面,是不能为WEB-INF中页的。因为重定向相当于用户再次发出一次请求,而用户是不能直接访问 WEB-INF 中资源的
center
SpringMVC 框架把原来 Servlet 中的请求转发和重定向操作进行了封装。现在可以使用简单的方式实现转发和重定向。

  • forward:表示转发,实现request.getRequestDispatcher(“xx.jsp”).forward()
  • redirect:表示重定向,实现 response.sendRedirect(“xxx.jsp”)

请求转发

处理器方法返回 ModelAndView 时,需在 setViewName()指定的视图前添加 forward:,且此时的视图不再与视图解析器一同工作,这样可以在配置了解析器时指定不同位置的视图。视图页面必须写出相对于项目根的路径。forward 操作不需要视图解析器。处理器方法返回 String,在视图路径前面加入 forward: 视图完整路径。
语法:setViewName(“forward:使徒的完整路径”);
在这里插入图片描述

@RequestMapping("/handlerIntercwptor.do")
public ModelAndView forwardDemo(String name ,Integer age){
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname",name);
    mv.addObject("myage",age);
    mv.setViewName("forward:/WEB-INF/view/forward.jsp");
    return mv;
}

请求重定向

在处理器方法返回的视图字符串的前面添加 redirect:,则可实现重定向跳转。
处理器方法定义:
在这里插入图片描述

@RequestMapping("/handlerIntercwptor.do")
public ModelAndView redirectDemo(String name ,Integer age){
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname",name);
    mv.addObject("myage",age);
    mv.setViewName("redirect:/redirect.jsp");
    //mv.setViewName("redirect:/WEB-INF/view/forward.jsp");
    return mv;
}

异常处理

@ExceptionHandler 注解

使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。该注解只有一个可选属性 value,为一个 Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。

而被注解的方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参数赋值。

对于异常处理注解的用法,也可以直接将异常处理方法注解于Controller 之中
在这里插入图片描述

public @interface ExceptionHandler {
    Class<? extends Throwable>[] value() default {};
}

使用步骤:

  1. 自定义异常类
  2. 修改Controller抛出异常
  3. 自定义异常响应页面
  4. 自定义一场全局处理类
  5. 修改配置文件(声明异常类的存在)
    在这里插入图片描述

Controller抛出异常:

@RequestMapping("/some.do")
public ModelAndView addStudent(String name, Integer age) throws MyException {
    ModelAndView mv = new ModelAndView();
    if (!"zs".equals(name)) {
        throw  new NameException("名字有误");
    }
    if(age==null||age>100){
        throw new AgeException("年龄异常");
    }
    mv.addObject("myname", name);
    mv.addObject("myage", age);
    mv.setViewName("show");
    return mv;
}

在这里插入图片描述

扫描二维码关注公众号,回复: 11301139 查看本文章
/**
 * @ControllerAdvice :控制器增强,给控制器类增强功能
 * 在类上使用
 * 需要使用组件扫描器,让框架知道这个注解所在的包名
 *
 * 处理异常的方法和控制器方法的定义一样可以以有多个参数,可以返回ModelAndView
 * String,void对象返回值
 * 形参:Exception,获取异常发生的信息
 *  @ExceptionHandler :异常的class,表示发生异常的类型
 */
@ControllerAdvice
public class MyHandler {

    @ExceptionHandler(NameException.class)
    public ModelAndView ageExcrption(Exception e){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","宁输入的姓名异常");
        mv.addObject("message",e.getMessage());
        mv.setViewName("ageErorr");
        return mv;
    }
}

在这里插入图片描述

拦截器

SpringMVC 中的 Interceptor 拦截器它的主要作用是拦截指定的用户请求,并进行相应的预处理后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。

一个拦截器的执行

在这里插入图片描述

  1. preHandle(request,response, Object handler):

该方法在处理器方法执行之前执行。其返回值为 boolean,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。
在这里插入图片描述

/**
 *  preHandle:预处理方法,
 *  Object handler:被拦截的控制器对象
 *  返回值:boolean
 *      true:表示能够进入控制方法,
 *      false:请求被拦截
 *  特点:
 *      1、方法在控制器方法之前执行
 *      2、这个方法中能够验证请求的信息,验证请求是否符合要求
 *          验证失败可以截断请求
 */
@Override
public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler) throws Exception {
    System.out.println("preHandle,验证通过");
    return true;
}
  1. postHandle(request,response,Objecthandler,modelAndView):

该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。

在这里插入图片描述

 /**
     *后处理方法:
     * handler :被拦截的处理器对象
     * modelAndView:处理器方法的返回值,能够修改
     * 在处理器方法之后进行,没有返回值
     * 能够获取处理器返回值,能够修改视图和值
     * 对执行结果进行二次修正
     */
    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
  1. afterCompletion(request,response, Object handler, Exception ex):

当 preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。
afterCompletion 最后执行的方法,清除资源,例如在 Controller 方法中加入数据
在这里插入图片描述

/**
 * 最后执行的方法
 *
 *Exception:程序发生的异常
 * 在请求处理完成过后执行,视图处理完成后,对视图进行了forward就认为请求处理完成
 * 一般做资源回收工作
 */
@Override
public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex) throws Exception {
    System.out.println("afterCompletion");
}

拦截器中方法与处理器方法的执行顺序如下图:
在这里插入图片描述
在这里插入图片描述

多个拦截器的执行

当有多个拦截器时,形成拦截器链。拦截器链的执行顺序,与其注册顺序一致。需要再次强调一点的是,当某一个拦截器的preHandle()方法返回 true 并被执行到时,会向一个专门的方法栈中放入该拦截器的 afterCompletion()方法。
在这里插入图片描述

SSM的整合

两个容器:

  1. SpringMVC容器,管理Controller对象
  2. Spring容器,管理service,dao,工具类

实现步骤:

  1. 建表

  2. 新建maven项目

  3. 加入依赖:
    SpringMVC,servlet,jsp,jackson,Spring,Spring事务,Spring-MyBatis,Mybatis,mysql驱动,druid连接池

  4. web.xml
    1)注册DispatcherServlet,目的:创建springmvc容器,才能创建Controller类对象
    2)注册spring监听器:ContextLoaderListener,创建spring容器对象,才能创建service,dao等对象
    3)注册字符集过滤器,post请求乱码

  5. 创建包,Controller,service,dao,实体类

  6. springmvc,spring,mybatis的配置文件

pom.xml:

<dependencies>
    <!--添加依赖-->
    <!--servlet依赖-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp依赖 -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2.1-b03</version>
        <scope>provided</scope>
    </dependency>
    <!--springmvc的依赖,自动导入了spring的依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!--spring管理事务的依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!--jkson的依赖-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>
    <!--mybatis的依赖,spring-mybatis的依赖,德鲁伊连接池-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.12</version>
    </dependency>
    <!--Resource注解无法使用-->
    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.1</version>
    </dependency>
</dependencies>

spring的主配置文件:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:conf/mybatis.xml" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <property name="basePackage" value="com.yky.dao" />
    </bean>

    <!--创建出service的对象使用注解完成,添加注解扫描器-->
    <context:component-scan base-package="com.yky.service" />

springmvc的配置文件:

  1. 组件扫描器
  2. 视图解析器
  3. 数据类型转为json时用到@ResponseBody注解启动
    能够解决访问静态资源时的冲突问题
<context:component-scan base-package="com.yky.Controller"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:annotation-driven/>

本站所有文章均为原创,欢迎转载,请注明文章出处:爱敲代码的小游子

猜你喜欢

转载自blog.csdn.net/qq_44895397/article/details/106772405