導(dǎo)航
[封裝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中常用注解
(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();
(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中常用注解
(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 標簽 )
- 告訴springboot這是一個 (
- @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 將組件注入類中使用
(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>
(四) 連接數(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
- 連接數(shù)據(jù)庫
-
下載到本地環(huán)境
-
連接,這里是遠程服務(wù)器
(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 類型
(4-5) xml方式 - 利用mybatis的xml方式操作數(shù)據(jù)庫 ( 重點 )
- 在大型項目中更推薦使用xml的方式显晶,更強大和靈活
- 第一步
- 在
resources
文件夾中新建mybatis
文件夾 - 在mybatis文件夾中新建
mybatis-config.xml
全局配置文件- mybatis/mybatis-config.xml
- mubatis官網(wǎng)教程
- 建議
<configuration>
所代表的配置在application.yml
中去配置
- 在mybatis文件夾中新建
mapper
文件夾贷岸,接著在里面創(chuàng)建musicMapper.xml
mapper的sql映射文件- mybatis/mapper/musicMapper.xml
- 里面寫 增刪改查的代碼
- 我之前的文章
- 在
- 第二步
- 在
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);
(五) 攔截器 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)資源
(六) 靜態(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";
}
}
(七) 文件上傳
(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";
}
}