SpringBoot 框架(上)

SpringBoot

  • SpringBoot
    • 概述
    • 依賴管理
    • 自動配置
    • SpringBoot 注解使用
      • @Configuration
      • @Import(value = {Cat.class,Dog.class})
      • @ImportResource(locations = "classpath:beans.xml")
    • yaml 標記語言
      • 概述
      • 基本語法
      • 數據類型
        • 字面量
        • 對象
        • 數組
      • 使用細節
    • Rest 風格請求處理
      • 概述
      • 注意事項
    • 接收參數注解
      • @CookieValue
    • 自定義轉換器
      • 概述
      • 創建自定義轉換器的步驟
      • 代碼實現
        • 前端提交的表單
        • 實體類 Car
        • 自定義轉換器
        • 注意
    • 內容協商
      • 概述
      • 示例
      • 注意
    • 服務器渲染技術 Thymeleaf
      • 概述
      • 基本語法
        • 表達式
        • 字面量
        • 文本操作
        • 運算符
        • th 屬性
        • 使用 th 屬性需要注意點
      • 綜合案例
        • 需求說明
        • 思路分析
        • 代碼實現
          • 1、配置 pom.xml 引入 thymeleaf-start
          • 2、轉發到登錄頁面 - IndexController
          • 3、登錄頁面 - login.html
          • 4、創建 model
          • 5、驗證用戶信息 - CheckUserController
          • 6、管理用戶頁面 - manage.html
    • 攔截器 Interceptor
      • 概述
      • 實現步驟
    • 文件上傳
      • 需求說明
      • 綜合案例
        • 單個文件上傳
          • 1、上傳文件頁面
          • 2、添加依賴
          • 3、編寫控制器
        • 多個文件上傳
          • 1、上傳文件頁面
          • 2、依賴如上
          • 3、編寫控制器方法
      • 注意事項


SpringBoot

大家好呀!我是小笙,我接下來繼續分享一些自己學習韓老師 Java課程的筆記,由于 SpringBoot 這部分內容較多,我分成二部分進行總結,以下是第一部分,希望內容對你有所幫助!

概述

SpringBoot 可以輕松創建獨立的、生產級的基于 Spring 的應用程序

SpringBoot 直接嵌入 Tomcat、Jetty 或者 Undertow,可以直接運行應用程序

約定優于配置理念

簡便來說就是你所期待的配置與約定的配置一致,那么就可以不做任何配置,約定不符合期待的時候,才需要對約定進行替換配置

依賴管理

自動依賴仲裁,即如果沒有指定某個依賴的版本號,則以父項目指定的版本號為準(就近原則)

修改版本仲裁的兩種方式如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.Al_tair</groupId><artifactId>springboot_lns</artifactId><version>1.0-SNAPSHOT</version><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.5.3</version></parent><dependencies><!--  Web 場景啟動器:會自動引入 Web 開發相關的依賴  --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--  1、直接指定 mysql 的版本  --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency></dependencies><!--  2、屬性里面指定對應key的版本號  --><properties><mysql.version>5.4.19</mysql.version></properties><!--  3、如果沒有指定mysql版本則以父項目的版本為準  -->
</project>

自動配置

掃描包:默認為執行的主程序所在的包及其子包下的所有文件都會被掃描

// 修改默認配置
@SpringBootApplication(scanBasePackages = {"",""})
public class MainApp {}

配置文件

image-20231116182532422

配置文件的讀取路徑以及配置文件名的默認值如下

image-20231116183052414

自定義配置

// 自定義類中獲取 application.properties 中的配置信息
class Test {@Value("${配置文件里的名稱}")private String properties
}

SpringBoot 注解使用

@Configuration

類似于 Spring 里面的 Bean 對象創建

@Configuration
public class BeanConfig {/*1、默認Bean對象的 name/id 為方法名 usero1如果想要設置 name/id,通過 @Bean(name = "")2、User: 為注入的類型3、默認為單例注入 @Scope("prototype") 設置為多實例注入*/@Beanpublic User usero1(){return new User(100,18,"lns","1079936@qq.com",1);}
}

@Import(value = {Cat.class,Dog.class})

注入 Bean 對象,value 值傳入的是 Bean對象的 Class 數組

@Import(value = {User.class})
@Configuration
public class BeanConfig {@Beanpublic User usero1(){return new User(100,18,"lns","1079936@qq.com",1);}
}

@ImportResource(locations = “classpath:beans.xml”)

將 Spring 框架中使用的 beans.xml 文件導入到 Java 配置文件里(指定 beans.xml 的類路徑)

@Configuration
@ImportResource(locations = "classpath:beans.xml")
public class BeanConfig {
}

yaml 標記語言

注意:格式很重要!!!

概述

一種以數據為中心,而不是以標記語言為重點的標記語言(適合用作配置文件 .yml .yam 后綴文件)

基本語法

  • 形式為 key: value (注意冒號后面有空格)

  • 區分大小寫

  • 使用縮進形式表示層級關系(注意縮進最好只用空格,相同層級的元素之間要對齊)

    User: Name: xxxSex: yyySchool: zzz
    
  • 字符串不需要加單/雙引號(加上也沒影響)

  • 注釋符號 #

數據類型

字面量

類似于 Java 里面的數據類型,是不可再分割的值

value 值的字面值為:date、boolean、string、number、null

對象

鍵值對的集合,如:map、hash、set、object

# 行內寫法 object
User: {Name: xxx,Sex: yyy,School: zzz}
# 換行形式 object    
User:   Name: xxx   Sex: yyy   School: zzz   
數組

一組按次序排列的值,如: array、list、queue

# 行內寫法 array
User: [v1,v2,v3]
# 換行形式 array    
k:   - v1  - v2  - v3  

使用細節

  1. application.properties 和 application.yml 有相同的前綴值綁定時候,application.properties 優先級較高

  2. 添加相關依賴可以是 application.yml 和 application.properties 有提示(只提示沒有填的數據)

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><!-- optional 為 true,防止將此依賴傳遞給其他模塊 --><optional>true</optional>
    </dependency>
    
  3. 實體類要對應 yml 文件的對象數據,需要添加注解 @ConfigurationProperties

    @ConfigurationProperties(prefix = "user")
    

Rest 風格請求處理

概述

請求方法:GET、POST、PUT、DELETE等等(如果需要請求為 PUT、DELETE,需要配置相關內容如下)

Rest 風格請求處理核心:HiddenHttpMethodFilter

  • 首先表單請求會被 HiddenHttpMethodFilter 攔截,獲取到表單里 _method 的值

  • 判斷是否是 PUT/DELETE/PATCH(PATCH 可以理解為是對PUT 方法的補充)來進行對應的跳轉

  • 配置文件 .yml 文件

    spring:mvc:hiddenmethod:filter:enabled: true # 開啟頁面表單的 Rest 功能
    

注意事項

  • 分析如下控制層方法為啥是返回字符串而不是對應的資源文件

    // 如果沒有配置如下的試圖解析器參數,則會默認查詢字符串下地址 /hello,如果還是沒有,則會在頁面上直接輸出字符串 hello
    @RestController
    public class HiController {@RequestMapping("/hi")public String hi() {return "hello";}
    }
    @RestController
    public class HiController {@RequestMapping("/hello")public String hi() {return "find it";}
    }
    
  • 需要添加配置文件

    # 需要注意靜態資源是否加前綴 static-path-pattern,prefix 需要與其保持一致性
    spring:mvc:static-path-pattern: /lns/** # 修改靜態資源訪問的路徑/前綴view:suffix: .htmlprefix: /lns
    

接收參數注解

@RequestMapping、@RequestHeader、@PathVariable等等已經在SprignMVC 中講解,接下來講一些其他的注解

@CookieValue

概述

@CookieValue是Spring框架中用于獲取HTTP請求中的Cookie值的注解

示例

使用@CookieValue注解將名為cookieKey的Cookie值綁定到方法參數cookieValue上。當客戶端發起GET請求到"/demo"路徑時,Spring會自動從請求中獲取名為cookieKey的Cookie的值,并將其作為字符串賦值給cookieValue參數

@GetMapping("/demo")
public String exampleMethod(@CookieValue("cookieKey") String cookieValue) {System.out.println(cookieValue);return "example";
}

注意:注解可以通過設置屬性 required 來控制請求參數 cookieKey 是否需要時必填的

@RequestAtrribute、@SessionAtrribute等相關注解用法類似

自定義轉換器

概述

自定義轉換器通常是指根據特定的需求編寫的一段代碼,用于將一種數據類型轉換為另一種數據類型。這種轉換器在多種情況下非常有用,比如數據遷移、系統整合、不同格式之間的數據交換等(SpringBoot在響應客戶端請求時,將提交的數據封裝成對象時,使用了內置的轉換器 )

底層 org.springframework.core.convert.converter 包下的類 ConvertiblePair

創建自定義轉換器的步驟

  1. 確定需要轉換的數據類型
  2. 設計轉換邏輯,處理任何可能出現的異常情況
  3. 編寫單元測試來驗證轉換器的正確性
  4. 在適當的地方使用或集成這個轉換器

代碼實現

要求:自定義轉換器用于將級聯對象通過一個字符串里包含多個參數定制化轉換成對象的實現形式

前端提交的表單
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>添加車</title>
</head>
<body>
<form action="/savemonster" method="post"><!-- 使用自定義轉換器關聯car(對應實體類), 使用,號間隔  -->交通工具:<input name="car" value="比亞迪秦,79888"><br/><input type="submit" value="提交"/>
</form>
</body>
</html>
實體類 Car
@Data
public class Car {private String name;private Double price;
}
自定義轉換器
/*** @Configuration(proxyBeanMethods = false)* 1. 表示 WebConfig 是一個配置類* 2. proxyBeanMethods = false 使用Lite模式*/
@Configuration(proxyBeanMethods = false)
public class WebConfig  {/*** 1. 在addFormatters 方法中,增加一個自定義的轉換器* 2. 增加自定義轉換器 String -> Car,會注冊到 converters 容器中*/@Beanpublic WebMvcConfigurer webMvcConfigurer() {return new WebMvcConfigurer() {@Overridepublic void addFormatters(FormatterRegistry registry) {// 使用匿名內部類的方式增加自定義轉換器registry.addConverter(new Converter<String, Car>() {// source就是 傳入的字符串 比亞迪秦,79888@Overridepublic Car convert(String source) {// 自定義的轉換業務代碼if (!ObjectUtils.isEmpty(source)) {Car car = new Car();String[] split = source.split(",");car.setName(split[0]);car.setPrice(Double.parseDouble(split[1]));return car;}return null;}});}};}
}
注意
  • converters 底層結構是 ConcurrentHashMap,key 為 源類型 —> 目標類型,如果添加相同的源類型以及目標類型的自定義轉換器,則會覆蓋前面的轉換器

  • 網頁默認返回 Json 格式數據底層也是轉換器進行轉換的,只需要控制層的方法上添加注解 @Responsebody,可以將目標方法返回的數據格式為 json 格式

    <!--  SpringBoot 中引入場景啟動器  spring-boot-starter-web,已經引入了 處理 Json 格式數據的 jar包Web 場景啟動器:會自動引入 Web 開發相關的依賴  
    -->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

內容協商

概述

內容協商在計算機科學領域通常指的是在互聯網通信中,服務端與客戶端之間就數據交換格式、語言或其他特性達成一致的過程,主要有類型協商(服務器根據客戶端發送的Accept頭部信息提供相應的數據格式,如JSON、XML或HTML等)、編碼協商(服務器根據客戶端的Accept-Encoding頭部提供壓縮或未壓縮的版本)等等,本節主要講解類型協商

示例

使用 Postman 發送 Http 請求,根據不同請求頭參數,返回對應的 json 或者 xml 數據

image-20240227125733835 image-20240227125805744

注意:返回 xml 數據需要下載相關依賴

<!-- 引入xml格式處理依賴 -->
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>

注意

  • 為啥沒下載 xml 處理依賴的時候默認是 Json 格式,而下載了依賴之后默認的是 xml 格式了呢?

    客戶端請求頭 Accept 會給出返回數據格式的權重,根據權重來解析,如下圖image-20240227183338483

  • 瀏覽器已經固定內容協商的類型,如果想要返回不同的格式,有解決方法嗎?

    • 配置 yml 文件

      spring:mvc:contentnegotiation:favor-parameter: true # 開啟基于請求參數的內容協商parameter-name: format # 指定接收參數名,默認是 format
      
    • 瀏覽器訪問的時候攜帶 ?format = json 或者 ?format = xml 來決定返回什么格式的數據

服務器渲染技術 Thymeleaf

概述

在線文檔

Thymeleaf 是一個用于 Web 和獨立環境的現代服務器端 Java 模板引擎。它能夠處理 HTML、XML、JavaScript、CSS 等多種類型的模板,并且能夠讓開發者在瀏覽器中直接查看模板的靜態原型,無需啟動服務器或構建整個應用程序(和 Velocity、FreeMarker 類似的模版引擎,可替代 JSP)

優點

  1. 瀏覽器兼容性:Thymeleaf 模板可以直接在瀏覽器中打開,無需服務器渲染,這對于前端開發者來說是一個很大的便利。
  2. 與 Spring Boot 的集成:Thymeleaf 與 Spring Boot 框架有很好的集成,Spring Boot 提供了自動配置,使得在 Spring 應用程序中使用 Thymeleaf 變得很簡單
  3. 豐富的表達式支持:Thymeleaf 支持豐富的表達式語法,包括文本、消息、鏈接、片段等,提供了強大的數據綁定能力

缺點

  1. 性能問題:Thymeleaf 在處理大型模板時可能會遇到性能瓶頸,特別是在模板中包含大量表達式和邏輯時
  2. XML/HTML 限制:Thymeleaf 模板必須符合 XML 或 HTML 規范,這可能會限制模板的靈活性,特別是在使用非標準化的 HTML 代碼時
  3. 與前端框架的集成:雖然 Thymeleaf 可以與前端框架(如 Angular、React 等)集成,但與純前端模板引擎(如 Handlebars、Mustache 等)相比,集成可能會更加復雜。
  4. 依賴 Spring:Thymeleaf 與 Spring 的緊密集成意味著在非 Spring 應用程序中使用它可能會更加困難

基本語法

表達式
表達式名字語法用途
變量取值${…}獲取請求域、session 域、對象等值
選擇變量*{…}獲取上下文對象值
消息#{…}獲取國際化等值
鏈接@{…}生成鏈接
片段表達式~{…}jsp:include 作用,引入公共頁面片段
字面量
  • 數字: 10 , 7 , 36.8 , …
  • 文本值: ‘hsp edu’ , ‘hello’ ,…
  • 布爾值: true , false
  • 空值: null
  • 變量: name,age,… (變量不能有空格)
文本操作
  • 字符串拼接: +
  • 變量替換: |age= ${age}|
運算符
  • 數學運算: + , - , * , / , %**
  • 布爾運算: and , or**
  • 一元運算: ! , not
  • 比較運算: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )**
  • 條件運算
    • If-then: (if) ? (then)
    • If-then-else: (if) ? (then) : (else)
    • Default: (value) ?: (default value)
th 屬性
  • th:text :設置當前元素的文本內容,相同功能的還有 th:utext,兩者的區別在于前者不會轉義 html 標簽,后者會。優先級不高:order=7
  • th:value:設置當前元素的 value 值,類似修改指定屬性的還有 th:src,th:href。優先級不高:order=6
  • th:each:遍歷循環元素,和 th:text 或 th:value 一起使用。注意該屬性修飾的標簽位置,詳細往后看。優先級很高:order=2
  • th:if:條件判斷,類似的還有 th:unless,th:switch,th:case。優先級較高:order=3
  • th:insert:代碼塊引入,類似的還有 th:replace,th:include,三者的區別較大,若使用不恰當會破壞 html 結構,常用于公共代碼塊提取的場景。優先級最高:order=1
  • th:fragment:定義代碼塊,方便被 th:insert 引用。優先級最低:order=8
  • th:object:聲明變量,一般和*{}一起配合使用,達到偷懶的效果。優先級一般:order=4
  • th:attr:修改任意屬性,實際開發中用的較少,因為有豐富的其他 th 屬性幫忙,類似的還有 th:attrappend,th:attrprepend。優先級一般:order=5
使用 th 屬性需要注意點
  • 若要使用 Thymeleaf 語法,首先要聲明名稱空間:xmlns:th=“http://www.thymeleaf.org”
  • 設置文本內容 th:text,設置 input 的值 th:value,循環輸出 th:each,條件判斷 th:if,插入代碼塊 th:insert,定義代碼塊 th:fragment,聲明變量 th:object
  • th:each 的用法需要格外注意,打個比方:如果你要循環一個 div 中的 p 標簽,則 th:each屬性必須放在 p 標簽上。若你將 th:each 屬性放在 div 上,則循環的是將整個 div
  • 變量表達式中提供了很多的內置方法,該內置方法是用#開頭,請不要與#{}消息表達式弄混

綜合案例

需求說明

實現簡單的用戶登錄頁面,登錄成功則跳轉到管理頁面,登錄失敗則提示錯誤信息(主要以實現 SpringBoot 引入 Thymeleaf 為主,不實現三層架構)

思路分析
image-20240228220403488
代碼實現
1、配置 pom.xml 引入 thymeleaf-start
<!--引入thymeleaf-start: 會進行默認配置-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

注意: thymeleaf 配置默認路徑在 templates 下后綴為 html 文件中

image-20240228220917497
2、轉發到登錄頁面 - IndexController
@Controller
public class IndexController {// 編寫方法,轉發到登錄頁面@GetMapping(value = {"/", "/login"})public String login() {/*** 直接使用視圖解析到 thymeleaf下的模板文件 login.html*/return "login";}
}
3、登錄頁面 - login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>login</title>
</head>
<body bgcolor="#CED3FE"><hr/><div style="text-align: center"><h1>用戶登陸</h1><form action="#" th:action="@{/login}"  method="post"><label style="color: red" th:text="${msg}"></label><br/>用戶名:<input type="text" style="width:150px" name="name"/><br/><br/>密 碼:<input type="password" style="width:150px" name="password"/><br/><br/><input type="submit" value="登錄"/><input type="reset" value="重新填寫"/></form></div><hr/>
</body>
</html>
4、創建 model
@Data
public class Admin {private String name;private String password;
}@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String name;private String password;private Integer age;private String email;
}
5、驗證用戶信息 - CheckUserController
@Controller
@Slf4j
public class CheckUserController {// 響應用戶的登錄請求@PostMapping("/login")public String login(Admin admin, HttpSession session, Model model) {// 驗證用戶是否合法(默認密碼為:admin)if (StringUtils.hasText(admin.getName()) && "admin".equals(admin.getPassword())) {// 將登錄用戶保存到sessionsession.setAttribute("loginAdmin", admin);// 驗證成功則重定向到 manage.html// 不使用請求轉發是防止刷新頁面會重復提交return "redirect:/manage.html";} else {// 驗證失敗則重新登錄, 請求轉發model.addAttribute("msg", "賬號/用戶密碼錯誤");return "login";}}// 處理用戶的請求 manage.html@GetMapping("/manage.html")public String managePage(Model model, HttpSession session) {Object loginAdmin = session.getAttribute("loginAdmin");if(null != loginAdmin) {//可以這里集合-模擬用戶數據, 放入到request域中,并顯示ArrayList<User> users = new ArrayList<>();users.add(new User(1, "關羽", "123", 43, "11@sohu.com"));users.add(new User(2, "張飛", "234", 54, "22@sohu.com"));users.add(new User(3, "趙云", "345", 43, "33@sohu.com"));users.add(new User(4, "馬超", "5645", 24, "44@sohu.com"));users.add(new User(5, "黃忠", "7657", 43, "55@sohu.com"));// 將數據放入到request域model.addAttribute("users", users);return "manage";} else {// 這里就返回登錄頁,并給出提示model.addAttribute("msg","你沒有登錄/請登錄");return "login";}}
}
6、管理用戶頁面 - manage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>管理后臺</title>
</head>
<body bgcolor="#CED3FE"><a href='#'>返回管理界面</a>  <a href='#' th:href="@{/}">安全退出</a>   歡迎您:[[${session.loginAdmin.name}]]<hr/><div style="text-align: center"><h1>管理用戶~</h1><table border="1px" cellspacing="0" bordercolor="green" style="width:800px;margin: auto"><tr bgcolor="pink"><td>id</td><td>name</td><td>pwd</td><td>email</td><td>age</td></tr><tr bgcolor="#ffc0cb" th:each="user:${users}"><td th:text="${user.id}">a</td><td th:text="${user.name}">b</td><td th:text="${user.password}">c</td><td th:text="${user.email}">d</td><td th:text="${user.age}">e</td></tr></table><br/></div><hr/>
</body>
</html>

攔截器 Interceptor

概述

在 Spring Boot 應用程序中,攔截器是一種 AOP(面向切面編程)工具,用于在處理 HTTP 請求和響應的過程中插入特定的邏輯。攔截器可以用于多種用途,例如日志記錄、權限校驗、請求驗證等

示意圖

image-20230110223137664

實現步驟

  1. 創建攔截器類:實現 HandlerInterceptor接口,并重寫其中的方法

    • preHandle():在請求處理之前進行調用(Controller 方法調用之前)
    • postHandle():在請求處理之后立即調用,但是在視圖被渲染之前(Controller 方法調用之后)
    • afterCompletion():在整個請求結束之后,也就是在視圖被渲染之后進行調用
    import org.springframework.web.servlet.HandlerInterceptor;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在請求處理之前進行調用(Controller方法調用之前)return true; // 返回 true 繼續執行,返回 false 則取消當前請求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在請求處理之后立即調用,但是在視圖被渲染之前(Controller方法調用之后)}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整個請求結束之后調用,也就是在DispatcherServlet渲染了對應的視圖之后執行(主要用于資源清理工作)}
    }
    
  2. 注冊攔截器:創建一個配置類,實現 WebMvcConfigurer 接口,并重寫 addInterceptors() 方法,以注冊攔截器

  3. 配置攔截規則:在 addInterceptors() 方法中,可以配置攔截器的攔截路徑和排除路徑

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
    public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**") // 表示攔截所有請求.excludePathPatterns("/","/login", "/static/**"); // 排除登錄和靜態資源}
    }
    

文件上傳

需求說明

實現簡單的單個文件上傳以及多個文件上傳的功能

綜合案例

單個文件上傳
1、上傳文件頁面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>File Upload</title>
</head>
<body><form method="POST" action="/upload" enctype="multipart/form-data"><input type="file" name="file" /><input type="submit" value="Upload" /></form>
</body>
</html>
2、添加依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
3、編寫控制器
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;@RestController
public class FileUploadController {@PostMapping("/upload")public String uploadFile(@RequestParam("file") MultipartFile file) {// 處理文件保存邏輯...return "File uploaded successfully";}
}
多個文件上傳
1、上傳文件頁面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>File Upload</title>
</head>
<body><form method="POST" action="/uploadMultiple" enctype="multipart/form-data"><input type="file" name="files" multiple /><input type="submit" value="Upload" /></form>
</body>
</html>
2、依賴如上
3、編寫控制器方法
@PostMapping("/uploadMultiple")
public String uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {// 處理多個文件保存邏輯for (MultipartFile file : files) {String fileName = file.getOriginalFilename();String filePath = "savePath/" + fileName;File dest = new File(filePath);try {file.transferTo(dest);} catch (IOException e) {log.info("多個文件上傳失敗!")}}// ...return "Files uploaded successfully";
}

注意事項

  • 處理異常情況,如文件大小限制、文件類型檢查等。在 Spring Boot 中,可以通過配置 application.propertiesapplication.yml 文件來設置文件上傳的相關屬性

    # 根據項目需求修改文件上傳的參數,否測文件上傳會拋出異常
    spring:servlet:multipart:max-file-size: 5MB # 單個文件大小,max-request-size: 50MB # 一次請求最大上傳大小(多個文件)
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713825.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713825.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713825.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue2 開發記錄

el-select 如何修改選擇項的樣式/el-select-dropdown__item 文字上下顯示 測試代碼 <div stylemargin-left: 100px><!-- 測試代碼--><el-select filterablesizemini><div classxxx-el-select><el-optionv-foritem in [{key:1,des:2,…

AVT Prosilica GC Vision Cameras 相機視覺說明使用安裝。具體詳情內容可參看PDF目錄內容。

AVT Prosilica GC Vision Cameras 相機視覺說明使用安裝。具體詳情內容可參看PDF目錄內容。

TikTok矩陣系統功能怎么寫?常用源代碼是什么?

TikTok矩陣系統的功能是如何編寫的?又有哪些常用的源代碼支撐這些功能呢?本文將通過五段源代碼的分享&#xff0c;為大家揭開TikTok矩陣系統的神秘面紗。 一、TikTok矩陣系統的核心功能 TikTok的矩陣系統涵蓋了多個核心功能&#xff0c;包括但不限于用戶管理、內容分發、推…

【接口測試】HTTP協議介紹

目錄 介紹 HTTP狀態碼 HTTP報文 請求方法 HTTP版本 HTTP標頭 通用標頭 請求標頭 響應標頭 get 編碼 post 編碼 RESTful風格 HTTPS 絕大多數的Web服務接口都是基于HTTP協議進行通信的&#xff0c;包括RESTful API和SOAP等。了解HTTP協議可以幫助測試人員理解接口的…

回溯算法題單???

力扣&#xff1a; 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 216. 組合總和 III - 力扣&#xff08;LeetCode&#xff09; LCR 080. 組合 - 力扣&#xff08;LeetCode&#xff09; LCR 082. 組合總和 II - 力扣&#xff08;LeetCode&#xff09; LCR 083. 全排列…

【多線程】CAS詳解

目錄 &#x1f334;什么是 CAS&#x1f338;CAS 偽代碼 &#x1f38d;CAS 是怎么實現的&#x1f340;CAS 有哪些應?&#x1f338;實現原子類&#x1f338;實現自旋鎖 &#x1f333;CAS 的 ABA 問題&#x1f338;**什么是 ABA 問題**&#xff1f;&#x1f338;ABA 問題引來的 B…

【C++】核心編程--函數高級

文章目錄 1. 函數的默認參數2. 函數占位參數3. 函數重載4. 注意事項 1. 函數的默認參數 在C中&#xff0c;函數的形參列表中的形參是可以有默認值的 //語法&#xff1a; 返回值類型 函數名 (參數 默認值){} #include<iostream> using namespace std; //函數默認參數 //如…

異常值檢測-3σ法提交 代碼注釋

背景信息里面都給了相應的答案&#xff0c;但我們可以多了解一下代碼的含義&#xff0c;而不是簡單的復制粘貼 import pandas as pd import matplotlib.pyplot as plt from scipy import stats import numpy as npdata pd.read_csv("src/death.csv", index_colUnna…

ASPICE實操中的那點事兒-如何避免重復性測試

寫在前面 ASPICE理解起來容易&#xff0c;畢竟是有條有理的。但實操起來&#xff0c;尤其是把ASPICE各過程域做全的時候&#xff0c;會遇到各種各樣的問題&#xff08;不是技術問題有多難&#xff0c;而是該如何做選擇&#xff0c;如何既能符合ASPICE要求&#xff0c;保證過程質…

智慧城市建設的新里程碑:公共服務電子支付大屏

隨著科技的飛速發展&#xff0c;我們的生活正在經歷前所未有的變革。電子支付的出現&#xff0c;無疑是這場變革中的一大亮點&#xff0c;它不僅改變了我們日常的支付方式&#xff0c;更成為智慧城市建設的重要一環&#xff0c;為公眾提供了更加便捷、高效的服務體驗。 在以前&…

python SHP2COCO

1. 將shp的標簽數據轉成coco # -*- coding: utf-8 -*- import os, json import cv2 from osgeo import gdal import numpy as np from osgeo import ogr, gdal, osr from shapely.geometry import box, shape from shapely.geometry.polygon import Polygon import collection…

Flutter 的狀態管理

狀態提升&#xff08;Lifting-state-up&#xff09; 把子組件的狀態&#xff0c;提升到上級組件中&#xff0c;從而實現在多個組件之間共享和同步數據的效果 以 flutter counter demo&#xff0c;那個按按鈕1 的來說&#xff0c;現在的 count 是幾&#xff0c;不是存在頁面顯…

政府采購標書制作的要點解析

導語&#xff1a;政府采購是政府為滿足公共利益&#xff0c;按照法定程序和標準&#xff0c;通過招標、競爭性談判等方式&#xff0c;購買商品、工程和服務的行為。標書作為政府采購活動中的重要文件&#xff0c;其制作質量直接影響到項目的順利進行。本文將圍繞政府采購標書制…

二路歸并排序的算法設計和復雜度分析and周記

數據結構實驗報告 實驗目的: 通過本次實驗&#xff0c;了解算法復雜度的分析方法&#xff0c;掌握遞歸算法時間復雜度的遞推計算過程。 實驗內容&#xff1a; 二路歸并排序的算法設計和復雜度分析 實驗過程&#xff1a; 1.算法設計 第一步&#xff0c;首先要將數組進行…

【網站項目】314學生二手書籍交易平臺

&#x1f64a;作者簡介&#xff1a;擁有多年開發工作經驗&#xff0c;分享技術代碼幫助學生學習&#xff0c;獨立完成自己的項目或者畢業設計。 代碼可以私聊博主獲取。&#x1f339;贈送計算機畢業設計600個選題excel文件&#xff0c;幫助大學選題。贈送開題報告模板&#xff…

關于游戲公司組織架構的小討論

過完年剛剛上班沒幾天&#xff0c;就有一件比較搞笑的事情&#xff0c;可以和大家分享一下。 ??某一天我們在公司的會議室開會&#xff0c;發現有非常多蚊子&#xff0c;于是找行政問能不能找專業人士來滅蚊。行政的答復是&#xff0c;專業滅蚊是有固定時間的&#xff0c;還要…

JVM相關面試題(2024大廠高頻面試題系列)

一、JVM的組成 1、JVM由哪些部分組成&#xff0c;運行流程是什么&#xff1f; 回答&#xff1a;在JVM中共有四大部分&#xff0c;分別是Class Loader&#xff08;類加載器&#xff09;、Runtime Data Area&#xff08;運行時數據區&#xff0c;內存分區&#xff09;、Execut…

MyBatis的補充用法

說明&#xff1a;之前介紹過MyBatis的用法&#xff0c;像 用注解和Mapper.xml操作數據庫、在Mapper.xml里寫動態SQL。最近在一次用MyBatis批量更新數據庫對象的場景中&#xff0c;意識到對MyBatis的一些標簽用法不太熟悉&#xff0c;所以去 MyBatis官網 看了一些文檔&#xff0…

php httpfs鏈接hdfs

一.代碼&#xff08;有bug&#xff09; GitHub - michaelbutler/php-WebHDFS: A PHP client for WebHDFS 二.調用代碼 1.代碼1.代碼 require_once(../webhdfs/src/org/apache/hadoop/WebHDFS.php);require_once(../webhdfs/src/org/apache/hadoop/tools/Curl.php); require_o…

什么是人才儲備?如何做人才儲備?

很多小伙伴都會有企業面試被拒的情況&#xff0c;然后HR會告訴你&#xff0c;雖然沒有錄用你&#xff0c;但是你進入了他們的人才儲備庫&#xff0c;那么這個儲備庫有什么作用和特點呢&#xff1f;我們如何應用人才測評系統完善人才儲備庫呢&#xff1f; 人才儲備一般有以下三…