MVC,一种用于创建Web应用程序表现层的模式。
它通过一套注解,让一个简单的Java类成为处理器。
作用:分离数据的存储和数据的展示;
Model(模型):数据模型,用于封装数据;
View(视图):页面视图,用于展示数据:
jsp
html
Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑:
Servlet
SpringMVC
SpringMVC底层用的还是Servlet。
SpringMVC特点:
1.基于 MVC 设计模型的请求驱动类型的轻量级 Web 框架;
2.可以集成其它的web框架;
3.它通过一套注解,让一个简单的 Java 类成为处理器代替以前的Servlet;
4.支持RESTful编程风格的请求。
简述SpringMVC如何接收前端的数据?
SpringMVC为我们提供了很多种获取参数的方式,其中包含普通参数、POJO类型参数、嵌套POJO类型参数、数组类型参数、集合类型参数以及JSON数据类型参数。
1.普通参数有两种数据传递方式
方式一:url?key=value,确保方法的形参与key一致即可接收,如果不一致需要使用@RequestParam来建立关系;
方式二:url/value,RESTFul参数传递方式即为路径参数,需要使用@PathVariable来接收;
2.普通参数如果过多,在方法中编写参数就比较麻烦,此时可以使用POJO数据类型来接收,需要确保POJO的属性名和参数的key一致即可;
3.POJO对象也可以嵌套其他的POJO,可以用来接收比较复杂的数据,比如用户中包含地址信息;
4.数组类型参数可以用来接收key相同的多个参数,比如用户的爱好信息等;
5.集合类型参数,使用数组来接收的数据也可以使用集合来接收,但是需要在参数前添加@RequestParam注解;
6.对于JSON数据类型参数,后台接收需要使用@RequestBody。
SpringMVC入门案例
使用SpringMVC技术开发web程序流程:
1.创建web工厂(Maven结构)
2.导入坐标(SpringMVC+Servlet)
3.创建SpringMVC控制器类(等同于Servlet功能)
@Controller:用来处理客户端的请求,这个创建对象放到Spring容器中。
@RequestMapping:设置当前控制器方法请求访问路径,save前斜杠可以省略;放在SpringMVC控制器方法定 义上方。可以放在方法或类上。
请求映射路径:@RequestMapping
@ResponseBody//将方法的返回值作为响应体
4.设定SpringMVC加载对应的bean
5.初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径
SpringMVC技术架构图
SpringMVC各组件的作用:
DispatcherServlet:前端控制器,是整体流程控制的中心,由其调用其它组件处理用户的请求,有效的降 低了组件间的耦合性;
HandlerMapping:处理器映射器,负责根据用户请求找到对应具体的Handler处理器;
Handler:处理器,业务处理的核心类,通常由开发者编写,描述具体的业务;
HandlerAdapter:处理器适配器,通过它对处理器进行执行;
ViewResolver:视图解析器,将处理结果生成View视图;
View:视图,最终产出结果,常用视图如jsp、html 。
请求与响应
postMan的使用
Postman是一款功能强大的网页调试与发送网页HTTP请求的软件。
请求
Get请求传参
普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数。
Post请求
普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数。
Post请求中文乱码处理
为web容器添加过滤器并指定字符集,Spring-web包中提供了专用的字符过滤器。
请求参数
普通参数
请求参数名与形参变量名不同,使用@RequestParam绑定参数关系。
POJO参数
请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数。
嵌套POJO参数
请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。
数组参数
请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数。
集合保存普通参数
请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系。
传递json数据
接收请求中的json数据的步骤:
1.添加json数据转换相关坐标
2.设置发送json数据(请求body中添加json数据),设置接收json数据。
@RequestBody:获取请求体中的数据是一个JSON字符串要转成Java中的数组或对象。
3.开启自动转换json数据的支持
开启SpringMVC辅助功能,JSON字符串要转成Java中的数组或对象。
配置完后,传递json数据和上述的参数编写方式一样。
日期类型参数传递
设定日期时间型数据格式,默认是yyyy/MM/dd;
属性:pattern:日期时间格式字符串。
@RequestBody与@RequestParam区别
@RequestParam用于接收url地址传参;传递的参数格式是:键=值&键=值;底层使用是getParameter(“键”)。
@RequestBody用于接收json数据;数据在请求体中,不能用于GET方法,只能出现一次,因为每次请求只有一个请求体;不能获取键值对的数据,底层使用getReader()方法。
后期开发中,发送json格式数据为主,@RequestBody应用较广
响应
方法的上面没有@ResponseBody注解
没有@ResponseBody就会跳转到其他页面
return “/success.jsp”;——默认是转发
return “forword:/success.jsp”;——转发
return “redirect:/success.jsp”;——重定向
前面加/是因为要使用绝对路径,不然会出现跳转错误
比如:
响应文本数据
@ResponseBody——返回值会作为响应体返回给客户端
响应json数据(对象转json)
响应json数据(对象集合转json数组)
RESTful风格
REST即表现形式状态转换,它是一种软件架构风格,不是标准。简单概括就是通过使用同一个请求地址和不同的请求动作来区分对资源进行不同的操作,如GET用来做查询,POST用来做新增,PUT用来做修改,DELETE用来做删除。
RESTful是基于REST构建的API统称为RESTful。
RESTful其中的两个特点:
1.每一个URI代表1种资源
2. 客户端使用GET、POST、PUT、DELETE四个表示操作方式的动词对服务端资源进行操作
1). GET用来获取资源
2). POST用来新建资源
3). PUT用来更新资源
4). DELETE用来删除资源
RESTful快速开发-优化
@Controller:创建这个类的对象,放到Spring容器中;
@RequestBody :取出请求体中的JSON数据 自动转成Java的对象或集合;
@ResponseBody:把返回值作为响应给浏览器;
@RestController:RESTful风格的控制器 @RestController=@Controller+@ResponseBody;
@PathVariable:路径变量,取路径中的数据复制给参数。
//@Controller//创建这个类的对象,放到Spring容器中
//@ResponseBody//每个方法都是@ResponseBody
@RestController//RESTful风格的控制器 @RestController=@Controller+@ResponseBody
@RequestMapping("/books")
public class BookController {
//保存书籍
//@RequestBody :取出请求体中的JSON数据 自动转成Java的对象或集合
// @ResponseBody:把返回值作为响应给浏览器
@PostMapping//@RequestMapping(method = RequestMethod.POST)
public String save(@RequestBody Book book){
System.out.println("保存书籍"+book);
return "save success";
}
//修改书籍
@PutMapping//@RequestMapping(method = RequestMethod.PUT)
public String update(@RequestBody Book book){
System.out.println("修改书籍:"+book);
return "update success";
}
//删除书籍
//@PathVariable:路径变量,取路径中的数据复制给参数
@DeleteMapping("/{id}")//@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
public String delete(@PathVariable int id){
System.out.println("删除:"+id);
return "delete success";
}
}
案例:基于RESTful页面数据交互
拦截器
拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。
拦截器与过滤器区别:
归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术;
拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。
拦截器的入门案例
1.声明拦截器的bean,编写类,并实现HandlerInterceptor接口,重写三个方法。
2.定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法(注意:扫描加载配置包);
3.添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个。
拦截器拦截流程
1. preHandle是在handle方法执行之前执行,返回true或者false,true代表放行,false代表拦截
2.postHandle是在handle方法执行之后执行
3.afterCompletion是拦截器最后执行的方法
多拦截器执行顺序
拦截器链的运行顺序:
preHandle:与配置顺序相同,必定运行;
postHandle:与配置顺序相反,可能不运行;
afterCompletion:与配置顺序相反,可能不运行。
SpringMVC上传文件
1.导入jar包
2.配置CommonsMultipartResolver
利用注解方式@Bean
方法名必须是multipartResolver
package com.itheima.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig{
@Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver cmr=new CommonsMultipartResolver();
cmr.setMaxUploadSize(5242880);//设置上传文件的最大尺寸为5MB——1024*1024*5
return cmr;
}
}
3.使用MultipartFile获取文件
方法的参数名称要和前端发送文件的名称一致。
package com.itheima.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
@RequestMapping("/upload")
public class UploadController {
@PostMapping
public String upload(MultipartFile upload, HttpSession session) throws IOException {
//1.获取项目根路径下的images路径地址
String realPath = session.getServletContext().getRealPath("/images");
//2.获取上传文件的名称
String filename = upload.getOriginalFilename();//XXX.jpg
//3.得到文件重新命名,避免出现文件名重复导致覆盖
//3.1获取到一个uuid字符串+文件后缀
String uuid = UUID.randomUUID().toString();
String extName = filename.substring(filename.lastIndexOf("."));
filename=uuid+extName;
//4.将文件存入指定的位置
upload.transferTo(new File(realPath+"/"+filename));
return "success";
}
}