[前端學(xué)java08-SpringBoot實戰(zhàn)總結(jié)1-7] 階段性總結(jié)

導(dǎo)航

[react] Hooks

[封裝01-設(shè)計模式] 設(shè)計原則 和 工廠模式(簡單抽象方法) 適配器模式 裝飾器模式
[封裝02-設(shè)計模式] 命令模式 享元模式 組合模式 代理模式

[React 從零實踐01-后臺] 代碼分割
[React 從零實踐02-后臺] 權(quán)限控制
[React 從零實踐03-后臺] 自定義hooks
[React 從零實踐04-后臺] docker-compose 部署react+egg+nginx+mysql
[React 從零實踐05-后臺] Gitlab-CI使用Docker自動化部署

[源碼-webpack01-前置知識] AST抽象語法樹
[源碼-webpack02-前置知識] Tapable
[源碼-webpack03] 手寫webpack - compiler簡單編譯流程
[源碼] Redux React-Redux01
[源碼] axios
[源碼] vuex
[源碼-vue01] data響應(yīng)式 和 初始化渲染
[源碼-vue02] computed 響應(yīng)式 - 初始化朝群,訪問庄萎,更新過程
[源碼-vue03] watch 偵聽屬性 - 初始化和更新
[源碼-vue04] Vue.set 和 vm.$set
[源碼-vue05] Vue.extend

[源碼-vue06] Vue.nextTick 和 vm.$nextTick
[部署01] Nginx
[部署02] Docker 部署vue項目
[部署03] gitlab-CI

[數(shù)據(jù)結(jié)構(gòu)和算法01] 二分查找和排序

[深入01] 執(zhí)行上下文
[深入02] 原型鏈
[深入03] 繼承
[深入04] 事件循環(huán)
[深入05] 柯里化 偏函數(shù) 函數(shù)記憶
[深入06] 隱式轉(zhuǎn)換 和 運算符
[深入07] 瀏覽器緩存機制(http緩存機制)
[深入08] 前端安全
[深入09] 深淺拷貝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模塊化
[深入13] 觀察者模式 發(fā)布訂閱模式 雙向數(shù)據(jù)綁定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手寫Promise
[深入20] 手寫函數(shù)
[深入21] 數(shù)據(jù)結(jié)構(gòu)和算法 - 二分查找和排序
[深入22] js和v8垃圾回收機制
[深入23] JS設(shè)計模式 - 代理噪珊,策略贿肩,單例

[前端學(xué)java01-SpringBoot實戰(zhàn)] 環(huán)境配置和HelloWorld服務(wù)
[前端學(xué)java02-SpringBoot實戰(zhàn)] mybatis + mysql 實現(xiàn)歌曲增刪改查
[前端學(xué)java03-SpringBoot實戰(zhàn)] lombok古程,日志搭独,部署
[前端學(xué)java04-SpringBoot實戰(zhàn)] 靜態(tài)資源 + 攔截器 + 前后端文件上傳
[前端學(xué)java05-SpringBoot實戰(zhàn)] 常用注解 + redis實現(xiàn)統(tǒng)計功能
[前端學(xué)java06-SpringBoot實戰(zhàn)] 注入 + Swagger2 3.0 + 單元測試JUnit5
[前端學(xué)java07-SpringBoot實戰(zhàn)] IOC掃描器 + 事務(wù) + Jackson
[前端學(xué)java08-SpringBoot實戰(zhàn)總結(jié)1-7] 階段性總結(jié)

(一) 前置知識

(1) 一些單詞

fragment 片段
drawer 抽屜

library 資源庫
premium 昂貴的 溢價 // navicat permium 支持多種數(shù)據(jù)庫

rainbow 彩虹
bracket 括號
rainbow bracket 彩虹括號

wired 連線
auto wired 自動連接 // @Autowired
conditional 條件的 // @Conditional

override 復(fù)寫
preference 偏好
distinct 清晰的 不同的

exception 異常

(2) mac版idea快捷鍵

1. 全局查找
command + shift + r

2. 調(diào)出actions
command + 3

3. 設(shè)置
command + ,

4. 文件間的跳轉(zhuǎn)
command + e

5. 信息提示
command + 1

6. 跳轉(zhuǎn)到別的類
control + 鼠標左鍵

7. 復(fù)制文件的引用路徑
鼠標右鍵 - copy path - copy reference

8. 左右移動代碼塊
- 左移動 shift + tab
- 右移動 tab

9. 查找文件
- ctrl + h

(3) 一些常用的服務(wù)器應(yīng)用端口號

mysql ----------------------- 3306
nginx ----------------------- 80

(4) idea中出現(xiàn)端口被占用

lsof -i tcp:7890 
kill PID

// 7890表示被占用的端口號

(二) 常用注解

(1) lombok中常用注解

image.png

(1.1) lombok 的添加和使用

  • bean dto model 等對象中使用
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
</dependency>

(1.2) @Data

  • @Data包含了以下注解
    • @Getter/@Setter
    • @ToString
    • @EqualsAndHashCode
    • @RequiredArgsConstructor 特定參數(shù)的構(gòu)造器悼凑,特定參數(shù)是指加上了 final 修飾符的變量

(1.3) @Value

  • 只有g(shù)etter,其他的和@Data一樣苦囱,會把所有的變量都設(shè)成 final 的
  • @Getter
  • @ToString
  • @EqualsAndHashCode
  • @RequiredArgsConstructor 特定參數(shù)的構(gòu)造器,特定參數(shù)是指加上了 final 修飾符的變量

(1.4) @Builder

  • @Builder 自動生成 ( 流式set值 ) 寫法沿后,不需要寫一堆setter
  • @Builder 十分有用的一個注解
  • 注意:通常情況下 @Data 和 @Builder 會一起使用沿彭,因為還是必須寫getter/setter
@Data
@Builder
public class FirstBean {
    private String name;
    private Integer age;
    private String sex;
}

-----------------------

FirstBean firstBean = FirstBean.builder()
                .name(name)
                .age(age)
                .sex(sex)
                .build();
image.png
image.png

(1.5) @Slf4j

  • @Slf4j 自動生成該類的 log 靜態(tài)常量,所以不需要sout了
log.info("傳入的參數(shù)變量{}", name);
// {} 就是占位符尖滚,表示后面的變量name

(1.6) @NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor

  • @NoArgsConstructor 無參構(gòu)造器
  • @AllArgsConstructor 全參構(gòu)造器
  • @RequiredArgsConstructor 特定參數(shù)構(gòu)造器

(2) mybatis中常用注解

image.png

(3) controller 中常用注解

(3.1) @RestController 和 @Controller + @ResponseBody

  • @RestController
    • @RestController = @Controller + @ResponseBody
    • @RestController 不能返回html頁面喉刘,返回的內(nèi)容就是return的內(nèi)容
    • 如果一個controller,一些頁面要返回html漆弄,一些又要返回return的內(nèi)容睦裳,就需要用 @Controller注解controller返回html,然后在要返回的return的方法上加上@ResponseBody來返回return后面的內(nèi)容
  • @ResponseBody作用于類的方法上撼唾,@RestController和@Controller作用于類上
// @RestController = @Controller + @ResponseBody

@Controller --------------------------------- 1
@Slf4j
public class FirstController {
    @RequestMapping(value = "/music/{name}", method = {RequestMethod.GET})
    @ResponseBody --------------------------- 2
    public String getMusic(
            @PathVariable("name") String name,
            @RequestParam("age") Integer age,
            @RequestParam("sex") String sex
    ) {
        System.out.println(name);
        log.info("傳入的參數(shù)變量2{}", name);
        FirstBean firstBean = FirstBean.builder()
                .name(name)
                .age(age)
                .sex(sex)
                .build();
        System.out.println(firstBean);
        return "good246";
    }
}

(3.2) @GetMapping @PostMapping @PutMapping @DeleteMapping

  • @GetMapping
@GetMapping("/music/{name}")
相當(dāng)于
@RequestMapping(value="/music/{name}", method = {RequestMethod.GET})
  • CRUD 分別是 create read update delete 的縮寫

(3.3) @RequestParam 和 @PathVariable ------ get delete 請求

  • 有這樣一段url地址:www.baidu.com/music/周杰倫?age=20&sex=man
  • @PathVariable
    • 可以獲取到path的動態(tài)參數(shù)部分
    • "/music/{name}" 中的name即"周杰倫"
    • @PathVariable("name") String name
  • @RequestParam
    • 可以獲取到age和sex
    • @RequestParam("age") Integer age

(3.4) @RequestBody 和 @RequestHeader ------ post put 請求

    @PostMapping("/music")
    public MusicBean addMusic(
            @RequestBody MusicBean musicBean,
            @RequestHeader("Content-Type") String contentType
    ) {
        log.info("musicBean:{}", musicBean);
        log.info("Content-Type:{}", contentType);
        return musicBean;
    }

(3-5) @RequestPart

  • @RequestPart 主要用在 multipart/form-data 表單提交請求的方法上
  • 支持的請求方式是:MultipartFile廉邑,屬于Spring的MultipartResolver類熬甫,通過http協(xié)議傳輸
  • 注意:前端上傳組件的name="aaa"置鼻,是和java中的 @RequestPart("aaa") 對應(yīng)的
  • 結(jié)合下面上傳的例子

(4) 容器相關(guān)的注解

(4.1) @Configuration + @Bean 向容器中添加組件

  • @Configuration 配置類
    • 告訴springboot這是一個 ( 配置類 )
    • @Configuration 標注的 ( 配置類本身也是一個組件 )
    • @Configuration(proxyBeanMethods = true)
      • proxyBeanMethods代理bean的方法分苇,默認true
      • 當(dāng) ( proxyBeanMethods=true ) 時筏勒,外部無論對配置類中的組建注冊方法調(diào)用多少次,獲取的都是之前注冊到容器中的 ( 單實例對象 )
      • proxyBeanMethods=true 解決組件依賴問題
      • proxyBeanMethods=false 會跳過檢查缰揪,提升速度
    • 可以理解為 xml 中的 ( beans 標簽 )
  • @Bean 向容器中添加組件
    • ( @Bean ) 用來 ( 向容器中添加組件 )痪蝇,并且添加的組件是 ( 單實例 ) 的
    • @Bean 是標注在類的方法上的
    • 可以理解為 xml 中的 ( bean 標簽 )
  • 流程
    • @Configuration + @Bean + @Autowired
    • 1.注冊:@Configuration + @Bean 向容器中注入組件
    • 2.使用:@Autowired 將組件注入類中使用
/**
 * 1. @Configuration 標注的類就是 配置類
 * 2弱卡。配置類里抖格,使用 @Bean 標注在方法上給容器注冊組件诺苹,注冊的組件默認也是單實例的
 * 3. 注意:@Configuration標注的類,該類本身也是一個組件雹拄,即 UserConfig 也是一個組件收奔,即 ( 配置類本身也是一個組件 )
 *
 * 4. proxyBeanMethods 代理bean的方法,默認值是true
 *    Full(proxyBeanMethods = true) 單例滓玖,可以用于 ( 組件依賴 )
 *    Lite(proxyBeanMethods = false)
 */
// 告訴 SpringBoot 這是一個 ( 配置類 )坪哄,等用于以前的配置文件
// @Configuration 配置類
@Configuration(proxyBeanMethods = true)
public class UserConfig {
    // @Bean
    // @Bean 給容器中添加組件
    // 1. 以方法名作為組件的id => user1
    // 2. 返回類型就是組件類型 => UserBean
    // 3. 返回的值就是組件在容器中的實例 => new UserBean()
    // @Bean("userX") 的參數(shù)可以自定義id
    @Bean("userX")
    public UserBean user01() {
        return new UserBean("woow_wu7", 20);
    }
}

(4.2) @Autowired 和 @Resource 和 new

  • @Autowired
    • @Autowired是自動裝配的意思,wired連接势篡,auto wired自動連接
    • @Autowired ( 按類型裝配 ) ( 單例 ) ( 在程序啟動時創(chuàng)建 )
  • @Resource
  • @Autowired 和 new 的區(qū)別
    • @Autowired:是由spring創(chuàng)建的對象损姜,( 單例 ),( 作用域是整個項目 )殊霞,項目已啟動就創(chuàng)建了
    • new: 是手動生成實例對象,( 多例 )汰蓉,每次調(diào)用生成都都是新的對象
  • 流程
    • @Configuration + @Bean + @Autowired
    • 1.注冊:@Configuration + @Bean 向容器中注入組件
    • 2.使用:@Autowired 將組件注入類中使用
      image.png

(4.3) @Import 和 @Bean

  • @Import作用在類上绷蹲,可以是配置類,容器中的類比如Controller Service 等
  • @Import向容器中添加組件,作用和@Bea類似
  • @Configuration + @Bean 一般一起使用

(三) 熱更新

  • 1.引入 spring-boot-devtools 包
  • 2.setting => Build,Execution,Deployment => Compiler => 勾上Build project automaticallly
  • 3.command + 3 調(diào)出 actions祝钢,然后搜索 Registry
  • 4.勾選 compiler.autoMake.allow.when.app.running
<!-- spring-boot-devtools 熱更新 -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <optional>true</optional>
  <scope>true</scope>
</dependency>
image.png

image.png

image.png

(四) 連接數(shù)據(jù)庫實現(xiàn)crud

  • 重點掌握mybatis的xml配置方式
  • 當(dāng)添加比规,刪除,更新時拦英,返回值是一個Integer類型蜒什,1表示成功,0表示失敗
  • 可以在入口類中配置 @MapperScan 這樣就不用在每一個Interface加@Mapper了

(4-1) 安裝mysql數(shù)據(jù)庫到服務(wù)器疤估,并通過 navicat premium 連接數(shù)據(jù)庫

  • mac安裝-免費的社區(qū)版本-最底部-MySQL Community Server
  • windows版本mysql安裝教程
  • mysql常用命令教程
  • mysql常用命令 ( 可以直接通過navicat進行操作 )
    • 連接數(shù)據(jù)庫 mysql -h主機地址 -u用戶名 -p用戶密碼
    • 連接數(shù)據(jù)庫 mysql -h 120.53.220.141 -u root -p
    • 退出 exit
    • 查看數(shù)據(jù)庫 show databases;
    • 創(chuàng)建數(shù)據(jù)庫 create database 數(shù)據(jù)庫名;
    • 刪除數(shù)據(jù)庫 drop database 數(shù)據(jù)庫名;
    • 使用數(shù)據(jù)庫 use 數(shù)據(jù)庫名;
    • 查看當(dāng)前使用的數(shù)據(jù)庫 select database();
    • 查看表 show tables;
    • 創(chuàng)建表 create table 表名 (dde列名 類型);
    • 刪除表 droop table 表名;
    • 顯示表結(jié)構(gòu) desc 表名;
    • 修改密碼 mysqladmin -uroot -p123456 password 12345678;
    • 修改密碼 -p12345是當(dāng)前的數(shù)據(jù)庫密碼灾常,password是將要設(shè)置的數(shù)據(jù)庫密碼
    • 查看數(shù)據(jù)庫的安裝路徑 show variables like "%char%";
    • 查看mysql的版本:
      • 1.如果已經(jīng)連接了數(shù)據(jù)庫,使用命令 select version();
      • 2.如果未連接數(shù)據(jù)庫:cmd铃拇,切換至mysql的bin目錄钞瀑,運行 mysql -V
  • 下載到本地環(huán)境


    image.png
  • 連接,這里是遠程服務(wù)器


    image.png

(4-2) 添加必須的maven依賴

  • 需要 mysql-connector-java
  • 需要 spring-boot-starter-jdbc
  • 需要 mybatis-spring-boot-starter

<!-- mysql依賴 -->
<!-- mysql, 版本需要和你安裝的mysql版本保持一致 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.24</version>
</dependency>


<!-- jdbc依賴 -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.4.5</version>
</dependency>


<!-- mybatis依賴 -->
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

(4-3) 在 application.properties 中配置數(shù)據(jù)源組件配置項

application.properties
-------

# 定義數(shù)據(jù)源組件
# 已棄用 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 注意 spring.datasource.url="jdbc:mysql://localhost:3306/數(shù)據(jù)庫名稱?時區(qū)信息"
# 注意 上面的時區(qū)信息不能少慷荔,不然會報錯
# 分別是 ( 數(shù)據(jù)庫url ) ( 數(shù)據(jù)庫驅(qū)動 ) ( 用戶名 ) ( 密碼 )
spring.datasource.url=jdbc:mysql://localhost:3306/7-community-java?serverTimezone=GMT%2B8&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root

(4-4) 注解方式 - 利用mybatis注解的方式操作數(shù)據(jù)庫

  • 遇到的坑
    • 入口主類的名稱一定要正確雕什,不然回報 server中找不到mapper依賴的錯誤
    • mapper文件中的類型,記得選 interface 類型


      image.png

(4-5) xml方式 - 利用mybatis的xml方式操作數(shù)據(jù)庫 ( 重點 )

  • 在大型項目中更推薦使用xml的方式显晶,更強大和靈活
  • 第一步
    • resources 文件夾中新建 mybatis 文件夾
    • 在mybatis文件夾中新建 mybatis-config.xml 全局配置文件
    • 在mybatis文件夾中新建 mapper 文件夾贷岸,接著在里面創(chuàng)建 musicMapper.xml mapper的sql映射文件
  • 第二步
    • resources.yml 中配置mybatis的 全局配置文件mapper的sql映射文件,即制定mybatis的全局配置文件位置和sql映射文件位置
      • config-location: classpath:mybatis/mybatis-config.xml # mybatis全局配置文件
      • mapper-locations: classpath:mybatis/mapper/*.xml # mybatis的sql映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.MusicMapper">
    <!-- namespace 就是 mapper 文件夾中對應(yīng)的 Mapper 文件  -->

    <!-- public abstract List<MusicBean> getMusic(); -->
    <!-- id 是方法名 -->
    <!-- resultType 是方法的返回值類型磷雇,通過 copy path => copy reference 可以快速生成 -->
    <select id="getAllMusic" resultType="com.example.demo.bean.MusicBean">
        select * from music
    </select>

    <select id="getMusic" resultType="com.example.demo.bean.MusicBean">
        SELECT * FROM music
        WHERE
            name=#{name}
    </select>

    <insert id="addMusic" parameterType="com.example.demo.bean.MusicBean">
        insert into music
        (name, singer)
        values
        (#{name}, #{singer})
    </insert>

    <delete id="deleteMusic" parameterType="Integer">
        delete from music
        where
        id=#{id}
    </delete>

    <update id="updateMusic" parameterType="Map">
        update music
        set name=#{musicBean.name}, singer=#{musicBean.singer}
        where id=#{id}
    </update>

</mapper>
mapper


 public List<MusicBean> getAllMusic();

 public MusicBean getMusic(Integer id, String name);

 public Integer addMusic(MusicBean musicBean);

 Integer deleteMusic(Integer id);

 Integer updateMusic(Integer id, MusicBean musicBean);
image.png

(五) 攔截器 HandlerInterceptor

  • HandlerInterceptor
    • preHandle 在目標方法執(zhí)行 ( 前 ) 執(zhí)行偿警,即在 controller 中的目標方法執(zhí)行前執(zhí)行
    • postHandle 在目標方法執(zhí)行 ( 完成后 ) 執(zhí)行
    • afterCompletion 在 ( 頁面渲染后 ) 執(zhí)行
  • 我之前的文章-攔截器

(5-1) 攔截器實現(xiàn)的具體過程

  • interceptor
    • 1.新建interceptor文件夾,然后新建 MusicInterceptor.java 文件
    • 2.public class MusicInterceptor implements HandlerInterceptor
    • 3.新建 preHandler等方法倦春,在里面寫攔截邏輯户敬,return true放行,return false表示攔截
  • config
    • 1.新建一個config文件夾睁本,然后新建一個實現(xiàn)類尿庐,AdminWebConfig.java 文件
    • 2.public class AdminWebConfig implements WebMvcConfigurer
    • 3.registry.addInterceptor(new MusicInterceptor())
    • 4..addPathPatterns("/**") // 攔截 => 攔截所有請求,包括靜態(tài)資源
    • 5..excludePathPatterns("css/**") // 放行呢堰,放行了static文件夾下的css靜態(tài)資源
image.png

(六) 靜態(tài)資源

  • resources/static
  • resources/public
  • resources/MATA-INF/resources
  • resources/resources
  • 以上四個文件夾中的文件就屬于靜態(tài)資源抄瑟,通過訪問 跟路徑/靜態(tài)資源名稱 即可
package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestStaticResources {

    // 靜態(tài)資源

    // 1
    // - resources/static
    // - resources/public
    // - resources/MATA-INF/resources
    // - resources/resources
    // - 以上四個文件夾中的文件就屬于靜態(tài)資源,通過訪問 `跟路徑/靜態(tài)資源名稱` 即可

    // 2
    // 原理:靜態(tài)映射 /**
    // 請求進來枉疼,先去 ( controller ) 中看能不能處理皮假,如果不能處理再交給 ( 靜態(tài)資源處理器去處理靜態(tài)資源 )

    // 3
    // 問題:如果controller中有一個接口/mm.jpg,而我們的靜態(tài)資源文件夾中同樣有一個靜態(tài)資源叫mm.jpg骂维,會發(fā)生什么惹资?
    // 答案:會優(yōu)先處理controller中的類,而不會去訪問靜態(tài)資源

    // 4
    // 靜態(tài)資源前綴
    // 靜態(tài)資源設(shè)置前綴:spring.mvc.static-path-pattern=/resources/**
    // 訪問靜態(tài)資源:當(dāng)前項目 + 前綴 + 靜態(tài)資源
    // 例子:http://localhost:7777/resources/66.jpg

    // 5
    // 指定自定義的靜態(tài)資源目錄 ( 默認靜態(tài)文件夾路徑 )
    // spring.web.resources.static-locations=[classpath:/7resources/]
    @GetMapping("/mm.jpg")
    public String getStaticResources() {
        return "string, is not static resource mm.jpg";
    }
}
image.png

(七) 文件上傳

(7.1) 添加 spring-boot-start-thymeleaf maven依賴

  • spring-boot-start-thymeleaf 的主要作用是用來返回 html
<!-- spring-boot-starter-thymeleaf -->
<!-- 主要用于顯示resources/templates中的html -->
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

(7.2) 在 resources/templates/ 文件夾中新建 fileUpload.html

<!DOCTYPE html>
<!--注意:xmls:th 的值-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div>測試頁面</div>
<!-- th:action="@{/upload}" 提交的controller對應(yīng)的path -->
<!-- enctype="multipart/form-data" -->
<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <div>
        <span>單頭像上傳</span>
        <input type="file" name="single">
    </div>
    <div>
        <span>多頭像上傳</span>
        <!-- multiple表示開啟多個上傳 -->
        <input type="file" name="multiple" multiple>
    </div>
    <button type="submit">上傳</button>
</form>
</body>
</html>

(7.3) 新建controller

@Controller
@Slf4j
public class FileUploadController {

    @GetMapping("/fileUpload")
    public String handleFile() {
        return "fileUpload";
    }

    @PostMapping("/upload")
    public String upload(
            @RequestPart("single") MultipartFile single
    ) throws IOException {
        if (!single.isEmpty()) {
            String originalFilename = single.getOriginalFilename(); // 獲取原始文件名
            log.info("{}", originalFilename);
        }
        return "fileUpload";
    }
}
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末航闺,一起剝皮案震驚了整個濱河市褪测,隨后出現(xiàn)的幾起案子猴誊,更是在濱河造成了極大的恐慌,老刑警劉巖侮措,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懈叹,死亡現(xiàn)場離奇詭異,居然都是意外死亡分扎,警方通過查閱死者的電腦和手機澄成,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畏吓,“玉大人墨状,你說我怎么就攤上這事♀钟叮” “怎么了歉胶?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巴粪。 經(jīng)常有香客問我通今,道長,這世上最難降的妖魔是什么肛根? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任辫塌,我火速辦了婚禮,結(jié)果婚禮上派哲,老公的妹妹穿的比我還像新娘臼氨。我一直安慰自己,他們只是感情好芭届,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布储矩。 她就那樣靜靜地躺著,像睡著了一般褂乍。 火紅的嫁衣襯著肌膚如雪持隧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天逃片,我揣著相機與錄音屡拨,去河邊找鬼。 笑死褥实,一個胖子當(dāng)著我的面吹牛呀狼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播损离,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼哥艇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了僻澎?” 一聲冷哼從身側(cè)響起她奥,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤瓮增,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后哩俭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拳恋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年凡资,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谬运。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡隙赁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梆暖,到底是詐尸還是另有隱情伞访,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布轰驳,位于F島的核電站厚掷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏级解。R本人自食惡果不足惜冒黑,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勤哗。 院中可真熱鬧抡爹,春花似錦、人聲如沸芒划。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽民逼。三九已至泵殴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缴挖,已是汗流浹背袋狞。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留映屋,地道東北人苟鸯。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像棚点,于是被迫代替她去往敵國和親早处。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容