文章目录
1.SpringMVC
请求与响应(2~6)
REST风格(7~)
SSM整合
拦截器
目标:
1.掌握基于SpringMVC获取请求参数与响应json数据·操作
2.熟练应用基于REST风格的请求路径设置与参数传递
3.能够根据实际业务建立前后端开发通信协议并进行实现。
4.基于SSM整合技术开发任意模块功能
2.表现层(view)框架入门案例
2.1步骤:
1.导入pom.xml
2.创建mvc控制器(等同Serlvet功能)
3.初始化mvc环境,设置bean
4.初始化servlet容器,加载mvc,设置其技术处理的请求
2.2 项目结构:
ServletContainersInitConfig
package com.qxy.config;
//定义一个servlet容器(tomcat)启动的配置类,在里面加载spring配置
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//servlet容器用于接收配置的一个类
@Override
protected WebApplicationContext createServletApplicationContext() {
//创建并加载mvc配置
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;//返回这个配置
}
@Override
protected String[] getServletMappings() {
//设置被处理请求
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
//加载spring容器配置
return null;
}
}
SpringMvcConfig
package com.qxy.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.qxy.controller")
public class SpringMvcConfig {
}
UserController
package com.qxy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
//set controller
//use controller set bean
@Controller
public class UserController {
//set this path
@RequestMapping("/save")
//set this path's type
@ResponseBody
public String save(){
System.out.println("Get save...");
return "{'module':'springmvc'}";
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qxy</groupId>
<artifactId>springmvc_01_quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>//注意打包格式
//maven项目资源文件
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 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>
</dependencies>
//导入tomcat插件
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>//端口设置
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.3 所用注释(全)
名称 | 类型 | 位置 | 作用 | 相关属性 |
---|---|---|---|---|
@Controller | 类注解 | 控制器类 | 设定SpringMVC的核心控制器bean | |
@RequestMapping | 方法注解/类注解 | 控制器 | 设置当前控制器方法请求访问路径 | value(默认):请求访问路径 |
@ResponseBody | 方法注解 | 控制器方法定义 | 设置当前控制器方法响应内容为当前的返回值,无需解析 | |
@Configuration | 类注解 | MVC配置类 | ||
@ComponentScan | 类注解 | MVC配置类 | excludeFilters:排除扫描路径中加载的bean;includeFilters:加载指定的bean。都需要指定类别和具体项 | |
@RequestParam | 参数注解 | 形参 | 绑定前后关系 | |
@RequestBody | 参数注解 | 形参 | 将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次 | |
@EnableWebMvc | 配置类注解 | 配置类上方 | 开启SpringMVC多项辅助功能 | |
@PathVarible | 形参注解 | 形参 | 声明形参来自路径 | |
@RestController | 类注解 | RESTful控制器类 | 设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解 | |
@PostMapping | 方法注解 | |||
@DeletMapping | 方法注解 | |||
@PutMapping | 方法注解 | |||
@GetMapping | 方法注解 |
2.4 案例工作流程分析
-
启动服务器初始化过程
- 1.服务器启动,执行ServletContainerInitConfig类,初始化web容器
- 2.执行creatServletApplicationContext方法,创建了webApplicationContext对象
- 3.加载SpringMvcConfig
- 4.执行@ComponentScan加载到对应的bean
- 5.加载UserController,每个@RequestMapping的名称对应一个具体的方法
- 6.执行getSevletMappings方法,定义所有的请求都通过SpringMVC
-
单次请求过程
- 1.发送请求
- 2.web服务器发现所有请求都通过SpringMVC,将请求交给它处理
- 3.解析请求路径/save
- 4.由/save匹配执行对应的方法save()
- 5.执行save()
- 6.检测到有@ResponseBody直接将save()方法的返回值作为请求响应体返回给请求方
3.案例延伸 1 :Controller 加载控制 与 业务bean 加载控制
问题:因为功能的不同,如何避免Spring错误加载到SpringMVC的bean?
SpringBoot中使用filter对bean加载进行了控制
Controller 加载控制
业务bean 加载控制
- 方式一:Spring加载的bean设定扫描范围为com.groupid,排除掉controller包在内的bean
@Configuration
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
- 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包,dao包^
@Configuration
@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}
方式三:不区分Sping和SpringMVC环境,加载到同一个环境中
3.2 ServletContainerInitConfig bean加载格式
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//servlet容器用于接收配置的一个类
@Override
protected WebApplicationContext createServletApplicationContext() {
//创建并加载mvc配置
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;//返回这个配置
}
@Override
protected String[] getServletMappings() {
//设置被处理请求
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
//加载spring容器配置
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
public 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[]{"/"};
}
}
4.PostMan工具使用
1.注册登录
2.创建工作空间
3.创建请求集合
5.请求(json数据)
5.1 请求映射路径
根据模块不同加上一个映射路径
5.2 get请求和post请求
-
get请求
-
post请求
直接用postman测试
区别在于post请求在请求体里面发
-
post请求中文乱码处理
解决办法:设定过滤器(servlet容器初始化配置)
@Override
protected Filter[] getServletFilters() {
//启动过滤器
CharacterEncodingFilter filter = new CharacterEncodingFilter();
//设定字符集
filter.setEncoding("UTF-8");
//返回配置
return new Filter[]{filter};
}
5.3 请求参数(5种)
- 普通参数:
- 1.url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
- 2.请求参数名与形参不同(@RequestParam(“*”) *)
- POJO类型参数
- 属性名相同,参数就可以自动转换为pojo对象
- 嵌套POJO类型参数
- 注意引用对象的重写问题
- 数组类型参数
- 参数名相同直接传,多个数据是一个数组
- 集合类型参数
- ( @RequestParam List< String > likes )
5.4 请求参数(传递json数据)
1.开启json数据(导入坐标)格式的自动转换,在配置类(MVCconfig)中开启@EnableWebMvc
2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
为什么json参数要使用@ResoponBody? 前端JSON参数传递@RequestParam和@RequestBody的用法?
前端请求传Json对象则后端使用@RequestParam(默认);
前端请求传Json对象的字符串则后端使用@RequestBody。
@RequestBody接受的是一个json对象的字符串,而不是Json对象,在请求时往往都是Json对象,用JSON.stringify(data)的方式就能将对象变成json字符串。
json数组, json对象(POJO),json数组(POJO) 这三个参数接收差不多,都需要用@RequestBody+形参
//eg:
@RequestMapping(“/”)
@ResponseBody
public String listParamForJson(@RequestBody List<String> sths)
{
return "{' "listparamforjson" '}";
}
//
@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'}";
}
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
@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'}";
}
|
|
|
@RequestBody和@RequestParam区别
-
区别:
- @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
- @RequestBody用于接收json数据【application/json】
-
应用
- 后期开发中,发送json数据为主,@RequestBody使用面较广
- 如果发送非json格式数据,选用@RequestParam接受请求参数
5.5 日期类型参数传递
@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'}";
}
6.响应
@ResponseBody (直接将数据转换发送)设置当前控制其返回值(转化为可识别数据:对象转json)为响应体。
@Controller
public class UserController {
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
//响应文本数据
//返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
//响应POJO对象
//返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@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;
}
}
7.REST风格
7.1简介
- 优点:隐藏资源的访问行为,无法通过地址得知对资源是什么操作。书写简化
- 按照RESF风格访问资源时使用 行为动作 区分对资源的操作
- http://localhost/users : |查询全部用户信息| GET(查询)
- http://localhost/users/1 :|查询指定用户信息| GET(查询)
- http://localhost/users : |添加用户信息 | POST(新增/保存)
- http://localhost/users : |修改用户信息 | PUT(修改/更新)
- http://localhost/users/1 :|删除用户信息| DELETE(删除)
PS:上述行为是约定方式,restful是按照这种方式访问资源
7.2 入门案例
增(POST) 删(DELET) 改(PUT) 查(GET)
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
7.3 RESTful快速开发(注释页)
7.4 RESTful 案例
重点:静态资源放行访问
@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/");
}
}