SpringMVC
学习目标:
1.掌握基于SpringMVC获取请求参数与响应json数据操作
2.熟练应用基于REST风格的请求路径设置与参数传递
3.能够根据实际业务建立前后端开发通信协议并进行实现
4.基于SSM整合技术开发任意业务模块功能
1.SpringMVC简介
1.1SpringMVC概述
SpringMVC技术与Servlet技术功能相同,均属于web层开发技术,但SpringMVC技术更简洁,能用更少的代码进行开发
- 定义:SpringMVC是一种基于Java实现MVC模型的轻量级==Web框架==
- 优点:
- 使用简单,开发便捷(相比于Servlet)
- 灵活性强
1.2SpringMVC入门案例
1.2.1Servlet开发步骤:
1.创建web工程(Maven结构)
2.设置tomcat服务器,加载web工程(tomcat插件)
3.导入坐标(Servlet)
4.定义处理请求的功能类(UserServlet)
5.设置请求映射(配置映射关系)
1.2.2步骤:
①使用SpringMVC技术需要县导入SpringMVC坐标与Servlet坐标
<!--1.导入坐标springmvc和servlet的-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
②创建SpringMVC控制器类(等同于Servlet功能)。一般来说@Component是用来定义Bean,在SpringMVC中开发表现层的Bean要使用@Controller注解
@Controller
public class UserController{
@RequestMapping("/save")//访问路径
@ResponseBody
public String save(){//返回Json数据用String
System.out.println("user save ...");
return "{'module':'springmvc'}";
}
}
③初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean
@Configuration
@ComponentScan("com.iteima.controller")
public class SpringMvcConfig{
}
④初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理请求
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
//4.定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SpringMvcConfig.class);
return context;
}
//设置哪些请求归属springMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
1.2.3入门案例用到的注解
- 名称:@Controller
- 类型:类注解
- 位置:SpringMVC控制器定义上方
- 作用:设置SpringMVC的核心控制器bean
- 范例:
@Controller
public class UserController{
}
- 名称:@ResquestMapping
- 类型:方法注释
- 位置:SpringMVC控制器方法定义上方
- 作用:设置当前控制器方法请求访问路径
- 相关属性
- value(默认):请求访问路径
- 范例:
@ResquestMapping("/save")
public void save(){
System.out.println("user save ...");
}
- 名称:@ResponseBody
- 类型:方法注释
- 位置:SpringMVC控制器方法定义上方
- 作用:设置当前控制器方法响应内容为当前返回值,无需解析
- 范例:
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':"springmvc"}";
}
1.2.4SpringMVC入门程序开发总结(1+N)
- 一次性工作
- 创建工程,设置服务器,加载工程
- 导入坐标
- 创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
- SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
- 多次工作
- 定义处理请求的控制器类
- 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)
1.2.5Servlet容器配置类
AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化web3.0容器的抽象类
AbstractDispatcherServletInitializer提供三个接口方法供用户实现
createServletAppilcationContext(),创建servlet容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象中,而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围
protected WebApplicationContext createServletApplicationContext(){
AnnotattionConfigWebApplicationContext context = new AnnotattionConfigWebAppklicationtContext();
context.register(SpringMvcConfig.class);
return context;
}
getServletMappings(),设定SpringMVC对应的请求映射路径,设置为/表示拦截所有请求,任意请求都将转入道SpringMVC进行处
理
protected String[] getServletMapping(){
return new String[]("/");
}
createRootApplicationContext(),如果创建Servlet容器时需要加载飞SpringMVC对应的bean,使用当前方法进行,使用方式用createServletAppilcationContext()
protected WebApplicationContext createRootApplicationContext(){
return null;
}
1.2.6入门案例工作流程分析
- 启动服务器初始化过程
- 服务器启动,执行ServletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建了WebApplicationContext对象
- 加载SpringMvcConfig
- 执行@ComponentScan加载对应的bean
- 加载UserController,每过@RequestMapping的名称对应一个具体的方法
- 执行getServletMappings方法,定义所有请求都通过SpringMVC
- 单次请求过程
- 发射请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交割SpringMVC处理
- 解析请求路径/save
- 由/save匹配执行对应的方法save()
- 执行save()
- 检测道由@ResponseBody之际将save()方法的返回值作为响应体返回给请求方
1.3Bean加载控制
1.3.1问题分析
项目目录结构:
- config目录存入的是配置类,写过的配置类有:
- ServletContainersInitConfig SpringConfig
- SpringMVCConfig
- JdbcConfig
- MybatisConfig
- controller目录存放的是SpringMVC的controller类
- service目录存放的是service接口和实现类
- dao目录存放的是dao/Mapper接口
1.3.2问题引出
controller、service和dao这些类都需要被容器管理的bean对象,其中controller中的bean是让SpringMVC加载的,那怎么能让Spring不加载呢?
解决方法:Controller加载控制与业务bean加载控制
- SpringMVC相关bean(表现层bean)
- Spring控制的bean
- 业务bean(Service)
- 功能bean(DatatSource等)
- SpringMVC相关bean加载控制
- SpringMVC加载的bean对应的包均在com.hcx.controller包内
- Spring相关bean加载控制
- 方式一:Spring加载的bean设定扫描范围为com.hcx,排除controller包内的bean
- 方式二:Spring加在的bean设定扫描范围为精准范围,例如service包,dao包等
注解:
名称:@ComponentScan
类型:类注解
范例:
@Configuration
@ConmponentScan(value="com.itheima",
excludeFilters = @ComponentScna.Filter(
type = FilterType.ANNOTATION,
classer = Controller.class
)
)
public class SpringConfig{}
属性:
excludeFilters: 排除扫描路径中加载的bean,需要指定类别(type)与具体项(classer)
includeFilters: 加载指定的bean,需要指定类别(type)与具体项(class)
Tomcat启动时bean的加载格式,Servlet容器配置类:
有了Spring的配置类,要想在tomcat服务器启动将其加载,修改ServletContainersInitConfig的createRootApplicationContext方法
//4.定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SpringMvcConfig.class);
return context;
}
//设置哪些请求归属springMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SpringConfig.class);
return context;
}
}
简化开发,Servlet容器配置类:
对于上述的配置方式,Spring还提供了一种更简单的配置方式,可以不用再去创建AnnotationConfigWebApplicationContext对象,不用手动register对应的配置类。
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
但是,这种方式无法看清容器对象是由谁创建的
2.PostMan简介
2.1PostMan简介
1.PostMan是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件(模拟HTTP请求发送的工具,实现快速发送请求,加快程序测试速度)
2.作用:常用于进行接口测试
3.特征:
简单、实用、美观、大方
2.2Postman下载
https://www.postman.com/downloads/
2.3Postman使用
1.创建WorkSpace
2.点击+号新建请求
3.选择请求方式,输入请求地址,并点击send发送请求
4.保存请求,方便后续使用
3.请求与响应
SpringMVC是web层的框架,主要的作用是接收请求、接收数据、响应结果,本节介绍与web技术具体相关的内容:
1.请求映射路径
2.请求参数
3.日期类型参数传递
4.响应json数据(异步数据)
3.1请求映射路径
思考:1.团队多人开发,每人设置不同的请求路径,冲突问题如何解决?
在如下代码中出现了BookController和UserController,都有一个/save路径的情况,产生了冲突
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String save(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
@Controller
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
在BookController和UserController,都有一个/save路径,启动Tomcat服务器,后台会报错:
这里UserController有一个save方法,BookController也有一个save方法,且访问路径都为http://localhost/save,这样在请求访问http://localhost/saved时,无法分清访问UserController还是BookController
解决方案:
设置模块名作为请求路径前缀
BookController中:
@Controller
public class BookController {
//请求路径映射
@RequestMapping("/book/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
UserController中:
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
public class UserController {
//请求路径映射
@RequestMapping("/user/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
//请求路径映射
@RequestMapping("/user/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
注:上述这种写法在每个方法上都要写上注解,产生大量重复工作,故可以将@RequestMapping(“/user”)写在方法对应的控制器的类上方,去掉功能留下模块名user,把@RequestMapping(“/user”)称为请求路径的前缀
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
//请求路径映射
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
//请求路径映射
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
总结:
请求映射路径
名称:@RequestMapping
类型:方法注解 类注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前方法请求访问路径前缀
范例:
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
}
属性:
value(默认):请求访问路径,或访问路径前缀
3.2请求方式
- Get请求
GET发送单个参数:
Get接收单个参数:
controller里方法形参名必须和请求参数名一致:
@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name){
System.out.println("普通参数传递 name ==> "+name);
return "{'module':'commonParam'}";
}
}
GET发送多个参数
Get接收多个参数:
@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name){
System.out.println("普通参数传递 name ==> "+name);
return "{'module':'commonParam'}";
}
}
- Post请求
Post请求的参数属于请求体类,在Postman中需要选择Body
普通参数:formbiaodanpost请求传参,表单参数名与形参变量名相同,定义形参即可接收参数
再选择x-www-form-urlencoded
最后添加key-value的值
Post接收参数与Get一样:
@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name){
System.out.println("普通参数传递 name ==> "+name);
return "{'module':'commonParam'}";
}
}
乱码处理
在servlet容器配置类中重写getServletFilters过滤器方法,为web容器添加过滤器并指定字符集,Spring-web包中提供了专用的字符过滤器
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
注:这种处理方法仅针对Post方式,而Get请求更为复杂
所有Tomcat版本Post请求都中文乱码
CharacterEncodingFilter是在spring-webmvc包中
3.3请求参数
3.3.1参数种类
①普通参数
②POJO类型参数
③嵌套POJO类型参数
④数组类型参数
⑤集合类型参数
3.3.2普通参数
url 地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
@RequestMapping("/commoParam")
@ResponseBody
public String commonParam(String name,int age){
Stystem.out.println("普通参数传递 name ==> " + name );
System.out.println("普通参数 age ==> " + age);
return "{'module':'common param'}";
}
如果形参与地址参数名不一致该如何解决?
发送请求与参数:
http://localhost/commonParamDifferentName?name=张三&age=18
后台接收参数:
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
因为前端给的是name
,后台接收使用的是userName
,两个名称对不上,导致接收数据失败:
解决方案:使用@RequestParam注解
名称:@RequestParam
类型:形参注释
位置:SpringMVC控制器方法形参定义前面
作用:绑定请求参数与处理器方法形参间的关系
范例:
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
System.out.println("普通参数 userName ==>" + userName);
System.out.println("普通参数 userName ==>" + age);
return "{'module':'common param different name'}";
}
参数:
required:是否为必传参数
defaultValue:参数默认值
这里个人的理解是给userName起别名,从而达到解耦的目的
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestPaam("name") String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
注:写上@RequestParam注解框架就不需要自己去解析注入,能提升框架处理性能
3.3.3POJO参数类型
简单数据类型一般处理的是参数个数比较少的请求,如果参数比较多,那么后台接收参数的时候就比较复杂,这个时候我们可以考虑使用POJO数据类型。
POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数,按照形参层次结构关系即可接收嵌套POJO属性参数
此时需要使用前面准备好的POJO类,先来看下User
private String name;
private int age;
private Address address;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
发送请求和参数:
3.3.4嵌套POJO参数
若POJO对象中嵌套了其他的POJO类,如在User类中有Address属性,而这里Address类属性引用类型
public class User {
private String name;
private int age;
private Address address;
}
public class Address {
private String province;
private String city;
}
发送请求和参数
这里内嵌的pojo类在发送请求时参数要写成内嵌类对象.属性名
后台接收参数:
嵌套POJO参数:与POJO参数要求一样:请求参数名与形参对象属性名相同,形参依然是传外层类的对象
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
3.3.5数组参数
数组参数:请求参数名与形参数组名相同,且请求参数为多个,定义数组类型即可接收参数
发送请求和参数:
后台接收参数:
//数组参数
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 arrayParam ==> "+Arrays.toString(likes));
return "{'module':'array param'}";
}
3.3.6集合类型参数
集合保存普通参数:请求参数名与形参集合对象名称相同且请求参数为多个,@RequestParam绑定参数关系
集合直接做形参会报错
原因解释:SpringMVC首先会将List看成POJO对象,会为其创建一个对象并把前端的数据封装完send进对象中,但是List是一个接口没有构造方法也即无法创建对象,所以报错。
解决方法:使用**@RequestParam**注解绑定参数关系
发送请求与参数:
后台接收参数:
//集合参数
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 arrayParam ==> "+likes);
return "{'module':'list param'}";
}
3.4请求参数(传递json数据)
- json数组
- json对象(POJO)
- json数组(POJO)
3.4.1json数组
具体流程如下:
①pom.xml添加依赖jackson-databind
SpringMVC默认使用的是jackson来处理json的转换
步骤②使用PostMan发送json数据
写入json数据
③:开启SpringMVC注解支持@EnableWebMvc
在SpringMVC的配置类中开启SpringMVC的注解支持,包含了将JSON转换成对象的功能。
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
④在形参前加上@RequestBody
这里仍然默认给:List造对象然后传数据进去,但是json数据存储在请求体中,所以无法使用@RequestParam注解,这里使用@RequestBody
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
3.4.2json对象数据
在servlet中
①Servlet接收json对象:
1.Servlet的getParameter()获取String形式的json对象
2.fastjson的JSON.parseObject()将json对象转为实体类对象
②Servlet响应JSON对象到前端:
1.将实体类对象通过fastjson的JSON.toJSONString方法转为String类型
2.response.getWriter().write(jsonStr)
发送json对象数据
后台controller接收参数:
使用@RequestBody注解将这里的形参实体类对象User直接转换JSON对象
//PoJO参数:json格式
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 list ==> "+user);
return "{'module':'pojo for json param'}";
}
注意事项:@EnableWebMvc功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换
注解:
名称:@EnableWebMvc
类型:配置类注解
位置:SpringMVC配置定义上方
作用:开启SpringMVC多项负责功能
范例:
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
名称:@RequestBody
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
范例:
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==>"+ likes);
return "{'moudle':'list common for json param'}";
}
3.4.3json对象集合参数
发送对象集合参数与请求
后台接收参数:
//集合参数:json格式
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
总结:
SpringMVC接收json参数的过程如下:
- 导入jackson包
- 使用PostMan发送JSON数据
- 开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解
- Controller方法的参数前添加@RequestBody注解
3.4.4@RequestBody与@RequestParam的区别
区别:
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
@RequestBody用于接收json数据【application/json】
应用:
后期开发中,发送json格式数据为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数
3.4.4日期类型参数传递
日期类型数据基于系统不同格式也不尽相同
2088-08-18
2088/08/18
08/18/2088
对于2088/08/18这种格式,controller可以自动转换成Date对象,其他格式其无法转为Date类型对象
需要根据不同的日期格式设置不同的接收方式
步骤1:编写方法接收日期数据
在UserController类中添加方法,把参数设置为日期类型
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date)
System.out.println("参数传递 date ==> "+date);
return "{'module':'data param'}";
}
步骤2:启动Tomcat服务器
查看控制台是否报错,如果有错误,先解决错误。
步骤3:使用PostMan发送请求
使用PostMan发送GET请求,并设置date参数
步骤4:查看控制台
步骤5:更换日期格式
为了便于观测不同日期格式程序运行的结果,在方法中多添加一个日期参数
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,Date date1)
System.out.println("参数传递 date ==> "+date);
return "{'module':'data param'}";
}
发送请求,携带两个不同的日期格式
发送请求和数据后,页面会报400,控制台会报出一个错误
从错误信息可以看出,错误的原因是在将2088-08-08
转换成日期类型的时候失败了,原因是SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd
,而我们现在传递的不符合其默认格式,SpringMVC就无法进行格式转换,所以报错。
解决方案也比较简单,需要使用@DateTimeFormat
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
return "{'module':'data param'}";
}
注:pattern用于指定具体的日期格式
步骤6:携带时间的日期
尝试发送一个携带时间的日期,看下SpringMVC该如何处理
先修改UserController类,添加第三个参数
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
发送请求,携带三个不同格式的日期
重新启动服务器,重新发送请求测试,SpringMVC就可以将日期时间的数据进行转换
分析:
①这里类型转换是由SpeingMVC完成的,是利用了类型转换器Convert接口
public interface Converter<S,T>{
@Nullable
T convert(S source);
}
请求参数年龄数据(String>>Integer)
日期格式转换 (String >> Date)
②**@EnableWebMvc功能之一:根据类型匹配对应类型转换器**
4响应
1.响应页面
2.响应数据:①文本数据;②json数据(重点)
4.1响应jsp页面[了解]
设置返回页面
@Controller
public class UserController {
@RequestMapping("/toJumpPage")
//注意
//1.此处不可以加@ResponseBody,否则会将page.jsp当字符串返回前端
//2.这里的返回值是String
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
}
4.2响应文本数据[了解]
设置返回文本内容
@Controller
public class UserController {
@RequestMapping("/toText")
//与响应页面不同,这里的注解不可以省略,否则会把response text当前页面名称,如果找不到该页面就会报404
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
}
4.3响应JSON数据
响应POJO对象:直接返回对象
这里必须加上@ResponseBody,因为对于SpringMVC来说返回值的位置默认跳转页面,而我们希望他能够按照我们想要的类型给出返回值,这时候我们就要修改响应的内容,需要自定义响应内容,就用到@ResponseBody。
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
注:转json对象这件事情不是SpringMVC做的,而是我们导入的Jackson坐标来实现的
4.4返回Json集合对象
加上@ResponseBody,返回集合
@Controller
public class UserController {
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
注解:
名称:@ResponseBody
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法响应内容为当前返回值,无需解析>>>>>>>>>>设置当前控制器返回值作为响应体
范例:
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.print("Save...");
return "{'info':'springmvc'}";
}
注:加上@ResponseBody注解之后不同的返回值类型会产生不同的响应类型
方法的返回值为字符串,会将其作为文本内容直接响应给前端
方法的返回值为对象,会将对象转换成JSON响应给前端
上述的转换不再是Convert接口实现的,而是HttpMessageConverter接口实现的
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> var1, @Nullable MediaType var2);
boolean canWrite(Class<?> var1, @Nullable MediaType var2);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> var1, HttpInputMessage var2) throws IOException, HttpMessageNotReadableException;
void write(T var1, @Nullable MediaType var2, HttpOutputMessage var3) throws IOException, HttpMessageNotWritableException;
}
注:该接口专用于转换Http消息