SpringMVC介绍及入门

  • Post author:
  • Post category:其他


一、SpringMVC简介

1、什么是MVC

MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分

M:Model,模型层,指工程中的JavaBean,作用是处理数据

JavaBean分为两类:

  • 一类称为实体类Bean:专门存储业务数据的,如 Student、User 等

  • 一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理业务逻辑和数据访问。

V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据

C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器

MVC的工作流程:用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器

2、什么是SpringMVC

SpringMVC是Spring的一个后续产品,是Spring的一个子项目

SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的

首选方案

注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet

3、SpringMVC的特点


  • Spring 家族原生产品

    ,与 IOC 容器等基础设施无缝对接


  • 基于原生的Servlet

    ,通过了功能强大的

    前端控制器DispatcherServlet

    ,对请求和响应进行统一处理

  • 表述层各细分领域需要解决的问题

    全方位覆盖

    ,提供

    全面解决方案


  • 代码清新简洁

    ,大幅度提升开发效率

  • 内部组件化程度高,可插拔式组件

    即插即用

    ,想要什么功能配置相应组件即可


  • 性能卓著

    ,尤其适合现代大型、超大型互联网项目要求

4、 SpringMVC工作流程


第一步:

发起请求到前端控制器(DispatcherServlet)


第二步:

前端控制器请求HandlerMapping查找 Handler可以根据xml配置、注解进行查找,生成处理对象及处理器拦截器(如果有则生成)一并返回前端控制器


第三步:

处理器映射器HandlerMapping向前端控制器返回Handler(抽象)


第四步:

前端控制器调用处理器适配器去执行Handler


第五步:

处理器适配器根据Handler规则执行不同类型的Handler(处理器(Controller),后端控制器)


第六步:

Handler执行完成给适配器返回ModelAndView(模型视图)

ModelAndView是springmvc框架的一个底层对象

Model:即将被渲染的数据 包含了要在页面中展示的数据

View:跳转的页面(只包含页面名称:逻辑视图名) 例:index


第七步:

处理器适配器向前端控制器返回ModelAndView


第八步:

前端控制器请求视图解析器(ViewResolver)去进行视图解析(DispatcherServlet将ModelAndView传递给ViewResolver)

根据逻辑视图名解析成真正的视图(jsp)

在视图解析器中(拼接出完整的请求地址 例:jsp/book/index.jsp)


第九步:

视图解析器向前端控制器返回具体View


第十步:

前端控制器根据View进行视图渲染(即将模型数据填充至视图中)

视图渲染将模型数据(在ModelAndView对象中)填充到request域


第十一步:

前端控制器向用户响应结果

二、SpringMVC环境搭建

1、导入SpringMVC与JSTL相关依赖

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>5.0.2.RELEASE</version>
 </dependency>
    
<!-- ********************** JSTL依赖 ********************** -->
<!-- 缺少下面的这两个jar包会报java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config-->
<!-- 原因:org.springframework.web.servlet.view.JstlView在视图解析时需要这二个jar包-->
<dependency>
     <groupId>jstl</groupId>
     <artifactId>jstl</artifactId>
     <version>1.2</version>
</dependency>
<dependency>
     <groupId>taglibs</groupId>
     <artifactId>standard</artifactId>
     <version>1.1.2</version>
</dependency>

2、配置核心控制器DispathcerServlet(web.xml)

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
  <display-name>Archetype Created Web Application</display-name>

  <!--实现spring与web集成,实现spring上下文的初始化工作-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>

  <!-- 读取Spring上下文的监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 防止Spring内存溢出监听器 -->
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>

  <!--中文乱码过滤器-->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--配置springMVC核心控制器(DispatcherServlet)-->
  <!-- Spring MVC servlet -->
  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--此参数可以不配置,默认值为:/WEB-INF/springmvc-servlet.xml-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <!--web.xml 3.0的新特性,是否支持异步-->
    <async-supported>true</async-supported>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3、配置SpringMVC核心文件 spring-mvc.xml(WEB-INF目录下)

注:在配置扫描时,只需要扫描Controller层,不需要扫描其他

<?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.zking.ssm">
        <!--只扫描controller-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!--注册HandlerMapping(处理器映射器)和handlerAdapter(处理器适配器)-->
    <!-- 2) 此标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter  -->
    <!-- 两个bean,这两个bean是spring MVC为@Controllers分发请求所必须的。并提供了数据绑定支持, -->
    <!-- @NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson) -->
    <mvc:annotation-driven/>

    <!--配置视图解析器(ViewResolver)-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--  viewClass需要在pom中引入两个包:standard.jar and jstl.jar  -->
        <!--
        ModelAndView:View部分只包含了页面名字(逻辑视图名)
        例如:index.jsp 》》》 index

        -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--配置静态资源访问,例如:js/css/images-->
    <!-- 4) 单独处理图片、样式、js等资源  -->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/images/" mapping="/images1/**"/>
    <mvc:resources location="WEB-INF/images/" mapping="/images2/**"/>

    <!--但是,从spring3.1开始DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter的使用已经过时-->
    <!--spring3.1开始我们应该用RequestMappingHandlerMapping来替换DefaultAnnotationHandlerMapping,-->
    <!--spring3.1开始我们应该用用RequestMappingHandlerAdapter来替换AnnotationMethodHandlerAdapter-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJackson2HttpMessageConverter"/>
            </list>
        </property>
    </bean>
    <bean id="mappingJackson2HttpMessageConverter"
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <!--处理中文乱码以及避免IE执行AJAX时,返回JSON出现下载文件-->
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>text/json;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

    <!--配置文件上传解析器(CommonsMultipartResolver)-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 文件最大大小(字节) 1024*1024*50=50M-->
        <property name="maxUploadSize" value="52428800"></property>
        <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
        <property name="resolveLazily" value="true"/>
    </bean>
</beans>

4、创建Controller类和视图页面

package com.zking.ssm.book.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
public class IndexController {
 
    public String toIndex(){
        return  "";
    }
 
}

5、使用注解配置Controller类中业务方法的映射地址

package com.zking.ssm.book.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class IndexController {
 
    @RequestMapping("/")
    public String toIndex(){
        //视图解析器=前缀+逻辑视图名+后缀
        //前缀 /WEB-INF/jsp
        //逻辑视图名 index
        //后缀 .jsp
        return  "index";//逻辑视图名
    }
 
}

6、客户端发起请求测试

三、SpringMVC组件

  • DispatcherServlet:

    前端控制器

    ,不需要工程师开发,由框架提供

作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求

  • HandlerMapping:

    处理器映射器

    ,不需要工程师开发,由框架提供

作用:根据请求的url、method等信息查找Handler,即控制器方法

  • Handler:

    处理器

    ,需要工程师开发

作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理

  • HandlerAdapter:

    处理器适配器

    ,不需要工程师开发,由框架提供

作用:通过HandlerAdapter对处理器(控制器方法)进行执行

  • ViewResolver:

    视图解析器

    ,不需要工程师开发,由框架提供

作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、RedirectView

  • View:

    视图

作用:将模型数据通过页面展示给用户

四、@RequestMapping注解

1、@RequestMapping注解的功能

从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

2、@RequestMapping注解的位置

@RequestMapping标识一个类:设置映射请求的请求路径的初始信息,窄化路径

@RequestMapping标识一个方法:设置映射请求请求路径的具体信息

@Controller
@RequestMapping("/test")
public class RequestMappingController {
​
    //此时请求映射所映射的请求的请求路径为:/test/testRequestMapping
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        return "success";
    }
​
}

3、@RequestMapping注解的value属性

@RequestMapping注解的value属性通过请求的请求地址匹配请求映射

@RequestMapping注解的value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求

@RequestMapping注解的value属性必须设置,至少通过请求地址匹配请求映射

@RequestMapping(value = "/toAddBook")
    public String toAddBook(){
        return "book/AddBook";
}

注:value单独使用可以省略不写,与其他属性一起使用必须指明

4、@RequestMapping注解的method属性

@RequestMapping注解的method属性通过请求的请求方式(get或post)匹配请求映射

@RequestMapping注解的method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求

若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错405:Request method ‘POST’ not supported

@RequestMapping(value = "/toAddBook",method = {RequestMethod.POST,RequestMethod.GET})
    public String toAddBook(){
        return "book/AddBook";
    }

注:

1、对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

处理get请求的映射–>@GetMapping

处理post请求的映射–>@PostMapping

处理put请求的映射–>@PutMapping

处理delete请求的映射–>@DeleteMapping

2、常用的请求方式有get,post,put,delete

但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理

若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到

5、@RequestMapping注解的params属性(了解)

@RequestMapping注解的params属性通过请求的请求参数匹配请求映射

@RequestMapping注解的params属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系

“param”:要求请求映射所匹配的请求必须携带param请求参数

“!param”:要求请求映射所匹配的请求必须不能携带param请求参数

“param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value

“param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value

@RequestMapping(
         value="/test"
        ,method = {RequestMethod.GET, RequestMethod.POST}
        ,params = {"username","password!=123456"}
)
public String testRequestMapping(){
    return "success";
}

注:

若当前请求满足@RequestMapping注解的value和method属性,但是不满足params属性,此时页面回报错400:Parameter conditions “username, password!=123456” not met for actual request parameters: username={admin}, password={123456}

6、@RequestMapping注解的headers属性(了解)

@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射

@RequestMapping注解的headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系

“header”:要求请求映射所匹配的请求必须携带header请求头信息

“!header”:要求请求映射所匹配的请求必须不能携带header请求头信息

“header=value”:要求请求映射所匹配的请求必须携带header请求头信息且header=value

“header!=value”:要求请求映射所匹配的请求必须携带header请求头信息且header!=value

若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到

7、SpringMVC支持ant风格的路径

?:表示任意的单个字符

*:表示任意的0个或多个字符

**:表示任意的一层或多层目录

注意:在使用**时,只能使用/**/xxx的方式

8、SpringMVC支持路径中的占位符

原始方式:/deleteUser?id=1

rest方式:/deleteUser/1

SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参

//访问地址:http://localhost:8080/ssm/testRest/1/admin

@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id, @PathVariable("username") String username){
    System.out.println("id:"+id+",username:"+username);
    return "success";
}
//最终输出的内容为-->id:1,username:admin

五、SpringMVC的

参数传递

1)String和八大基础类型直接在方法上加参数,访问时路径上的参数名要与方法的参数名相同

//直接传递String或者八大基础类型
    @RequestMapping("/getBookName")
    public String toAddBook(String bookName){
        System.out.println("bookName:"+bookName);
        return "book/AddBook";
    }

2) 传递对象类型的参数 在路径上写对象中的属性名及对应的属性值

传递json数据需要导入相关依赖

<!--jackson-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson.version}</version>
    </dependency>
//传递对象
    @RequestMapping("/getBook")
    @ResponseBody//不跳页面(不经过视图解析器),返回json数据
    public Book toAddBook(Book book){
        System.out.println("book:"+book);
        return book;
    }

3)传递 HttpServletRequest HttpServletResponse HttpSession

//传参 request/respect/session
    @RequestMapping("/getBookName3")
    public String toAddBook3(HttpServletRequest req, HttpServletResponse resp, HttpSession session){
        System.out.println("req:"+req.getRequestURI());
        System.out.println("session:"+session.getId());
        return "book/AddBook";
    }

4)传递集合类型的参数

使用

@RequestParam

接受

map

类型的参数

    //传参 Map集合
    //@RequestParam 接收map类型的参数
    @RequestMapping("/getBookName4")
    public String toAddBook4(@RequestParam Map<String,Object> map){
        System.out.println("map:"+map);
        return "book/AddBook";
    }

使用

@RequestBody

传递

list

或者

Map

类型的的参数,但是参数的格式必须是json

 @RequestMapping("/getBookName5")
    //@RequestBody:传递List/Map类型的参数
    public String toAddBook5(@RequestBody List<Map<String,Object>> list){
        System.out.println("list:"+list);
        return "book/AddBook";
    }





版权声明:本文为weixin_57504000原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。