SpringMVC基础知识(1)

1、SpringMVC的介绍

  Spring Web MVC是构建在Servlet API上的原始Web框架,从一开始就包含在Spring Framework中。 正式名称 “Spring Web MVC,” 来自其源模块(spring-webmvc)的名称,但它通常被称为“Spring MVC”。

  SpringMVC是Spring框架的一部分,是基于java实现的一个轻量级web框架。

  学习SpringMVC框架最核心的就是DispatcherServlet的设计,掌握好DispatcherServlet是掌握SpringMVC的核心关键。

2、SpringMVC的优点

  1)清晰的角色划分:控制器(controller)、验证器(validator)、命令对象(command obect)、表单对象(form object)、模型对象(model object)、Servlet分发器(DispatcherServlet)、

    处理器映射(handler mapping)、试图解析器(view resoler)等等。每一个角色都可以由一个专门的对象来实现。

  2)强大而直接的配置方式:将框架类和应用程序类都能作为JavaBean配置,支持跨多个context的引用,例如,在web控制器中对业务对象和验证器validator的引用。

  3)可适配、非侵入:可以根据不同的应用场景,选择合适的控制器子类(simple型、command型、from型、wizard型、multi-action型或者自定义),而不是一个单一控制器(比如Action/ActionForm)继承。

  4)可重用的业务代码:可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。

  5)可定制的绑定(binding)和验证(validation):比如将类型不匹配作为应用级的验证错误,这可以保证错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,

    需要手动解析它并转换到业务对象。

  6)可定制的handler mapping和view resolution:Spring提供从最简单的URL映射,到复杂的、专用的定制策略。与某些web MVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。

  7)灵活的model转换:在Springweb框架中,使用基于Map的键/值对来达到轻易的与各种视图技术集成。

  8)可定制的本地化和主题(theme)解析:支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等等。

  9)简单而强大的JSP标签库(Spring Tag Library):支持包括诸如数据绑定和主题(theme)之类的许多功能。他提供在标记方面的最大灵活性。

  10)JSP表单标签库:在Spring2.0中引入的表单标签库,使用在JSP编写表单更加容易。

  11)Spring Bean的生命周期:可以被限制在当前的HTTP Request或者HTTP Session。准确的说,这并非Spring MVC框架本身特性,而应归属于Spring MVC使用的WebApplicationContext容器。

3、SpringMVC的实现原理

  SpringMVC的MVC模式:

  

  SpringMVC的具体执行流程:

  当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,

  访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。

  

  1、DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
  2、HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
  3、返回处理器执行链,根据url查找控制器,并且将解析后的信息传递给DispatcherServlet
  4、HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  5、执行handler找到具体的处理器
  6、Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
  7、HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  8、DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  9、视图解析器将解析的逻辑视图名传给DispatcherServlet。
  10、DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图,进行试图渲染
  11、将响应数据返回给客户端

4、基于XML的Hello_SpringMVC

  1)添加pom依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>

  2)编写web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

      <!--
        关联springmvc的配置文件
        此配置文件的属性可以不添加,但是需要在WEB-INF的目录下创建 前端控制器名称-servlet.xml文件
      -->

        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
    </servlet>

    <!--匹配servlet的请求,
      /:标识匹配所有请求,但是不会jsp页面
      /*:拦截所有请求,拦截jsp页面

    但是需要注意的是,当配置成index.html的时候,会发现请求不到
    原因在于,tomcat下也有一个web.xml文件,所有的项目下web.xml文件都需要继承此web.xml
    在服务器的web.xml文件中有一个DefaultServlet用来处理静态资源,但是url-pattern是/
    而我们在自己的配置文件中如果添加了url-pattern=/会覆盖父类中的url-pattern,此时在请求的时候
    DispatcherServlet会去controller中做匹配,找不到则直接报404
    而在服务器的web.xml文件中包含了一个JspServlet的处理,所以不过拦截jsp请求
    -->

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--/*和/都是拦截所有请求,/会拦截的请求不包含*.jsp,而/*的范围更大,还会拦截*.jsp这些请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

  3)编写springmvc需要的spring配置文件,applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--处理映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <!--处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!--视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!--配置后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <bean id="/hello" class="com.llxazy.controller.HelloController"></bean>
</beans>

  4)HelloController.java

package com.llxazy.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

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

public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //创建模型和视图对象
        ModelAndView mv = new ModelAndView();
        //将需要的值传递到model中
        mv.addObject("msg","helloSpringMVC");
        //设置要跳转的视图,
        mv.setViewName("hello");
        return mv;
    }
}

  5)创建hello.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  ${msg}
</body>
</html>

  6)配置tomcat,发送请求

             http://localhost:8080/hello

5、基于注解的Hello_SpringMVC

  1)添加pom依赖

  2)编写web.xml文件

  3)编写applicationContext.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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--自动扫描包,由IOC容器进行控制管理-->
    <context:component-scan base-package="com.llxazy"></context:component-scan>
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

  4)编写HelloController.java

package com.llxazy.controller;

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

@Controller
public class HelloController{
    /*
    * @RequestMapping就是用来标识此方法用来处理什么请求,其中的/可以取消
    * 取消后默认也是从当前项目的根目录开始查找,一般在编写的时候看个人习惯
    * 同时,@RequestMapping也可以用来加在类上,
    * */
    @RequestMapping("/hello")
    public String hello(Model model){
        model.addAttribute("msg","hello,SpringMVC");
        return "hello";
    }
}

  5)编写hello.jsp

  6)配置tomcat,发送请求

             http://localhost:8080/hello

6、springmvc_helloworld运行流程: 

  1)客户端发送请求http://localhost:8080/hello

  2)由tomcat接受到对应的请求

  3)SpringMVC的前端控制器DispatcherServlet接收到所有的请求

  4)查看请求地址和@RequestMapping注解的哪个匹配,来找到具体的类的处理方法

  5)前端控制器找到目标处理类和方法之后,执行目标方法

  6)方法执行完成之后会有一个返回值,SpringMVC会将这个返回值用视图解析器进行解析拼接成完整的页面地址

  7)DispatcherServlet拿到页面地址之后,转发到具体的页面

7、@RequestMapping

  @RequestMapping用来匹配客户端发送的请求,可以在方法上使用,也可以在类上使用。

  方法:表示用来匹配要处理的请求

  类上:表示为当前类的所有方法的请求地址添加一个前置路径,访问的时候必须要添加此路径

  在整个项目的不同方法上不能包含相同的@RequestMapping值

  @RequestMapping注解还可以添加很多额外的属性值,用来精确匹配请求

  @RequestMapping还包含了很多复杂的匹配功能,提供了通配符的支持

package com.llxazy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/llxazy")
public class HelloController{

    /*
    * @RequestMapping就是用来标识此方法用来处理什么请求,其中的/可以取消
    * 取消后默认也是从当前项目的根目录开始查找,一般在编写的时候看个人习惯
    * 同时,@RequestMapping也可以用来加在类上,
    * */
    @RequestMapping("/hello")
    public String hello(Model model){
        model.addAttribute("msg","hello,SpringMVC");
        return "hello";
    }

    /**
     * Request的其他属性值
     *  value:要匹配的请求
     *  method:限制发送请求的方式: POST GET
     *  params:表示请求要接受的参数,如果定义了这个属性,那么发送的时候必须要添加参数
     *         params有几种匹配规则
     *          1、直接写参数的名称,param1,param2
     *              params = {"username"}
     *          2、表示请求不能包含的参数,!param1
     *              params = {"!username"}
     *          3、表示请求中需要要包含的参数但是可以限制值 param1=values  param1!=value
     *              params = {"username=123","age"}
     *              params = {"username!=123","age"}
     *  headers:填写请求头信息
     *          chrome:User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
     *          firefox:User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0
     *
     *  consumers:只接受内容类型是哪种的请求,相当于指定Content-Type
     *  produces:返回的内容类型 Content-Type:text/html;charset=utf-8
     *
     * @return
     */
    @RequestMapping(value = "/hello2",method = RequestMethod.POST)
    public String hello2(){
        return "hello";
    }

    @RequestMapping(value = "/hello3",params = {"username!=123","age"})
    public String hello3(String username){
        System.out.println(username);
        return "hello";
    }

    @RequestMapping(value = "/hello4",headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0"})
    public String hello4(){
        return "hello";
    }

    /**
     * @Request包含三种模糊匹配的方式,分别是:
     *  ?:能替代任意一个字符
     *  *: 能替代任意多个字符和一层路径
     *  **:能代替多层路径
     * @return
     */
    @RequestMapping(value = "/**/h*llo?")
    public String hello5(){
        System.out.println("hello5");
        return "hello";
    }
}

8、@PathVariable

  @PathVariable注解,此注解就是提供了对占位符URL的支持,就是将URL中占位符参数绑定到控制器处理方法的参数中。

package com.llxazy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/llxazy")
public class HelloController{

    @RequestMapping(value = "/pathVariable/{name}")
    public String pathVariable(@PathVariable("name") String name){
        System.out.println(name);
        return "hello";
    }
}

 

 

posted @ 2021-07-08 15:08  禾野牧村  阅读(80)  评论(0)    收藏  举报