SpringMVC框架 -- 入门案例

一、SpringMVC入门案例

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

2. web.xml

配置:

  • DispatcherServlet前端控制器
  • 加载springmvc.xml配置文件

<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">

    
    <servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:SpringMVC.xmlparam-value>
        init-param>
        
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        
        
        <url-pattern>*.dourl-pattern>
    servlet-mapping>

web-app>

注意:

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

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

  • 开启注解扫描
  • 配置视图解析器
  • 开启注解驱动

<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.itheima"/>

    
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/pages/"/>
        
        <property name="suffix" value=".jsp"/>
    bean>

    
    <mvc:annotation-driven/>
beans>

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

6. 小结:

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

二、SpringMVC Project 执行流程

1. 项目目录结构
SpringMVC框架 -- 入门案例_第1张图片

2. 项目执行过程时序图

SpringMVC框架 -- 入门案例_第2张图片

3. 执行流程

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

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

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

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


三、SpringMVC中常用注解

  • SpringMVC框架 – 请求参数的获取方式

  • 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()");
    }
}

第三步:配置拦截器


<context:component-scan base-package="com.zz" />


<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/pages/"/>
    <property name="suffix" value=".jsp" />
bean>


<mvc:annotation-driven />


<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,测试结果如下
SpringMVC框架 -- 入门案例_第3张图片

5. 自定义拦截器的执行流程图
SpringMVC框架 -- 入门案例_第4张图片

你可能感兴趣的:(SSM,SpringMVC,入门案例)