一、SpringMVC简介
一、SpringMVC学习目标
二、SpringMVC概述
三、SpringMVC快速入门
四、启动服务器初始化过程
五、Controller加载控制与业务bean加载控制
六、简化Servlet容器开发
二、设置请求映射路径
一、get请求发送参数
一、解决post请求传递的参数名与后台形参名不一致问题
二、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
三、嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
四、数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数据类型形参即可接收参数
五、集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
六、总结关于@RequestParam
二、post请求参数
三、发送JSON数据(常用)
一、集合参数
二、POJO参数
三、POJO集合参数
四、@RequestParam与@RequestBody区别
五、日期类型参数传递
三、响应
一、响应页面(了解)
二、响应文本数据(了解)
三、响应json数据(对象转json)
四、响应json数据(对象集合转json数组)
四、REST风格
一、REST简介
二、入门案例
三、对入门案例进行快速开发优化(RESTful)
四、注解@RequestBody、@RequestParam、@PathVariable区别
五、案例:基于RESTful页面数据交互
一、SpringMVC简介
一、SpringMVC学习目标
1、掌握基于SpringMVC获取请求参数与相应json数据操作;
2、熟练应用基于REST风格的请求路径设置与参数传递;
3、能够根据实际业务建立前后端开发通信协议并进行实现;
4、基于SSM整合技术开发任意业务模块功能。
二、SpringMVC概述
1、SpringMVC技术与Servlet技术功能等同,均属于web层开发技术。相比于Servlet使用简单、开发便捷。
2、SpringMVC是一种基于Java实现MVC模型的轻量级Web框架。
三、SpringMVC快速入门
步骤①:使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.19</version>
</dependency>
</dependencies>
②:创建SpringMVC控制器类(等同于Servlet功能)
package com.chf.controller;
@Controller
public class UserController{
//此注解相当于Servlet的@WebServlet("/save"),设置翻墙控制器方法的访问路径。
@RequestMapping("/save")
//此注解设置当前控制器方法相应内容为当前返回值,无需解析。
@ResponseBody
public String save(){
System.out.println("user save");
return "{'info':'SpringMVC'}";//为相应到网页上的内容
}
}
③:初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean
package com.chf.config;
@Configuration
@ComponentScan("com.chf.controller")
public class SpringMvcConfig{}
④:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
package com.chf.config;
//定义一个Servlet容器启动的配置类,在里面加载Spring的配置
public class ServletContainsInitConfig extends AbstractDispatcherServletInitializer {
//加载SpringMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置哪些请求归属SpringMVC处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};//代表所有请求
}
//加载Spring容器配置,可以将上上的方法体复制过来,将SpingMvcConfig改成SpringConfig
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
对步骤四进行解释:
1、AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类;
2、AbstractDispatcherServletInitializer提供三个接口方法供用户实现;
①createServletApplicationContext()方法,创建Servlct容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServlctContext范围,即整个web容器范围。
③getServletMappings()方法,设定SpringMVC对应的请求映射路径,设置为"/"表示拦截所有请求,任意请求都将转入到SpringMVC进行处理。
④createRootApplicationContext()方法,如果创建Serlvet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()方法。
四、启动服务器初始化过程
1、服务器启动,执行ServletContainersInitConfig类,初始化Web容器;
2、执行createServletApplicationContext方法,创建了WebApplicationContext对象;
3、加载SpringMvcConfig;
4、执行@ComponentScan加载对应的bean;
5、加载UserController,每个@RequestMapping的名称对应一个具体的方法;
6、执行 getServletMappings方法,定义所有的请求都通过SpingMVC。
五、Controller加载控制与业务bean加载控制
1、SpringMVC相关bean加载控制:对应的包均在com.chf.controller包内。
2、Spring相关bean加载控制:
①设定扫描范围为精准范围,例如数组方式指定想要扫描的包{"com.chf.service","com.chf.dao"};
②设定扫描范围为com.chf,排除掉controller包内的bean。此时就需要用下图所写的代码(在SpringBoot源码涉及)。excludeFilters:排出扫描路径中加载的bean,需要指定类别(type)与具体(classes)。
package com.chf.config;
@Configuration
@ComponentScan("com.chf.controller")
public class SpringMvcConfig{}
package com.chf.config;
@Configuation
//@ComponentScan({"com.chf.service","com.chf.dao"})
@ComponentScan(value="con.chf",encludeFilters=@ComponentScan.Filter(
type=FilterType.ANNOTATION,classes=Controller.class
)
)
public class SpringConfig{}
六、简化Servlet容器开发
package com.chf.config;
public class ServletContainsInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
二、设置请求映射路径
一、get请求发送参数
我们首先需要了解参数有五种:
①普通参数、②POJO类型参数、③嵌套POJO类型参数、④数组类型参数、⑤集合类型参数
package com.chf.controller;
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping("/save")
@ResponseBody
public String save(String username,int age){
System.out.println("user save");
return "{'info':'SpringMVC user'}";
}
}
一、解决post请求传递的参数名与后台形参名不一致问题
如上例子所示,将代码中的形参名做修改,使用到@RequestParam注解
作用:绑定请求参数与处理器方法形参间的关系
package com.chf.controller;
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping("/save")
@ResponseBody
public String save(@RequestParam("username") String name,int age){
System.out.println("user save");
return "{'info':'SpringMVC user'}";
}
}
二、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
package com.chf.service;
@RequestMapping("/domain")
@ResponseBody
public String pojoParam(User user){
System.out.println("domain参数传递 user ==> "+user);
return "{'module':'domain param'}";
}
package com.chf.domain;
//domain目录下的实体类
public class User {
private String name;
private int age;
//以下省略toString()方法和setget方法
}
三、嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
package com.chf.service;
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
package com.chf.domain;
//domain目录下的实体类
public class User {
private String name;
private int age;
private Address address;
//以下省略toString()方法和setget方法
}
public class Address {
private String province;
private String city;
//以下省略toString()方法和setget方法
}
四、数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数据类型形参即可接收参数
package com.chf.service;
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
五、集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
package com.chf.service;
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
六、总结关于@RequestParam
①、注解@RequestParam接收的参数是来自requestHeader中,即请求头。
RequestParam可以接受简单类型的属性,也可以接受对象类型。
②、@RequestParam有三个配置参数:
required 表示是否必须,默认为 true,必须。 defaultValue 可设置请求参数的默认值。 value 为接收url的参数名(相当于key值)。 ③、@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。
④、可以使前端的参数名和后端控制器的变量名不保持一致
⑤、可以绑定多个参数,如集合或者数组时必须使用。
二、post请求参数
解决网页post提交后在后台的乱码问题:在Servlet容器中添加过滤器 :
package com.chf.config;
public class ServletContainsInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//配置字符编码过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
三、发送JSON数据(常用)
一、集合参数
步骤①在pom.xml中添加以下依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
②在SpringMvcConfig核心配置类中添加注解@EnableWebMvc
注:@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换。
package com.chf.config;
@Configuration
@ComponentScan("com.chf.controller")
@EnableWebMvc
public class SpringMvcConfig{}
③在postman软件中,先改成body形式紧接着使用raw,在右边的格式改成JSON
④后端代码中的形参前面添加@RequestBody注解即可。
总结关于@RequestBody
①、@RequestBody:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能用一次。
②、注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。
③、就application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。
package com.chf.service;
@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'}";
}
二、POJO参数
package com.chf.service;
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
三、POJO集合参数
package com.chf.service;
@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'}";
}
四、@RequestParam与@RequestBody区别
1、区别:
①@RequestParam用于接收url地址传参、列表传参【application/x-www-from-urlencoded】
②@RequestBody用于接收json数据【application/json】
2、应用:
①后期开发中,传送json格式数据为主,@RequestBody应用较广
②如果发送非json格式数据,选用@RequestParam接收请求参数
五、日期类型参数传递
接收形参时,根据不同的日期格式设置不同的接收方式。
注解@DateTimeFormat作用:设定日期时间型时间格式
package com.chf.service;
@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'}";
}
三、响应
响应分为:响应页面和响应数据。
响应数据分为:文本数据和json数据。
一、响应页面(了解)
package com.chf.service;
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "welcome.jsp";//这里编写的即是跳转到的页面名
}
二、响应文本数据(了解)
@ResponseBody:设置当前控制器返回值作为响应体。
但不是Servlet里的response.setContentType("text/html")。
package com.chf.service;
@RequestMapping("/toText")
@ResponseBody
public String toJumpPage(){
return "response text";
}
三、响应json数据(对象转json)
设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解。
package com.chf.service;
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("鸿");
user.setAge(18);
return user;
}
四、响应json数据(对象集合转json数组)
设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解。
package com.chf.service;
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("鸿");
user1.setAge(18);
User user2 = new User();
user2.setName("a");
user2.setAge(19);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
四、REST风格
一、REST简介
REST(Representational State Transfer),表现形式状态转换。
传统风格资源描述形式
http://localhost/user/getById?id=1
http://localhost/user/saveUser
REST风格描述形式
http://localhost/user/1
http://localhost/user
优点:①隐藏资源的访问行为,无法通过地址得知对资源是何种操作;②书写简化
二、入门案例
①:设定http请求动作(动词)
package com.chf.service;
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
②设定请求参数(路径变量)
注解@PathVariable用于形参注解,放在形参定义的前面。
作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应。
package com.chf.service;
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
三、对入门案例进行快速开发优化(RESTful)
package com.chf.service;
@RequestMapping("/users")
@RestController
public class UserController{
@PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
@PutMapping //使用@PutMapping简化Put请求方法对应的映射配置
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
①@RestController注解,用于类注解。
作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能。
②@GetMapping、@PostMapping、@PutMapping、@DeleteMapping,用于方法注解。
作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,其中value默认为默认访问路径。
四、注解@RequestBody、@RequestParam、@PathVariable区别
区别:
①@RequestParam用于接收url地址传参或者表单传参
②@RequestBody用于接收json数据
③@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用:
①后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
②如果发送非json格式数据,选用@RequestParam接收请求参数
③采用RESTful进行开发,但参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量。
五、案例:基于RESTful页面数据交互
①:制作SpringMVC控制器,并通过PostMan测试接口功能。
package com.chf.service;
@RestController
@RequestMapping("/books")
public class BookController {
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save ==> "+ book);
return "{'module':'book save success'}";
}
@GetMapping
public List<Book> getAll(){
System.out.println("book getAll is running ...");
List<Book> bookList = new ArrayList<Book>();
Book book1 = new Book();
book1.setType("计算机");
book1.setName("SpringMVC入门教程");
book1.setDescription("小试牛刀");
bookList.add(book1);
Book book2 = new Book();
book2.setType("计算机");
book2.setName("SpringMVC实战教程");
book2.setDescription("一代宗师");
bookList.add(book2);
Book book3 = new Book();
book3.setType("计算机丛书");
book3.setName("SpringMVC实战教程进阶");
book3.setDescription("一代宗师呕心创作");
bookList.add(book3);
return bookList;
}
}
②:设置对静态资源的访问放行
package com.chf.config;
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
//设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}