SpringMVC框架 -- 入门案例

一、SpringMVC入门案例

1. 添加依赖
spring-context spring-webmvc

2. web.xml

配置:

  • DispatcherServlet前端控制器
  • 加载springmvc.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <!--配置SpringMVC的前端控制器,所有的.do后缀的请求都经过这里-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载springMVC.xml配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:SpringMVC.xml</param-value>
        </init-param>
        <!--启动时候创建servlet对象,数字越小越先加载-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!--拦截所有.do为后缀的请求-->
        <!--举例:http://localhost:8080/hello.do-->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

注意:

  • 当配置了load-on-startup时,前端控制器在启动的时候创建,且控制器类也在启动时创建;如果没有配置,则控制器类在请求到达的时候才创建;
  • <init-parm>只在当前有效,<context-parm>是全局有效;
  • <url-pattern></url-pattern>中间不能写/*,可以写/。

3. 控制器

/**
 * 处理请求的控制器类(相当于servlet)
 */
@Controller  // 创建对象加入容器
public class HelloController {

    /**
     * 处理请求的方法
     * 1)请求要来到hello()方法
     *    @RequestMapping("/hello") 表示当前方法处理的请求路径,举例:http://localhost:8080/hello.do
     * 2)处理完请求后,需要跳转
     *    跳转的路径:http://localhost:8080/pages/success.jsp
     */
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("处理请求开始。。。。。");
        // 返回的就是跳转后的文件的名称
        // 路径缺少前缀: /pages/   路径缺少后缀: .jsp
        // 前缀与后缀在springMVC.xml中指定。
        return "success";
    }
}

4. springmvc.xml

  • 开启注解扫描
  • 配置视图解析器
  • 开启注解驱动
<?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">

    <!--1.开启注解扫描-->
    <context:component-scan base-package="com.itheima"/>

    <!--2. 配置视图解析器,可以实现路径的跳转-->
    <!--最终的路径是:http://localhost:8080/前缀/控制器方法返回值.后缀-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--跳转路径的前缀-->
        <property name="prefix" value="/pages/"/>
        <!--跳转路径的后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--3.开启springmvc的注解驱动(作用:自动创建处理器映射器、处理器适配器)-->
    <mvc:annotation-driven/>
</beans>

5. 测试
  访问地址:http://localhost:8080/hello.do

6. 小结:

  • SpringMVC默认跳转是转发;
  • 处理请求的控制器类是单例,容器中只有一个对象;
  • 当配置了load-on-startup时候,前端控制器在启动时创建,且控制器类也在启动时创建。如果没有配置load-on-startup,再第一次访问时创建前端控制器DispatcherServlet及处理请求的类。

二、SpringMVC Project 执行流程

1. 项目目录结构
项目执行流程

2. 项目执行过程时序图

在这里插入图片描述

3. 执行流程

1)服务器启动,应用被加载,读取到 web.xml 中的配置创建 spring 容器并且初始化容器中的对象;

2)浏览器发送请求,被 DispatherServlet 捕获,该 Servlet 并不处理请求,而是把请求转发出去。转发的路径是根据请求 URL匹配@RequestMapping 中的内容;

3)匹配后,执行对应方法,该方法有一个返回值;

4)根据方法的返回值,借助 InternalResourceViewResolver 找到对应的结果视图。


三、SpringMVC中常用注解

四、SpringMVC 拦截器

1. 过滤器

依赖于servlet容器,在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码、在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

2. 拦截器

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。谈到拦截器,不得不提拦截器链( Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

3. 相同点和区别

  • 都能对请求进行拦截,但是过滤器在url-pattern中配置/*能够拦截所有请求,拦截器只会拦截访问的控制器方法,如果访问的是 jsp, html,css,image或者js 是不会进行拦截的;

  • 在请求之前都能做一些工作,请求处理完毕后,也能做一些后续功能;

  • 过滤器是servlet规范中的一部分,任何JavaWeb先项目都能使用,拦截器依赖于SpringMVC框架,只有使用了SpringMVC框架的工程才能用。


4. 多个自定义拦截器的执行步骤

第一步:编写控制器

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/find")
    public String find(Model model) {

        //int i = 1 / 0;
        System.out.println("2.find...");
        return "success";
    }
}

第二步:编写类实现 HandlerInterceptor 接口

编写拦截器HandlerInterceptorDemo:

public class HandlerInterceptorDemo implements HandlerInterceptor {

    // 在请求进入控制器方法之前,先执行这里。(如果配置了拦截器,这里肯定执行)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("1.HandlerInterceptorDemo.preHandle()");
        // 返回true相当于放行;false不放行
        return true;
    }

    /**
     * 1. preHandle()必须返回为true时候这里才可能执行。
     * 2. 执行完控制器方法,且没有异常时候,再执行这里
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("3.HandlerInterceptorDemo.postHandler()");
    }

    /**
     * 1.preHandle()必须返回为true时候这里才能执行。
     * 2.无论控制器方法有没有异常,这里都会执行。(finally)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("4.最后执行HandlerInterceptorDemo.afterCompletion()");
    }
}

编写拦截器HandlerInterceptorDemo2:

public class HandlerInterceptorDemo2 implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("1.HandlerInterceptorDemo2.preHandle()");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("3.HandlerInterceptorDemo2.postHandler()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("4.最后执行HandlerInterceptorDemo2.afterCompletion()");
    }
}

第三步:配置拦截器

<!--1.开启注解扫描-->
<context:component-scan base-package="com.zz" />

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

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

<!--4.配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--拦截所有请求-->
        <mvc:mapping path="/**"/>
        <!--自定义的拦截器-->
        <bean class="com.zz.controller.HandlerInterceptorDemo"/>
    </mvc:interceptor>

    <!--配置另一个拦截器-->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.zz.controller.HandlerInterceptorDemo2"/>
    </mvc:interceptor>
</mvc:interceptors>

第四步:测试localhost:8080/user/find,测试结果如下
执行结果

5. 自定义拦截器的执行流程图
执行流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值