SpringMVC第一讲

SpringMVC笔记
课前事项
[了解]今日课程内容
SpringMVC框架,帮我们写Controller(接收请求),及跳转页面的。(web表现层框架)
SpringMVC框架进行介绍【了解】
什么是SpringMVC?
SpringMVC作用于哪一层?
SpringMVC有什么优势
SpringMVC的入门案例【掌握】
SpringMVC的架构【了解】
SpringMVC的请求参数绑定【掌握】
简单参数绑定
pojo参数绑定
pojo包装对象绑定
集合参数的绑定
[了解]MVC模式
M即Model数据模型,V即View视图,C即Controller控制器。
Model的广义和狭义之说
广义:Model = Service层 +Dao层,由这两层来产生数据模型
狭义:Model就是数据模型本身,就是Controller和View之间传递的数据,在这种说法下,MVC又可归为Web层。
经典三层:web表现层(view+controller)、service业务层、dao持久层
[了解]SpringMVC概述
SpringMVC是什么
SpringMVC是什么
SpringMVC是一个轻量级的Web表现层框架,作用:用来写Controller接收请求跳转页面的,它是Spring框架的一部分。
说白了,用来替代servlet的。SpringMVC是对Servlet的封装和增强,简化了servlet的操作。它已经超越了Struts,成为目前最优秀的表现层框架。
原始Servlet中
第一步:取参
request.getParameter(“param”)
第二步:数据类型转换
Integer.valueOf()
http协议:超文本传输协议

在SpringMVC中,因为它是对servlet的封装,所以可以很方便的拿到整型数据

什么时候使用SpringMVC?
你觉得servlet繁琐的时候
在哪儿使用SpringMVC?
在经典三层的web表现层使用SpringMVC框架
SpringMVC的优势
操作特简单,性能特别高,灵活性特别强
与Struts框架相比
解决了struts的安全性低,操作难,执行性能低的问题
拓展认识
Spring + Spring jdbctemplate + SpringMVC --> Spring全家桶 1.0 主流
Spring cloud + Spring Boot + Spring Data JPA + SpringMVC --> Spring全家桶2.0 潮流
Spring Cloud(微服务框架,单体工程拆分成很多个小(微)工程,订单服务、用户服务等)
dubbo(阿里巴巴微服务框架、hsf框架)
[理解]SpringMVC的处理流程
原始Servlet方式
一个项目中有很多个servlet,每个servlet负责不同的业务或者功能,前台请求各个servlet。
好比自己去找水电工、木工等。

SpringMVC全局只有一个servlet,这个servlet就好比装修队的头儿

SpringMVC的入门案例
入门案例需求
浏览器输入url发起请求,该url请求被SpringMVC框架拦截处理,把后台服务器的当前时间输出到jsp页面显示
入门案例实现分析
jsp页面(显示当前系统时间)
前端控制器dispatcherServlet在web.xml中配置
写Handler获取当前系统时间(这里的Handler就是Controller)
@Controller标识处理类,并配置扫描
入门案例步骤
使用骨架创建web应用,配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

com.itheima.springmvc
hm328_springmvc01_main
1.0-SNAPSHOT
war

hm328_springmvc01_main Maven Webapp

http://www.example.com

junit junit 4.12 test
  <!--引入spring框架-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>

  <!--引入springmvc模块-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>

  <!--引入web开发所需要的两个jar,往往一起引入即可,start-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.0</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>3.0</version>
    <!--使用范围provide,只在开发、编译阶段有效,打包之后是由服务器环境提供-->
  <scope>provided</scope>
</dependency>
  <!--引入web开发所需要的两个jar,往往一起引入即可,end-->
hm328_springmvc01_main maven-clean-plugin 3.0.0 maven-resources-plugin 3.0.2 maven-compiler-plugin 3.7.0 maven-surefire-plugin 2.20.1 maven-war-plugin 3.2.0 maven-install-plugin 2.5.2 maven-deploy-plugin 2.8.2

result.jsp页面开发
<%@ page isELIgnored=“false” contentType=“text/html;charset=UTF-8” language=“java” %>

测试结果页 当前系统时间:${nowDate} springmvc配置文件配置 <?xml version="1.0" encoding="UTF-8"?>
<!--自动注册最优最合适的处理器适配器和处理器映射器-->
<mvc:annotation-driven/>

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

入门案例执行过程
tomcat启动加载读取web.xml
进一步读取到web.xml中配置的前端控制器DispatcherServlet
DispatcherServlet会读取到springmvc.xml,进一步去实例化DefaultController对象
当url请求到来时,首先被DispatcherServlet前端控制器拦截,然后前端控制器去找能够处理当前url的处理器Handler(根据@RequestMapping的配置)
jsp页面从request域当中获取到变量,进行显示

[理解]SpringMVC架构
框架结构

架构流程
第一步:用户发送请求至前端控制器DispatcherServlet
第二步:DispatcherServlet收到请求调用HandlerMapping处理器映射器
第三步:处理器映射器根据请求Url找到具体的Handler(后端控制器),生成处理器对象及处理器拦截器(如果有则生成)一并返回DispatcherServlet
第四步:DispatcherServlet调用HandlerAdapter处理器适配器去调用Handler
第五步:处理器适配器执行Handler
第六步:Handler执行完成给处理器适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View
第八步:前端控制器请求视图解析器去进行视图解析
    根据逻辑视图名来解析真正的视图。
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染
    就是将模型数据(在 ModelAndView 对象中)填充到 request 域
第十一步:前端控制器向用户响应结果
组件说明
DispatcherServlet:前端控制器
接收用户请求,响应结果,相当于*处理器,DispatcherServlet是整个流程控制的中心,由它调用其它组件完成用户请求的处理。DispatcherServlet的存在降低了组件之间的耦合性。
HandlerMapping:处理器映射器
理解为一个Map<url,Hanlder>
HandlerMapping负责根据用户请求的Url找到Handler即处理器,SpringMVC提供了不同的映射器来实现不同的映射方式,例如:实现接口方式,注解方式等。
Handler:处理器
在SpringMVC当中有两层意思:Controller或者Controller当中的方法
Handler相对于前端控制器DispatcherServlet来说是后端控制器,执行具体业务处理的,它在DispatcherServlet的控制下处理用户的具体请求。
HandlAdapter:处理器适配器
不同的接口类型转换成usb,体现了万物归一的思想
通过HandlerAdapter对Handler处理器进行执行,这是适配器模式的应用。

ViewResolver:视图解析器
ViewResolver进行视图解析,首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象。

View:视图
SpringMVC框架提供了很多的View视图类型的支持,包括:jsp、freemarkerView等。我们最常用的视图就是jsp
注意:在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。
需要我们开发的组件有handler(后台的处理逻辑)、view(前端的显示页面)
配置mvc:annotation-driven
SpringMVC对于三大件默认在底层已经进行了注册和使用(三大件已经存在于SpringMVC的运行机制中),默认使用的三大件已经过时了(虽然过时,但是依然能够保证程序运行的),建议我们使用更好更合适的三大件,只需要在SpringMVC的配置文件中添加一个标签mvc:annotation-driven,配置完成后会自动注册最合适的三大件
[掌握]RequestMapping使用
多个URL路径映射到同一个Handler(同一个方法)

添加到类上面(分类管理,限定类中方法访问的前缀),一看到url,就知道这个url所处理的业务领域

属性限定请求方法,请求的url相同,请求方式(get/post)不同进入不同方法处理
访问的url是一样的(Handler名字是一样的),但是我根据你不同的请求方式(get/post)进入不同的方法处理
请求的url一样,但是请求方式不一样(get/post)
/*

  • 用例:url相同,根据请求方式(get/post)不同进入不同方法处理
  • */
    @RequestMapping(value = “gotoResultSameUrl”,method = {RequestMethod.GET})
    public ModelAndView gotoResultSameUrlGet(ModelAndView modelAndView) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”,date + “—>>>gotoResultSameUrlGet”);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

/*

  • 用例:url相同,根据请求方式(get/post)不同进入不同方法处理
  • */
    @RequestMapping(value = “gotoResultSameUrl”,method = {RequestMethod.POST})
    public ModelAndView gotoResultSameUrlPost(ModelAndView modelAndView) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”,date + “—>>>gotoResultSameUrlPost”);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

属性限定请求参数,支持简单的表达式语法
url一样,根据携带参数的不同进入不同的方法处理
url相同,请求方式相同,请求参数不同进入不同hanlder方法处理
param1:表示请求必须包含名为 param1 的请求参数
!param1:表示请求不能包含名为 param1 的请求参数
param1 != value1:表示请求包含名为 param1 的请求参数,但其值不能为 value1
{“param1=value1”, “param2”}:请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
[掌握]请求参数绑定(接收)
默认支持Servlet API作为方法参数

绑定简单类型参数
参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整型:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0

绑定简单数据类型参数,只需要直接形参声明
注意:形参的参数名和传递的参数名保持一致
建议使用包装类型
参数绑定两步骤:1、从request中getParameter;2、根据形参定义的参数类型进行类型转换和赋值
@RequestParam使用
当形参和传递的参数名称不一致时使用RequestParam进行手动映射,类似于Mybatis当中国的resultMap的作用
/**

  • @RequestParam:从请求中把某一个参数取出赋值给当前形参
  • value属性:指定从请求中获取哪个参数赋值给当前形参
  • defaultValue:默认值,如果获取的参数值为空,则取该默认值(场景:分页的第一页)
  • @param modelAndView
  • @param id
  • @return
    */
    @RequestMapping(value = “sendSimpleParams2”)
    public ModelAndView sendSimpleParams2(ModelAndView modelAndView,@RequestParam(value = “ids”,defaultValue = “3”) Integer id) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”, date + " id==>>" + id);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

绑定pojo类型参数
直接形参声明pojo即可接收
要求:传递的参数名必须和pojo属性名对应
/**

  • 绑定pojo类型参数,只需要直接在形参中声明pojo即可
  • 要求:请求参数名和pojo属性名保持一致
  • @param modelAndView
  • @param user
  • @return
    */
    @RequestMapping(“sendPojo”)
    public ModelAndView sendPojo(ModelAndView modelAndView,User user) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”, date + " user==>>" + user);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

重点在于传参参数的命名(和pojo属性名保持一致)
绑定pojo包装对象参数
重点在于传参参数的命名
pojo包装对象首先就是一个普通的pojo,就应该按照上面绑定pojo的要求来,然后进一步处理
传参时参数名,首先应该定位到包装对象的属性名,如果不能确定数据,通过属性.的方式进一步锁定即可
前台传参

传递(绑定)pojo包装类型参数

测试

后台接收
/**

  • 绑定pojo包装类型参数,只需要直接在形参中声明pojo包装对象即可
  • 注意:绑定pojo包装类型参数,重点在于前台参数参数名的取法,首先定位到pojo的属性,然后通过.的方式进一步确定
  • @param modelAndView
  • @return
    */
    @RequestMapping(“sendPojoPackage”)
    public ModelAndView sendPojoPackage(ModelAndView modelAndView, QueryVo queryVo) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”, date + " queryVo==>>" + queryVo);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

绑定pojo包含集合类型参数
传递绑定集合类型(List/Map),作为POJO的一个属性来传递
前端页面

测试用例USE_CASE10:SpringMVC接收集合(List)类型参数

    </table>
    <input type="submit" value="批量修改提交">
</form>
主键 用户名 性别

测试用例USE_CASE11:SpringMVC接收集合(Map)类型参数

    </table>
    <input type="submit" value="批量修改提交">
</form>
主键 用户名 性别

pojo

后端handler
/**

  • 用例:springmvc绑定list集合
  • 重点在于前端参数的取值方式
  • @param modelAndView
  • @return
    */
    @RequestMapping(“sendList”)
    public ModelAndView sendList(QueryVo queryVo, ModelAndView modelAndView) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”,date + “—>>>queryVo:” + queryVo);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

/**

  • 用例:springmvc绑定map集合
  • 重点在于前端参数的取值方式
  • @param modelAndView
  • @return
    */
    @RequestMapping(“sendMap”)
    public ModelAndView sendMap(QueryVo queryVo, ModelAndView modelAndView) {
    Date date = new Date();
    modelAndView.addObject(“nowDate”,date + “—>>>queryVo:” + queryVo);
    modelAndView.setViewName(“result”);
    return modelAndView;
    }

自定义类型转换器
自定义类型转换器
package com.itheima.springmvc.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**

  • 自定义类型转换器实现改接口,Converter<S,T>
  • S:source,转换前的数据类型
  • T:target,转换后的数据类型
    */
    public class DateConverter implements Converter<String,Date> {
    @Override
    public Date convert(String source) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
    try {
    return simpleDateFormat.parse(source);
    } catch (ParseException e) {
    e.printStackTrace();
    }
    return null;
    }
    }

注册自定义类型转换器

[了解]消息头相关的两个注解
@RequestHeader

@CookieValue

作业
笔记过一遍
练习要求“掌握”的部分
附录
附录一:乱码问题处理
Post请求乱码,web.xml中加入过滤器

encoding org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding true encoding /* Get请求乱码 Get请求乱码需要修改tomcat下server.xml的配置
上一篇:SpringMVC初学笔记


下一篇:jsp使用EL表达式取不到后端ModelAndView传来的Object值