SpringBoot(五)-SringMVC
项目初始化
- 打开spring-boot-starter-web依赖,可以看到依赖的jar包有spring-webmvc,默认情况下,SpringBoot已经内置了很多SpringMVC的常用配置
- 在22_parent下新建Module项目为07_mvc
- 创建入口程序Application、创建TestController类
com.zh.controller.TestController
//com.zh.controller.TestController @RestController public class TestController { @Autowired private ProjectProperties properties; @GetMapping("/test") public String test(Date birthday) { return "哈哈哈哈 - " + birthday; } }
- 创建入口程序Application、创建TestController类
SringMVC的配置
- 默认情况下,SpringBoot已经内置了很多SpringMVC的常用配置(WebMvcConfigurer接口可以查看)
- 如果希望在此基础上,继续增加一些配置,可以新建类SpringMvcConfig,实现WebMvcConfigurer接口,该接口中包含了springVC很多配置
- 如果希望完全自定义SpringMVC的配置,那就使用@EnableWebMvc
//com.zh.cfg.SpringMvcConfig @Configuration //@EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { //实现WebMvcConfigurer的接口 }
- 在application.yml配置文件的配置
- 具体配置那些内容,可以参考,maven依赖包目录spring-boot-autoconfigure.jar中的WebMvcProperties类
- 在jar包下打开spring.factories->搜索WebMvcAutoConfiguration->搜索WebMvcProperties,进入即可
- 在resources下新建application.yml
spring: mvc: servlet: # servlet的创建时间 load-on-startup: 0 #日期格式转换 format: date: yyyy-MM-dd
- 具体配置那些内容,可以参考,maven依赖包目录spring-boot-autoconfigure.jar中的WebMvcProperties类
文件上传
-
resources下新建templates文件夹,在下面新建index.xml
//核心代码 <form action="/upload" method="post" enctype="multipart/form-data"> <input type="text" name="username"> <input type="file" name="photo"> <button type="submit">上传</button> </form>
-
07_mvc的pom.xml添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!--第三方库,获取文件扩展名 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.7</version> </dependency>
-
application.xml中配置上传文件的大小限制、文件上传的具体路径
# 配置上传文件的大小 servlet: multipart: max-file-size: 10MB max-request-size: 10MB # 指定好文件上传的具体路径 project: upload: base-path: F:/upload/ image-path: img/ video-path: video/
-
封装读取application.xml中设置的数据类ProjectProperties
//对应这application.xml中的project字段 @ConfigurationProperties("project") @Component @Data public class ProjectProperties { //对应upload字段 private Upload upload; //内部类 @Data public static class Upload { //对应upload类 private String basePath; private String imagePath; private String videoPath; public String getImageFullpath() { return basePath + imagePath; } public String getVideoFullpath() { return basePath + videoPath; } } }
-
注意: 这个功能是父类里面的这个第三方依赖包实现的
<!-- 配置文件属性名提示 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency>
-
-
TestController新增upload方法
@PostMapping("/upload") public String upload(String username, MultipartFile photo, HttpServletRequest request) throws Exception { System.out.println(username); System.out.println(photo); // 使用第三方库commons-io,获取文件扩展名 String extension = FilenameUtils.getExtension(photo.getOriginalFilename()); // 目标文件 //获取文件目录 String dir = properties.getUpload().getImageFullpath(); //文件名 String filename = UUID.randomUUID() + "." + extension; File file = new File(dir + filename); // springboot如果文件路径不存在,默认不会创建,因此使用第三方commons-io,创建好目标文件所在的父目录 FileUtils.forceMkdirParent(file); // 将文件数据写到目标文件 photo.transferTo(file); return "上传成功!!!"; }
资源映射(重点!!!!,理解)
-
在学习javaEE时上传文件直接在contextpath下建一个文件路径存储即可,原因是之前打包的项目都是war包,然后直接放到Tomcat的webapps文件夹下,路径固定可以直接访问
//之前JavaEE获取项目的根路径通过这个方法 request.getServletContext().getRealPath(); //如果springboot项目仍然使用这个,会发现获取的是临时路径
- 而且war项目部署的方式是直接本地解压war包,然后上传的所有文件会放到war包的某个目录下,所以可以直接访问。
- springboot项目打包是jar,而且直接通过java-jar直接运行,此时运行的项目路径都是临时的虚拟路径,并不是在当前目录下解压运行,因此文件上传的路径不能是临时的,所以要配置一个绝对路径,这就是上面为什么要在application.xml中配置文件的具体路径的原因
- 通常情况接收到客户端上传的文件时,还需要将这个文件存储的路径返回给客户端进行访问,但是此时文件存储在磁盘固定位置上,并不在在这个服务器项目路径中,那该怎么办呢? —-资源映射
- 资源映射的原理
- 将指定存储文件的磁盘路径映射到项目的静态资源路径下,这样就可以直接访问固定磁盘路径下的资源了
-
在application.yml中配置
#通过什么路径能够访问到静态资源,/**,无论静态资源下面几层目录,直接通过/就可以访问,比如:http://localhost:8080/img/xxx.png # 尽管图片的实际路径是:F:/upload/img/xxx.png,但是直接用一个/代表了F:/upload/路径 spring: mvc: static-path-pattern: /** # 告诉springmvc有那些静态资源的路径 spring: resources: static-locations: # 项目根目录即resources下的static文件夹 - classpath:/static/ # 存储文件的具体磁盘路径,file://本机去查找,/根路径 - file:///${project.upload.base-path}
- 这么配置,项目resources下的static、电脑的F:/upload/都变成了静态资源目录,浏览器直接可以访问了
-
也可以通过实现WebMvcConfigurer的方法进行静态资源的映射
public class SpringMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/"); registry.addResourceHandler("/**") .addResourceLocations("file:///F:/upload/"); } }
- 总结
- 在SpringBoot中,静态资源需要进行映射才能直接访问
-
SpringBoot默认的静态资源映射处理,看下面源码路径,就是如何设置静态资源的访问目录
spring-boot-autoconfigure.jar-> 打开spring.factories-> 搜索WebMvcAutoConfiguration-> WebMvcAutoConfigurationAdapter-> addResourceHandlers
-
在application.yml中添加的值本质是如下:
//1. 配置文件中的配置 spring: mvc: static-path-pattern: /** spring: resources: static-locations: - classpath:/static/ - file:///F:/upload/ //2. 实际的代码转化如下: @Configuration public class SpringMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/"); registry.addResourceHandler("/**") .addResourceLocations("file:///F:/upload/"); } }
webjars
- SpringBoot支持使用webjars的方式访问静态资源
- 本质就是一个第三方库org.webjars,添加了依赖之后,会在maven下新建一个静态资源目录,然后将前端很多的框架导入进去
- 在项目中可以直接通过/webjars/路径去访问
- 举例:使用webjars方式访问jquery
-
pom.xml添加依赖
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.5.1</version> </dependency>
-
index.html使用
<button type="button" id="btn-add">添加</button> //直接可以引入jquery <script src="/webjars/jquery/3.5.1/jquery.min.js"></script> <script> $('#btn-add').click(() => { alert('点击了添加') }) </script>
-
文件下载
- 在项目的static文件夹下新建一个txt文件夹,下面有个test.txt文件
-
index.html
<a href="/download">下载test.txt文件</a>
-
TestController
@GetMapping("/download") public void download(HttpServletResponse response) throws Exception { // 把文件以附件的形式返回 // 设置响应头 response.setHeader("Content-Disposition", "attachment; filename=test.txt"); // 读取文件 try (InputStream is = new ClassPathResource("static/txt/test.txt").getInputStream()) { // 将文件数据利用response写回到客户端 //IOUtils使用commons-io第三方框架 IOUtils.copy(is, response.getOutputStream()); } }
SringMVC-API的参数格式
-
控制器api如下:
@PostMapping("/test1") //本质等价于:public DataJsonVo<User> json(@RequestParam User user) //此时客户端传递到服务器的body参数格式为字段形式:id=0&name=jk public DataJsonVo<User> json(User user) { return new DataJsonVo<>(user); } @PostMapping("/test2") //此此时客户端传递到服务器的body参数格式为json数据,而不是一个字段一个字段的数据:{"id":10,"name":"jk"} // 客户端的Content-Type要设置为application/json,而且传递的格式必须是json格式 public DataJsonVo<User> json(@RequestBody User user) { return new DataJsonVo<>(user); }
-
总结:
@RequestParam
: 普通的请求参数- 前端不用做任何处理,客户端传递到服务器的body参数格式为字段形式:
id=0&name=jk
- 前端不用做任何处理,客户端传递到服务器的body参数格式为字段形式:
@RequestBody
:请求体- 客户端的Content-Type要设置为
application/json
- 而且传递的格式必须是json格式
{"id":10,"name":"jk"}
- 客户端的Content-Type要设置为
@RequestHeader("header-name")
: 请求头- 获取客户端传递过来的请求头
SpringBoot知识点总结
- springboot项目没有webapp文件夹,web资源放在了static文件夹,就是静态资源文件夹中即可
- 通常使用前后端分离分别部署,但是也可以将前端项目整合到springboot项目目录下一起部署,采用(springboot+Thymeleaf);样例