目录
1.SpringMVC概述
SpringMvc是一种基于Java实现MVC模型的轻量级web框架
1.在javaEE开发中,系统经典的三层架构包括表现层,业务层,持久层。三层架构中,每一层各司其职,
表现层(Web层):负责接收客户端请求,并响应客户端结果;
业务层(Service层):负责处理业务逻辑,与项目息息相关;
持久层(DAO层):负责与数据库交互,对数据库进行增删改查。
2.SpringMvc 优点:
1.使用简单,开发便捷(相比Servlet)
2.灵活性强!
2.SpringMVC基本使用
2.1maven中web项目的构建
两种构建方式:IDEA中创建Maven Web项目(两种方式)_码农怎么做的博客-CSDN博客_idea创建maven web项目
2.1.1导入坐标
<dependencies>
<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>
2.1.2 配置 tomcat 服务器。
2.1.3 配置web容器类
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
//web容器配置类 --类名可以自己定义 但是尽量要见名知意
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
2.2 SpringMvc开发中 简单注解
2.2.1 @Controller
@Controller 类注解 SpringMvc控制器 定义上方
作用: 设定 SpringMVC的核心控制器 Bean
@Controller
public class UserController {
}
2.2.2 @RequestMapping
-
名称:@RequestMapping
-
类型:方法注解
-
位置:SpringMVC控制器方法定义上方
-
作用:设置当前控制器方法请求访问路径
@RequestMapping("/save")
public void save(){
System.out.println("user save ...");
}
2.2.3 @ResponseBody
-
名称:@ResponseBody
-
类型:方法注解
-
位置:SpringMVC控制器方法定义上方
-
作用:设置当前控制器方法响应内容为当前返回值,无需解析
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
入门程序开发总结(1+N)
一次性工作
创建工程,设置服务器,加载工程
导入坐标
创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
多次工作
定义处理请求的控制器类
定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)
还有一些细节问题
3.请求与响应【重点】
3.1请求路径的映射
1. @RequestMapping 注解
-
名称:@RequestMapping
-
类型:==方法注解 类注解==
-
位置:SpringMVC控制器方法定义上方
-
作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
//请求路径映射
@RequestMapping("/save") //此时save方法的访问路径是:/user/save
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
}
3.2 请求参数问题【五种类型参数传递 】
3.2.1发送 普通请求 参数
@Controller
@RequestMapping("/user")
public class UserController {
//设置映射路径为/save,即外部访问路径
@RequestMapping("/save")
//设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
@ResponseBody
public String save(String username,Integer age){
System.out.println("user save ...");
System.out.println("姓名:" + username);
System.out.println("年龄:" + age);
return "{'info':'usersave'}";
}
}
当我们 发送 get请求 时,不会出现中文乱码问题 ,
发送 post 请求 时,就会出现中文乱码问题
get请求 出现中文乱码 就是这种原因
问题:如果同学们使用了tomcat插件传递的参数是中文试试,你们会发现接收到的参数出现了中文乱码问题。
原因:tomcat 8.5版本之后GET请求就不再出现中文乱码问题,但是我们使用的是tomcat7插件,所以会出现GET请求中文乱码问题。
解决:在pom.xml添加tomcat7插件处配置UTF-8字符集,解决GET请求中文乱码问题。
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port><!--tomcat端口号-->
<path>/</path> <!--虚拟目录-->
<uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
</configuration>
</plugin>
</plugins>
</build>
post 普通 请求 解决中文乱码问题
在配置文件 ServletContainerslnitConfig 写几行代码
// 乱码处理
@Override
protected Filter[] getServletFilters() {
// return super.getServletFilters();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
3.2.2 POJO类型 参数
1.实体类
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.请求访问路径:
// 对象 方法接收
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("姓名:" + user.getName());
System.out.println("年龄:" + user.getAge());
System.out.println(user);
return "{pojo : user}";
}
3.前端模拟访问
4.打印结果
这里有一个注意点: 请求参数key的名称要和POJO中属性的名称一致,否则无法封装。
3.2.3 嵌套pojo类型
1.实体类:
public class Address {
private String province;
private String city;
//getset toString 略
}
public class User {
private String username;
private int age;
private Address address;
//get set toString 略
}
2.后端接收
@RequestMapping("/nestPojoParam")
@ResponseBody
public String nestPojoParam(User user){
System.out.println("姓名:" +user.getUsername());
System.out.println("年龄:" + user.getAge() + "城市:" + user.getAddress().getCity());
return "{'nestPojoParam':'success'}";
}
3.模拟发送数据
3.2.4 数组和集合的形式 类型的参数
1.数组类型的参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数
请求的格式:
后端对应的方法
// 数组形式 接收 传递过来的
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
// 遍历数组
System.out.println(Arrays.toString(likes));
return "{arrayParam : success}";
}
注意:这里 likes 一定要对应 不然接收不到
上边是 数组形式 接收 ,下面是 用 集合形式接收
2.集合 形式 接收 请求 参数:
集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println(likes);
return "{'listParam':'success'}";
}
3.2.5 json数据参数传递 *****
导入坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
1.传递json 普通数组:
注解:
@EnableWebMvc 注解
-
名称:@EnableWebMvc
-
类型:==配置类注解==
-
位置:SpringMVC配置类定义上方
-
作用:开启SpringMVC多项辅助功能
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc//开启json数据类型 自动转换
public class SpringMvcConfig {
}
@RequestBody 注解
-
名称:@RequestBody
-
类型:==形参注解==
-
位置:SpringMVC控制器方法形参定义前面
-
作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
// json 数组格式
@RequestMapping("/listParamForJsonArr")
@ResponseBody
public String listParamForJsonArr(@RequestBody List<String> likes){
System.out.println(likes);
return "'listParamForJsonArr':'success'";
}
2.传递json 对象 格式
// pojoForJson
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("姓名:" + user.getUsername());
System.out.println("年龄:" + user.getAge());
System.out.println("省份:" + user.getAddress().getProvince());
System.out.println("省份:" + user.getAddress().getCity());
return "'pojoParamForJson':'success'";
}
3.传递 数组 对象 格式
// 解析 数组 对象格式
@RequestMapping("/listPojoForJson")
@ResponseBody
public String listPojoForJson(@RequestBody List<User> users){
System.out.println(users);
return "'listPojoForJson':'success'";
}
**********************
@RequestBody与@RequestParam区别
区别
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
@RequestBody用于接收json数据【application/json】
应用 后期开发中,发送json格式数据为主,@RequestBody应用较广 如果发送非json格式数据,选用@RequestParam接收请求参数
还有一些细节点,日期传递等等 日后要不断学习
4.RESTful风格
概述:RESTful风格 是一种 约定 而不是 规范 可以被打破 ,
import com.itheima.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller public class UserController { // 进行save保存的是来自 post,表示rest风格 的添加操作 @RequestMapping(value = "/users",method = RequestMethod.POST) //请求方式=post请求 // 如果路径匹配 且请求方式匹配就进该处理器方法 @ResponseBody public String save(@RequestBody User user){ System.out.println("user save:"+user); return "{'module':'save'}"; } // 进行delete删除来自 delete请求 表示rest风格的 删除操作 @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable("id")Integer id){ System.out.println("user delete"); return "{'module':'delete'}"; } // 进行update更新操作的 来自put请求 表示rest风格的 更新操作 @RequestMapping(value = "/users",method =RequestMethod.PUT ) @ResponseBody public String update(@RequestBody User user){ System.out.println("user update:"+user); return "{'module':'update'}"; } //进行getById查询操作的 来自 get请求,表示rest风格的查询操作 // http://localhost:8080/users/3/jack // 现在我们方法中想要得到的数据在哪? 请求路径上!!!Path // 这个数据是不是变化的数据--变量 variable // 我们要接收的数据 来自 路径变化数据 // /users/{id} {设置的一个变量} 接收当前位置的数据 // {} 区分了什么是资源 什么是数据 @RequestMapping(value = "/users/{id}",method = RequestMethod.GET) // id变量名 接收了 /users/后面的数据 // 可以这么想象..id=3 // @PathVariable()代表着从路径上的哪个接收变量上获取数据 @ResponseBody public String getById(@PathVariable("id")Integer id){ System.out.println("user getById..."+id); return "{'module':'getById'}"; } //进行getById查询操作的 来自 get请求,表示rest风格的查询操作 @RequestMapping(value = "/users",method = RequestMethod.GET) @ResponseBody public String getAll(){ System.out.println("user getAll"); return "{'module':'getAll'}"; } }
上面这种方式 不是最简单的方式 了解一下 就ok。
注解:介绍:
1. @PathVariable 注解
-
名称:@PathVariable
-
类型:形参注解
-
位置:SpringMVC控制器方法形参定义前面
-
作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应
注意:@RequestBody、@RequestParam、@PathVariable区别和应用
区别 @RequestParam用于接收url地址传参或表单传参 @RequestBody用于接收json数据 @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广 如果发送非json格式数据,选用@RequestParam接收请求参数 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
5.Rest 快速开发【重点】
-
名称:@GetMapping @PostMapping @PutMapping @DeleteMapping
-
类型:方法注解
-
位置:基于SpringMVC的RESTful开发控制器方法定义上方
-
作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求
-
属性: value(默认):请求访问路径
@postMapping 增加;
@DeleteMapping 删除;
@PutMapping 修改;
@GetMapping 查询;
@Controller
@RequestMapping("/users")
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
@PostMapping
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@DeleteMapping("/{id}")
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为PUT,表示REST风格中的修改操作
@PutMapping
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@GetMapping("/{id}")
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
@GetMapping
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
在Controller类上使用@RestController注解,等同于@Controller与@ResponseBody两个注解组合功能
@RestController
@RequestMapping("/users")
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
@PostMapping
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为PUT,表示REST风格中的修改操作
@PutMapping
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
@GetMapping
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
-
名称:@RestController
-
类型:类注解
-
位置:基于SpringMVC的RESTful开发控制器类定义上方
-
作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能
6.拦截器
问题1:拦截器拦截的对象是谁?
问题2:拦截器和过滤器有什么区别?
1.拦截器的概念和作用
-
拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
-
作用:
-
在指定的方法调用前后执行预先设定的代码
-
阻止原始方法的执行
-
总结:增强
-
-
核心原理:AOP思想
拦截器 和 过滤器 的区别?
归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
2.拦截器的实现
1.定义拦截器:做法:定义一个类,实现HandlerInterceptor接口即可
@Component //注意当前类必须受Spring容器控制
//定义拦截器类,实现HandlerInterceptor接口
public class ProjectInterceptor implements HandlerInterceptor {
@Override
//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle..."+contentType);
return true;
}
@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
3.配置加载拦截器
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired
private ProjectInterceptor projectInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//配置拦截器
registry.addInterceptor(projectInterceptor)
.addPathPatterns("/books","/books/*");
}
}
使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强)
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor)
.addPathPatterns("/books","/books/*");
}
}
最好使用第一种
4.拦截器流程分析
拦截参数
参数
request:请求对象
response:响应对象
handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
返回值 返回值为false,被拦截的处理器将不执行。
5.配置多个拦截器
@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...222");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...222");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...222");
}
}
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor)
.addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterceptor2)
.addPathPatterns("/books","/books/*");
}
}