JavaWeb——011 SpringBootWeb綜合案例(刪除/修改員工、文件上傳、配置文件)

SpringBootWeb案例

目錄

  • SpringBootWeb案例
    • 1. 新增員工
      • 1.1 需求
      • 1.2 接口文檔
      • 1.3 思路分析
      • 1.4 功能開發
      • 1.5 功能測試
      • 1.6 前后端聯調
    • 2. 文件上傳
      • 2.1 簡介
      • 2.2 本地存儲
      • 2.3 阿里云OSS
        • 2.3.1 準備
        • 2.3.2 入門
        • 2.3.3 集成
    • 3. 修改員工
      • 3.1 查詢回顯
        • 3.1.1 接口文檔
        • 3.1.2 實現思路
        • 3.1.3 代碼實現
        • 3.1.4 postman測試
      • 3.2 修改員工
        • 3.2.1 接口文檔
        • 3.2.2 實現思路
        • 3.2.3 代碼實現
        • 3.2.4 postman測試
        • 3.2.5 前后端聯調測試
    • 4. 配置文件
      • 4.1 參數配置化
      • 4.2 yml配置文件
      • 4.3 @ConfigurationProperties

1. 新增員工

1.1 需求

在這里插入圖片描述

在新增用戶時,我們需要保存用戶的基本信息,并且還需要上傳的員工的圖片,目前我們先完成第一步操作,保存用戶的基本信息。

1.2 接口文檔

我們參照接口文檔來開發新增員工功能

  • 基本信息

    請求路徑:/emps請求方式:POST接口描述:該接口用于添加員工的信息
    
  • 請求參數

    參數格式:application/json

    參數說明:

    名稱類型是否必須備注
    usernamestring必須用戶名
    namestring必須姓名
    gendernumber必須性別, 說明: 1 男, 2 女
    imagestring非必須圖像
    deptIdnumber非必須部門id
    entrydatestring非必須入職日期
    jobnumber非必須職位, 說明: 1 班主任,2 講師, 3 學工主管, 4 教研主管, 5 咨詢師

    請求數據樣例:

    {"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg","username": "linpingzhi","name": "林平之","gender": 1,"job": 1,"entrydate": "2022-09-18","deptId": 1
    }
    
  • 響應數據

    參數格式:application/json

    參數說明:

    參數名類型是否必須備注
    codenumber必須響應碼,1 代表成功,0 代表失敗
    msgstring非必須提示信息
    dataobject非必須返回的數據

    響應數據樣例:

    {"code":1,"msg":"success","data":null
    }
    

1.3 思路分析

新增員工的具體的流程:

在這里插入圖片描述

接口文檔規定:

  • 請求路徑:/emps
  • 請求方式:POST
  • 請求參數:Json格式數據
  • 響應數據:Json格式數據

問題1:如何限定請求方式是POST?

@PostMapping

問題2:怎么在controller中接收json格式的請求參數?

@RequestBody  //把前端傳遞的json數據填充到實體類中

1.4 功能開發

EmpController

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {@Autowiredprivate EmpService empService;//新增@PostMappingpublic Result save(@RequestBody Emp emp){//記錄日志log.info("新增員工, emp:{}",emp);//調用業務層新增功能empService.save(emp);//響應return Result.success();}//省略...
}

EmpService

public interface EmpService {/*** 保存員工信息* @param emp*/void save(Emp emp);//省略...
}

EmpServiceImpl

@Slf4j
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic void save(Emp emp) {//補全數據emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());//調用添加方法empMapper.insert(emp);}//省略...
}

EmpMapper

@Mapper
public interface EmpMapper {//新增員工@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +"values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime});")void insert(Emp emp);//省略...
}

1.5 功能測試

代碼開發完成后,重啟服務器,打開Postman發送 POST 請求,請求路徑:http://localhost:8080/emps

在這里插入圖片描述

1.6 前后端聯調

功能測試通過后,我們再進行通過打開瀏覽器,測試后端功能接口:

在這里插入圖片描述

在這里插入圖片描述

2. 文件上傳

在我們完成的新增員工功能中,還存在一個問題:沒有頭像(圖片缺失)

在這里插入圖片描述

上述問題,需要我們通過文件上傳技術來解決。下面我們就進入到文件上傳技術的學習。

文件上傳技術這塊我們主要講解三個方面:首先我們先對文件上傳做一個整體的介紹,接著再學習文件上傳的本地存儲方式,最后學習云存儲方式。

接下來我們就先來學習下什么是文件上傳。

2.1 簡介

文件上傳,是指將本地圖片、視頻、音頻等文件上傳到服務器,供其他用戶瀏覽或下載的過程。

文件上傳在項目中應用非常廣泛,我們經常發微博、發微信朋友圈都用到了文件上傳功能。

在這里插入圖片描述

在我們的案例中,在新增員工的時候,要上傳員工的頭像,此時就會涉及到文件上傳的功能。在進行文件上傳時,我們點擊加號或者是點擊圖片,就可以選擇手機或者是電腦本地的圖片文件了。當我們選擇了某一個圖片文件之后,這個文件就會上傳到服務器,從而完成文件上傳的操作。

想要完成文件上傳這個功能需要涉及到兩個部分:

  1. 前端程序
  2. 服務端程序

我們先來看看在前端程序中要完成哪些代碼:

<form action="/upload" method="post" enctype="multipart/form-data">姓名: <input type="text" name="username"><br>年齡: <input type="text" name="age"><br>頭像: <input type="file" name="image"><br><input type="submit" value="提交">
</form>

上傳文件的原始form表單,要求表單必須具備以下三點(上傳文件頁面三要素):

  • 表單必須有file域,用于選擇要上傳的文件

    <input type="file" name="image"/>
    
  • 表單提交方式必須為POST

    通常上傳的文件會比較大,所以需要使用 POST 提交方式

  • 表單的編碼類型enctype必須要設置為:multipart/form-data

    普通默認的編碼格式是不適合傳輸大型的二進制數據的,所以在文件上傳時,表單的編碼格式必須設置為multipart/form-data

前端頁面的3要素我們了解后,接下來我們就來驗證下所講解的文件上傳3要素。

在提供的"課程資料"中有一個名叫"文件上傳"的文件夾,直接將里的"upload.html"文件,復制到springboot項目工程下的static目錄里面。

在這里插入圖片描述

下面我們來驗證:刪除form表單中enctype屬性值,會是什么情況?

  1. 在IDEA中直接使用瀏覽器打開upload.html頁面

在這里插入圖片描述

  1. 選擇要上傳的本地文件

在這里插入圖片描述

  1. 點擊"提交"按鈕,進入到開發者模式觀察

在這里插入圖片描述

在這里插入圖片描述

我們再來驗證:設置form表單中enctype屬性值為multipart/form-data,會是什么情況?

 <form action="/upload" method="post" enctype="multipart/form-data">姓名: <input type="text" name="username"><br>年齡: <input type="text" name="age"><br>頭像: <input type="file" name="image"><br><input type="submit" value="提交"></form>

在這里插入圖片描述

在這里插入圖片描述

知道了前端程序中需要設置上傳文件頁面三要素,那我們的后端程序又是如何實現的呢?

  • 首先在服務端定義這么一個controller,用來進行文件上傳,然后在controller當中定義一個方法來處理/upload 請求

  • 在定義的方法中接收提交過來的數據 (方法中的形參名和請求參數的名字保持一致)

    • 用戶名:String name
    • 年齡: Integer age
    • 文件: MultipartFile image

    Spring中提供了一個API:MultipartFile,使用這個API就可以來接收到上傳的文件

在這里插入圖片描述

問題:如果表單項的名字和方法中形參名不一致,該怎么辦?

  • public Result upload(String username,Integer age, MultipartFile file) //file形參名和請求參數名image不一致
    

解決:使用@RequestParam注解進行參數綁定

  • public Result upload(String username,Integer age, @RequestParam("image") MultipartFile file)
    

UploadController代碼:

@Slf4j
@RestController
public class UploadController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image)  {log.info("文件上傳:{},{},{}",username,age,image);return Result.success();}}

后端程序編寫完成之后,打個斷點,以debug方式啟動SpringBoot項目

在這里插入圖片描述

打開瀏覽器輸入:http://localhost:8080/upload.html , 錄入數據并提交

在這里插入圖片描述

通過后端程序控制臺可以看到,上傳的文件是存放在一個臨時目錄

在這里插入圖片描述

打開臨時目錄可以看到以下內容:

在這里插入圖片描述

表單提交的三項數據(姓名、年齡、文件),分別存儲在不同的臨時文件中:

在這里插入圖片描述

當我們程序運行完畢之后,這個臨時文件會自動刪除。

所以,我們如果想要實現文件上傳,需要將這個臨時文件,要轉存到我們的磁盤目錄中。

2.2 本地存儲

前面我們已分析了文件上傳功能前端和后端的基礎代碼實現,文件上傳時在服務端會產生一個臨時文件,請求響應完成之后,這個臨時文件被自動刪除,并沒有進行保存。下面呢,我們就需要完成將上傳的文件保存在服務器的本地磁盤上。

代碼實現:

  1. 在服務器本地磁盤上創建images目錄,用來存儲上傳的文件(例:E盤創建images目錄)
  2. 使用MultipartFile類提供的API方法,把臨時文件轉存到本地磁盤目錄下

MultipartFile 常見方法:

  • String getOriginalFilename(); //獲取原始文件名
  • void transferTo(File dest); //將接收的文件轉存到磁盤文件中
  • long getSize(); //獲取文件的大小,單位:字節
  • byte[] getBytes(); //獲取文件內容的字節數組
  • InputStream getInputStream(); //獲取接收到的文件內容的輸入流
@Slf4j
@RestController
public class UploadController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image) throws IOException {log.info("文件上傳:{},{},{}",username,age,image);//獲取原始文件名String originalFilename = image.getOriginalFilename();//將文件存儲在服務器的磁盤目錄image.transferTo(new File("E:/images/"+originalFilename));return Result.success();}}

利用postman測試:

注意:請求參數名和controller方法形參名保持一致

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

通過postman測試,我們發現文件上傳是沒有問題的。但是由于我們是使用原始文件名作為所上傳文件的存儲名字,當我們再次上傳一個名為1.jpg文件時,發現會把之前已經上傳成功的文件覆蓋掉。

解決方案:保證每次上傳文件時文件名都唯一的(使用UUID獲取隨機文件名)

@Slf4j
@RestController
public class UploadController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image) throws IOException {log.info("文件上傳:{},{},{}",username,age,image);//獲取原始文件名String originalFilename = image.getOriginalFilename();//構建新的文件名String extname = originalFilename.substring(originalFilename.lastIndexOf("."));//文件擴展名String newFileName = UUID.randomUUID().toString()+extname;//隨機名+文件擴展名//將文件存儲在服務器的磁盤目錄image.transferTo(new File("E:/images/"+newFileName));return Result.success();}}

在解決了文件名唯一性的問題后,我們再次上傳一個較大的文件(超出1M)時發現,后端程序報錯:

在這里插入圖片描述

報錯原因呢是因為:在SpringBoot中,文件上傳時默認單個文件最大大小為1M

那么如果需要上傳大文件,可以在application.properties進行如下配置:

#配置單個文件最大上傳大小
spring.servlet.multipart.max-file-size=10MB#配置單個請求最大上傳大小(一次請求可以上傳多個文件)
spring.servlet.multipart.max-request-size=100MB

到時此,我們文件上傳的本地存儲方式已完成了。但是這種本地存儲方式還存在一問題:

在這里插入圖片描述

如果直接存儲在服務器的磁盤目錄中,存在以下缺點:

  • 不安全:磁盤如果損壞,所有的文件就會丟失
  • 容量有限:如果存儲大量的圖片,磁盤空間有限(磁盤不可能無限制擴容)
  • 無法直接訪問

為了解決上述問題呢,通常有兩種解決方案:

  • 自己搭建存儲服務器,如:fastDFS 、MinIO
  • 使用現成的云服務,如:阿里云,騰訊云,華為云

2.3 阿里云OSS

2.3.1 準備

阿里云是阿里巴巴集團旗下全球領先的云計算公司,也是國內最大的云服務提供商 。

在這里插入圖片描述

云服務指的就是通過互聯網對外提供的各種各樣的服務,比如像:語音服務、短信服務、郵件服務、視頻直播服務、文字識別服務、對象存儲服務等等。

當我們在項目開發時需要用到某個或某些服務,就不需要自己來開發了,可以直接使用阿里云提供好的這些現成服務就可以了。比如:在項目開發當中,我們要實現一個短信發送的功能,如果我們項目組自己實現,將會非常繁瑣,因為你需要和各個運營商進行對接。而此時阿里云完成了和三大運營商對接,并對外提供了一個短信服務。我們項目組只需要調用阿里云提供的短信服務,就可以很方便的來發送短信了。這樣就降低了我們項目的開發難度,同時也提高了項目的開發效率。(大白話:別人幫我們實現好了功能,我們只要調用即可)

云服務提供商給我們提供的軟件服務通常是需要收取一部分費用的。

阿里云對象存儲OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存儲服務。使用OSS,您可以通過網絡隨時存儲和調用包括文本、圖片、音頻和視頻等在內的各種文件。

在這里插入圖片描述

在我們使用了阿里云OSS對象存儲服務之后,我們的項目當中如果涉及到文件上傳這樣的業務,在前端進行文件上傳并請求到服務端時,在服務器本地磁盤當中就不需要再來存儲文件了。我們直接將接收到的文件上傳到oss,由 oss幫我們存儲和管理,同時阿里云的oss存儲服務還保障了我們所存儲內容的安全可靠。

在這里插入圖片描述

那我們學習使用這類云服務,我們主要學習什么呢?其實我們主要學習的是如何在項目當中來使用云服務完成具體的業務功能。而無論使用什么樣的云服務,阿里云也好,騰訊云、華為云也罷,在使用第三方的服務時,操作的思路都是一樣的。

在這里插入圖片描述

SDK:Software Development Kit 的縮寫,軟件開發工具包,包括輔助軟件開發的依賴(jar包)、代碼示例等,都可以叫做SDK。

簡單說,sdk中包含了我們使用第三方云服務時所需要的依賴,以及一些示例代碼。我們可以參照sdk所提供的示例代碼就可以完成入門程序。

第三方服務使用的通用思路,我們做一個簡單介紹之后,接下來我們就來介紹一下我們當前要使用的阿里云oss對象存儲服務具體的使用步驟。

在這里插入圖片描述

Bucket:存儲空間是用戶用于存儲對象(Object,就是文件)的容器,所有的對象都必須隸屬于某個存儲空間。

下面我們根據之前介紹的使用步驟,完成準備工作:

  1. 注冊阿里云賬戶(注冊完成后需要實名認證)
  2. 注冊完賬號之后,就可以登錄阿里云

在這里插入圖片描述

  1. 通過控制臺找到對象存儲OSS服務

在這里插入圖片描述

如果是第一次訪問,還需要開通對象存儲服務OSS

在這里插入圖片描述

在這里插入圖片描述

  1. 開通OSS服務之后,就可以進入到阿里云對象存儲的控制臺

在這里插入圖片描述

  1. 點擊左側的 “Bucket列表”,創建一個Bucket

在這里插入圖片描述

在這里插入圖片描述

大家可以參照"資料\04. 阿里云oss"中提供的文檔,開通阿里云OSS服務。

2.3.2 入門

阿里云oss 對象存儲服務的準備工作我們已經完成了,接下來我們就來完成第二步操作:參照官方所提供的sdk示例來編寫入門程序。

首先我們需要來打開阿里云OSS的官方文檔,在官方文檔中找到 SDK 的示例代碼:

在這里插入圖片描述

在這里插入圖片描述

如果是在實際開發當中,我們是需要從前往后仔細的去閱讀這一份文檔的,但是由于現在是教學,我們就只挑重點的去看。有興趣的同學大家下來也可以自己去看一下這份官方文檔。

在這里插入圖片描述

在這里插入圖片描述

參照官方提供的SDK,改造一下,即可實現文件上傳功能:

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;import java.io.FileInputStream;
import java.io.InputStream;public class AliOssTest {public static void main(String[] args) throws Exception {// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。String endpoint = "oss-cn-shanghai.aliyuncs.com";// 阿里云賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建并使用RAM用戶進行API訪問或日常運維,請登錄RAM控制臺創建RAM用戶。String accessKeyId = "LTAI5t9MZK8iq5T2Av5GLDxX";String accessKeySecret = "C0IrHzKZGKqU8S7YQcevcotD3Zd5Tc";// 填寫Bucket名稱,例如examplebucket。String bucketName = "web-framework01";// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。String objectName = "1.jpg";// 填寫本地文件的完整路徑,例如D:\\localpath\\examplefile.txt。// 如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件流。String filePath= "C:\\Users\\Administrator\\Pictures\\1.jpg";// 創建OSSClient實例。OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);try {InputStream inputStream = new FileInputStream(filePath);// 創建PutObjectRequest對象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);// 設置該屬性可以返回response。如果不設置,則返回的response為空。putObjectRequest.setProcess("true");// 創建PutObject請求。PutObjectResult result = ossClient.putObject(putObjectRequest);// 如果上傳成功,則返回200。System.out.println(result.getResponse().getStatusCode());} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}
}

在以上代碼中,需要替換的內容為:

  • accessKeyId:阿里云賬號AccessKey
  • accessKeySecret:阿里云賬號AccessKey對應的秘鑰
  • bucketName:Bucket名稱
  • objectName:對象名稱,在Bucket中存儲的對象的名稱
  • filePath:文件路徑

AccessKey :

在這里插入圖片描述

運行以上程序后,會把本地的文件上傳到阿里云OSS服務器上:

在這里插入圖片描述

2.3.3 集成

阿里云oss對象存儲服務的準備工作以及入門程序我們都已經完成了,接下來我們就需要在案例當中集成oss對象存儲服務,來存儲和管理案例中上傳的圖片。

在這里插入圖片描述

在新增員工的時候,上傳員工的圖像,而之所以需要上傳員工的圖像,是因為將來我們需要在系統頁面當中訪問并展示員工的圖像。而要想完成這個操作,需要做兩件事:

  1. 需要上傳員工的圖像,并把圖像保存起來(存儲到阿里云OSS)
  2. 訪問員工圖像(通過圖像在阿里云OSS的存儲地址訪問圖像)
    • OSS中的每一個文件都會分配一個訪問的url,通過這個url就可以訪問到存儲在阿里云上的圖片。所以需要把url返回給前端,這樣前端就可以通過url獲取到圖像。

我們參照接口文檔來開發文件上傳功能:

  • 基本信息

    請求路徑:/upload請求方式:POST接口描述:上傳圖片接口
    
  • 請求參數

    參數格式:multipart/form-data

    參數說明:

    參數名稱參數類型是否必須示例備注
    imagefile
  • 響應數據

    參數格式:application/json

    參數說明:

    參數名類型是否必須備注
    codenumber必須響應碼,1 代表成功,0 代表失敗
    msgstring非必須提示信息
    dataobject非必須返回的數據,上傳圖片的訪問路徑

    響應數據樣例:

    {"code": 1,"msg": "success","data": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-0400.jpg"
    }
    

引入阿里云OSS上傳文件工具類(由官方的示例代碼改造而來)

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;@Component
public class AliOSSUtils {private String endpoint = "https://oss-cn-shanghai.aliyuncs.com";private String accessKeyId = "LTAI5t9MZK8iq5T2Av5GLDxX";private String accessKeySecret = "C0IrHzKZGKqU8S7YQcevcotD3Zd5Tc";private String bucketName = "web-framework01";/*** 實現上傳圖片到OSS*/public String upload(MultipartFile multipartFile) throws IOException {// 獲取上傳的文件的輸入流InputStream inputStream = multipartFile.getInputStream();// 避免文件覆蓋String originalFilename = multipartFile.getOriginalFilename();String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));//上傳文件到 OSSOSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);ossClient.putObject(bucketName, fileName, inputStream);//文件訪問路徑String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;// 關閉ossClientossClient.shutdown();return url;// 把上傳到oss的路徑返回}
}

修改UploadController代碼:

import com.itheima.pojo.Result;
import com.itheima.utils.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;@Slf4j
@RestController
public class UploadController {@Autowiredprivate AliOSSUtils aliOSSUtils;@PostMapping("/upload")public Result upload(MultipartFile image) throws IOException {//調用阿里云OSS工具類,將上傳上來的文件存入阿里云String url = aliOSSUtils.upload(image);//將圖片上傳完成后的url返回,用于瀏覽器回顯展示return Result.success(url);}}

使用postman測試:

在這里插入圖片描述

3. 修改員工

需求:修改員工信息

在這里插入圖片描述

在這里插入圖片描述

在進行修改員工信息的時候,我們首先先要根據員工的ID查詢員工的信息用于頁面回顯展示,然后用戶修改員工數據之后,點擊保存按鈕,就可以將修改的數據提交到服務端,保存到數據庫。 具體操作為:

  1. 根據ID查詢員工信息
  2. 保存修改的員工信息

3.1 查詢回顯

3.1.1 接口文檔

根據ID查詢員工數據

  • 基本信息

    請求路徑:/emps/{id}請求方式:GET接口描述:該接口用于根據主鍵ID查詢員工的信息
    
  • 請求參數

    參數格式:路徑參數

    參數說明:

    參數名類型是否必須備注
    idnumber必須員工ID

    請求參數樣例:

    /emps/1
    
  • 響應數據

    參數格式:application/json

    參數說明:

    名稱類型是否必須默認值備注
    codenumber必須響應碼, 1 成功 , 0 失敗
    msgstring非必須提示信息
    dataobject必須返回的數據
    |- idnumber非必須id
    |- usernamestring非必須用戶名
    |- namestring非必須姓名
    |- passwordstring非必須密碼
    |- entrydatestring非必須入職日期
    |- gendernumber非必須性別 , 1 男 ; 2 女
    |- imagestring非必須圖像
    |- jobnumber非必須職位, 說明: 1 班主任,2 講師, 3 學工主管, 4 教研主管, 5 咨詢師
    |- deptIdnumber非必須部門id
    |- createTimestring非必須創建時間
    |- updateTimestring非必須更新時間

    響應數據樣例:

    {"code": 1,"msg": "success","data": {"id": 2,"username": "zhangwuji","password": "123456","name": "張無忌","gender": 1,"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg","job": 2,"entrydate": "2015-01-01","deptId": 2,"createTime": "2022-09-01T23:06:30","updateTime": "2022-09-02T00:29:04"}
    }
    
3.1.2 實現思路

在這里插入圖片描述

3.1.3 代碼實現
  • EmpMapper
@Mapper
public interface EmpMapper {//根據ID查詢員工信息@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time " +"from emp " +"where id = #{id}")public Emp findById(Integer id);//省略...
}
  • EmpService
public interface EmpService {/*** 根據ID查詢員工* @param id* @return*/public Emp getById(Integer id);//省略...
}
  • EmpServiceImpl
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic Emp getById(Integer id) {return empMapper.findById(id);}//省略...
}
  • EmpController
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {@Autowiredprivate EmpService empService;//根據id查詢@GetMapping("/{id}")public Result getById(@PathVariable Integer id){Emp emp = empService.getById(id);return Result.success(emp);}//省略...
}
3.1.4 postman測試

在這里插入圖片描述

3.2 修改員工

在這里插入圖片描述

當用戶修改完數據之后,點擊保存按鈕,就需要將數據提交到服務端,然后服務端需要將修改后的數據更新到數據庫中。

3.2.1 接口文檔
  • 基本信息

    請求路徑:/emps請求方式:PUT接口描述:該接口用于修改員工的數據信息
    
  • 請求參數

    參數格式:application/json

    參數說明:

    名稱類型是否必須備注
    idnumber必須id
    usernamestring必須用戶名
    namestring必須姓名
    gendernumber必須性別, 說明: 1 男, 2 女
    imagestring非必須圖像
    deptIdnumber非必須部門id
    entrydatestring非必須入職日期
    jobnumber非必須職位, 說明: 1 班主任,2 講師, 3 學工主管, 4 教研主管, 5 咨詢師

    請求數據樣例:

    {"id": 1,"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg","username": "linpingzhi","name": "林平之","gender": 1,"job": 1,"entrydate": "2022-09-18","deptId": 1
    }
    
  • 響應數據

    參數格式:application/json

    參數說明:

    參數名類型是否必須備注
    codenumber必須響應碼,1 代表成功,0 代表失敗
    msgstring非必須提示信息
    dataobject非必須返回的數據

    響應數據樣例:

    {"code":1,"msg":"success","data":null
    }
    
3.2.2 實現思路

在這里插入圖片描述

3.2.3 代碼實現
  • EmpMapper
@Mapper
public interface EmpMapper {//修改員工信息public void update(Emp emp);//省略...
}
  • EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper"><!--更新員工信息--><update id="update">update emp<set><if test="username != null and username != ''">username = #{username},</if><if test="password != null and password != ''">password = #{password},</if><if test="name != null and name != ''">name = #{name},</if><if test="gender != null">gender = #{gender},</if><if test="image != null and image != ''">image = #{image},</if><if test="job != null">job = #{job},</if><if test="entrydate != null">entrydate = #{entrydate},</if><if test="deptId != null">dept_id = #{deptId},</if><if test="updateTime != null">update_time = #{updateTime}</if></set>where id = #{id}</update><!-- 省略... --></mapper>
  • EmpService
public interface EmpService {/*** 更新員工* @param emp*/public void update(Emp emp);//省略...
}
  • EmpServiceImpl
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic void update(Emp emp) {emp.setUpdateTime(LocalDateTime.now()); //更新修改時間為當前時間empMapper.update(emp);}//省略...
}
  • EmpController
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {@Autowiredprivate EmpService empService;//修改員工@PutMappingpublic Result update(@RequestBody Emp emp){empService.update(emp);return Result.success();}//省略...
}
3.2.4 postman測試

在這里插入圖片描述

3.2.5 前后端聯調測試

在這里插入圖片描述

4. 配置文件

員工管理的增刪改查功能我們已開發完成,但在我們所開發的程序中還一些小問題,下面我們就來分析一下當前案例中存在的問題以及如何優化解決。

4.1 參數配置化

在這里插入圖片描述

在我們之前編寫的程序中進行文件上傳時,需要調用AliOSSUtils工具類,將文件上傳到阿里云OSS對象存儲服務當中。而在調用工具類進行文件上傳時,需要一些參數:

  • endpoint //阿里云OSS域名
  • accessKeyID //用戶身份ID
  • accessKeySecret //用戶密鑰
  • bucketName //存儲空間的名字

關于以上的這些阿里云相關配置信息,我們是直接寫死在java代碼中了(硬編碼),如果我們在做項目時每涉及到一個第三方技術服務,就將其參數硬編碼,那么在Java程序中會存在兩個問題:

  1. 如果這些參數發生變化了,就必須在源程序代碼中改動這些參數,然后需要重新進行代碼的編譯,將Java代碼編譯成class字節碼文件再重新運行程序。(比較繁瑣)
  2. 如果我們開發的是一個真實的企業級項目, Java類可能會有很多,如果將這些參數分散的定義在各個Java類當中,我們要修改一個參數值,我們就需要在眾多的Java代碼當中來定位到對應的位置,再來修改參數,修改完畢之后再重新編譯再運行。(參數配置過于分散,是不方便集中的管理和維護)

為了解決以上分析的問題,我們可以將參數配置在配置文件中。如下:

#自定義的阿里云OSS配置信息
aliyun.oss.endpoint=https://oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId=LTAI4GCH1vX6DKqJWxd6nEuW
aliyun.oss.accessKeySecret=yBshYweHOpqDuhCArrVHwIiBKpyqSL
aliyun.oss.bucketName=web-tlias

在將阿里云OSS配置參數交給properties配置文件來管理之后,我們的AliOSSUtils工具類就變為以下形式:

@Component
public class AliOSSUtils {/*以下4個參數沒有指定值(默認值:null)*/private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;//省略其他代碼...
}

而此時如果直接調用AliOSSUtils類當中的upload方法進行文件上傳時,這4項參數全部為null,原因是因為并沒有給它賦值。

此時我們是不是需要將配置文件當中所配置的屬性值讀取出來,并分別賦值給AliOSSUtils工具類當中的各個屬性呢?那應該怎么做呢?

因為application.properties是springboot項目默認的配置文件,所以springboot程序在啟動時會默認讀取application.properties配置文件,而我們可以使用一個現成的注解:@Value,獲取配置文件中的數據。

@Value 注解通常用于外部配置的屬性注入,具體用法為: @Value(“${配置文件中的key}”)

@Component
public class AliOSSUtils {@Value("${aliyun.oss.endpoint}")private String endpoint;@Value("${aliyun.oss.accessKeyId}")private String accessKeyId;@Value("${aliyun.oss.accessKeySecret}")private String accessKeySecret;@Value("${aliyun.oss.bucketName}")private String bucketName;//省略其他代碼...}   

在這里插入圖片描述

使用postman測試:

在這里插入圖片描述

4.2 yml配置文件

前面我們一直使用springboot項目創建完畢后自帶的application.properties進行屬性的配置,那其實呢,在springboot項目當中是支持多種配置方式的,除了支持properties配置文件以外,還支持另外一種類型的配置文件,就是我們接下來要講解的yml格式的配置文件。

  • application.properties

    server.port=8080
    server.address=127.0.0.1
    
  • application.yml

    server:port: 8080address: 127.0.0.1
    
  • application.yaml

    server:port: 8080address: 127.0.0.1
    

yml 格式的配置文件,后綴名有兩種:

  • yml (推薦)
  • yaml

常見配置文件格式對比:

在這里插入圖片描述

我們可以看到配置同樣的數據信息,yml格式的數據有以下特點:

  • 容易閱讀
  • 容易與腳本語言交互
  • 以數據為核心,重數據輕格式

簡單的了解過springboot所支持的配置文件,以及不同類型配置文件之間的優缺點之后,接下來我們就來了解下yml配置文件的基本語法:

  • 大小寫敏感
  • 數值前邊必須有空格,作為分隔符
  • 使用縮進表示層級關系,縮進時,不允許使用Tab鍵,只能用空格(idea中會自動將Tab轉換為空格)
  • 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
  • #表示注釋,從這個字符一直到行尾,都會被解析器忽略

在這里插入圖片描述

了解完yml格式配置文件的基本語法之后,接下來我們再來看下yml文件中常見的數據格式。在這里我們主要介紹最為常見的兩類:

  1. 定義對象或Map集合
  2. 定義數組、list或set集合

對象/Map集合

user:name: zhangsanage: 18password: 123456

數組/List/Set集合

hobby: - java- game- sport

熟悉完了yml文件的基本語法后,我們修改下之前案例中使用的配置文件,變更為application.yml配置方式:

  1. 修改application.properties名字為:_application.properties(名字隨便更換,只要加載不到即可)
  2. 創建新的配置文件: application.yml

原有application.properties文件:

在這里插入圖片描述

新建的application.yml文件:

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tliasusername: rootpassword: 1234servlet:multipart:max-file-size: 10MBmax-request-size: 100MBmybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: truealiyun:oss:endpoint: https://oss-cn-hangzhou.aliyuncs.comaccessKeyId: LTAI4GCH1vX6DKqJWxd6nEuWaccessKeySecret: yBshYweHOpqDuhCArrVHwIiBKpyqSLbucketName: web-397

4.3 @ConfigurationProperties

講解完了yml配置文件之后,最后再來介紹一個注解@ConfigurationProperties。在介紹注解之前,我們先來看一個場景,分析下代碼當中可能存在的問題:

在這里插入圖片描述

我們在application.properties或者application.yml中配置了阿里云OSS的四項參數之后,如果java程序中需要這四項參數數據,我們直接通過@Value注解來進行注入。這種方式本身沒有什么問題問題,但是如果說需要注入的屬性較多(例:需要20多個參數數據),我們寫起來就會比較繁瑣。

那么有沒有一種方式可以簡化這些配置參數的注入呢?答案是肯定有,在Spring中給我們提供了一種簡化方式,可以直接將配置文件中配置項的值自動的注入到對象的屬性中。

Spring提供的簡化方式套路:

  1. 需要創建一個實現類,且實體類中的屬性名和配置文件當中key的名字必須要一致

    比如:配置文件當中叫endpoints,實體類當中的屬性也得叫endpoints,另外實體類當中的屬性還需要提供 getter / setter方法

  2. 需要將實體類交給Spring的IOC容器管理,成為IOC容器當中的bean對象

  3. 在實體類上添加@ConfigurationProperties注解,并通過perfect屬性來指定配置參數項的前綴

在這里插入圖片描述

實體類:AliOSSProperties

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*阿里云OSS相關配置*/
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {//區域private String endpoint;//身份IDprivate String accessKeyId ;//身份密鑰private String accessKeySecret ;//存儲空間private String bucketName;
}

AliOSSUtils工具類:

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;@Component //當前類對象由Spring創建和管理
public class AliOSSUtils {//注入配置參數實體類對象@Autowiredprivate AliOSSProperties aliOSSProperties;/*** 實現上傳圖片到OSS*/public String upload(MultipartFile multipartFile) throws IOException {// 獲取上傳的文件的輸入流InputStream inputStream = multipartFile.getInputStream();// 避免文件覆蓋String originalFilename = multipartFile.getOriginalFilename();String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));//上傳文件到 OSSOSS ossClient = new OSSClientBuilder().build(aliOSSProperties.getEndpoint(),aliOSSProperties.getAccessKeyId(), aliOSSProperties.getAccessKeySecret());ossClient.putObject(aliOSSProperties.getBucketName(), fileName, inputStream);//文件訪問路徑String url =aliOSSProperties.getEndpoint().split("//")[0] + "//" + aliOSSProperties.getBucketName() + "." + aliOSSProperties.getEndpoint().split("//")[1] + "/" + fileName;// 關閉ossClientossClient.shutdown();return url;// 把上傳到oss的路徑返回}
}

在我們添加上注解后,會發現idea窗口上面出現一個紅色警告:
idea2023.3.3沒有出現該報錯
在這里插入圖片描述

這個警告提示是告知我們還需要引入一個依賴:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

當我們在pom.xml文件當中配置了這項依賴之后,我們重新啟動服務,大家就會看到在properties或者是yml配置文件當中,就會提示阿里云 OSS 相關的配置項。所以這項依賴它的作用就是會自動的識別被@Configuration Properties注解標識的bean對象。

剛才的紅色警告,已經變成了一個灰色的提示,提示我們需要重新運行springboot服務

@ConfigurationProperties注解我們已經介紹完了,接下來我們就來區分一下@ConfigurationProperties注解以及我們前面所介紹的另外一個@Value注解:

相同點:都是用來注入外部配置的屬性的。

不同點:

  • @Value注解只能一個一個的進行外部屬性的注入。

  • @ConfigurationProperties可以批量的將外部的屬性配置注入到bean對象的屬性中。

如果要注入的屬性非常的多,并且還想做到復用,就可以定義這么一個bean對象。通過 configuration properties 批量的將外部的屬性配置直接注入到 bin 對象的屬性當中。在其他的類當中,我要想獲取到注入進來的屬性,我直接注入 bin 對象,然后調用 get 方法,就可以獲取到對應的屬性值了

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

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

相關文章

07 編譯器

目錄 編譯過程編譯器查看詳解函數庫自動化構建工具進度條程序 1. 編譯過程 預處理: a. 去注釋 b.宏替換 c.頭文件展開 d.條件編譯 編譯: 匯編 匯編: 可重定向二進制目標文件 鏈接: 鏈接多個.o, .obj合并形成一個可執行exe gcc編譯c程序, g編譯c程序 2. 編譯器查看 輸入gcc …

mac蘋果電腦c盤滿了如何清理內存?2024最新操作教程分享

蘋果電腦用戶經常會遇到麻煩:內置存儲器(即C盤)空間不斷縮小&#xff0c;電腦運行緩慢。在這種情況下&#xff0c;蘋果電腦c盤滿了怎么清理&#xff1f;如何有效清理和優化存儲空間&#xff0c;提高計算機性能&#xff1f;成了一個重要的問題。今天&#xff0c;我想給大家詳細介…

備戰藍橋杯---線段樹基礎2

今天我們把線段樹的另一個模板看一下&#xff1a; 在這里&#xff0c;我們注意到乘的操作&#xff0c;因此我們用兩個懶標記來分別表示加和乘&#xff0c;這時我們面臨了一個問題&#xff0c;就是當我們把標記往下傳時&#xff0c;它的兒子怎么知道是先乘還是先加&#xff1f; …

2025張宇考研數學,百度網盤視頻課+36講PDF講義+真題

張宇老師的課屬于幽默生動&#xff0c;會讓一個文科生愛上數學&#xff0c;但是有的同學不知道在哪看&#xff0c;可以看一下&#xff1a;2025張宇考研數學全程網盤 docs.qq.com/doc/DTmtOa0Fzc0V3WElI 可以粘貼在瀏覽器 張宇30講作為一本基礎講義&#xff1a;和教材…

java的線程池介紹

什么是線程池&#xff1f; 線程池是一種用于管理和復用線程的機制&#xff0c;旨在減少線程的創建和銷毀次數&#xff0c;提高線程的可重用性和執行效率。通過線程池&#xff0c;可以控制線程的數量、數量大小以及線程的執行方式&#xff0c;從而更加有效地處理并發任務。 線…

代碼隨想錄刷題第48天

今天來看看股票市場。第一題是買賣股票的最佳時機https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/&#xff0c;首先想到了暴力解法&#xff0c;兩層for循環&#xff0c;時間復雜度為n * n&#xff0c;代碼超時了。 class Solution { public:int m…

如何使用公網地址遠程訪問內網Nacos UI界面查看注冊服務

文章目錄 1. Docker 運行Nacos2. 本地訪問Nacos3. Linux安裝Cpolar4. 配置Nacos UI界面公網地址5. 遠程訪問 Nacos UI界面6. 固定Nacos UI界面公網地址7. 固定地址訪問Plik Nacos是阿里開放的一款中間件,也是一款服務注冊中心&#xff0c;它主要提供三種功能&#xff1a;持久化…

關于gossip協議

Gossip協議&#xff0c;也稱為流言協議&#xff0c;是一種在分布式系統中用于節點之間通信和數據同步的算法。它的設計靈感來自于人類社交中的流言傳播機制&#xff1a;一個人告訴幾個人某個消息&#xff0c;這幾個人再各自告訴其他幾個人&#xff0c;如此反復&#xff0c;最終…

6、wuzhicms代碼審計

wuzhicms代碼審計 前言 安裝環境配置 服務器要求 Web服務器: apache/nginx/iis PHP環境要求:支持php5.2、php5.3、php5.4、php5.5、php5.6、php7.1 (推薦使用5.4或更高版本!) 數據庫要求: Mysql5www/install文件夾即可進入安裝頁面 審計開始 首頁文件index.php&#xff0c…

使用Files工具類中的walkFileTree(Path, FileVisitor)方法對文件進行操作

使用Files工具類中的walkFileTree(Path, FileVisitor)方法&#xff0c;其中需要傳入兩個參數 Path&#xff1a;文件起始路徑FileVisitor&#xff1a;文件訪問器&#xff0c;使用訪問者模式 接口的實現類SimpleFileVisitor有四個方法 preVisitDirectory&#xff1a;訪問目錄前的…

PHP curl 獲取當前請求 header 信息

一、正常 curl 獲取響應結果 1)、curl請求代碼 $url http:://www.baidu.com; $data [param > test]; $ch curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array("content-type:application/json&qu…

kubernetes+prometheus+grafana監控+alertmanager實現qq郵箱報警

prometheus基于kubernetes監控 prometheus對kubernetes的監控 對于Kubernetes而言&#xff0c;我們可以把當中所有的資源分為幾類&#xff1a; 基礎設施層&#xff08;Node&#xff09;&#xff1a;集群節點&#xff0c;為整個集群和應用提供運行時資源容器基礎設施&#xff…

C/C++內存管理及內存泄漏詳解

目錄 C/C內存分布 C語言中動態內存管理方式&#xff1a;malloc/calloc/realloc/free C內存管理方式 new/delete操作內置類型 new和delete操作自定義類型 operator new與operator delete函數 new和delete的實現原理 內置類型 自定義類型 內存泄漏 概念 內存泄漏分類 ?…

180基于matlab的頻率切片小波變換程序(FTWT)

基于matlab的頻率切片小波變換程序&#xff08;FTWT&#xff09;。從一種新的角度出發&#xff0c;通過自由選擇頻率切片函數、引進新尺度參數&#xff0c;在頻率域實現小波變換&#xff0c;該變換能夠很好地刻畫信號各成分之間的相對能量關系。此外&#xff0c;頻率切片小波變…

【InternLM 實戰營筆記】OpenCompass大模型評測

隨著人工智能技術的快速發展&#xff0c; 大規模預訓練自然語言模型成為了研究熱點和關注焦點。OpenAI于2018年提出了第一代GPT模型&#xff0c;開辟了自然語言模型生成式預訓練的路線。沿著這條路線&#xff0c;隨后又陸續發布了GPT-2和GPT-3模型。與此同時&#xff0c;谷歌也…

探討蘋果 Vision Pro 的 AI 數字人形象問題

Personas 的設計模糊性&#xff1a; 部分人認為這種模糊設計可能是出于安全考慮&#x1f6e1;?。安全角度&#xff1a;Personas 代表著你的 AI 數字形象&#xff0c;在創建時&#xff0c;它相當于你的 AVP&#xff08;生物識別掃描器的存在增加了冒充的難度&#xff09;。如果…

40、網絡編程/TCP和UDP通信模型練習20240229

一、使用TCP模型創建服務器和客戶端完成簡單通信。 服務器代碼&#xff1a; #include<myhead.h> #define SER_IP "192.168.32.130" #define SER_PORT 8888 int main(int argc, const char *argv[]) {//1.創建監聽的套接字int sfd-1;sfdsocket(AF_INET,SOCK_S…

解決 MySQL 未運行但鎖文件存在的問題

查看mysql狀態時&#xff0c;顯示錯誤信息"ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists"。 解決步驟 1、檢查 MySQL 進程是否正在運行 在繼續之前&#xff0c;我們首先需要確定 MySQL 進程是否正在運行。我們可以使用以下命令檢查…

MBD開發專欄介紹

文章目錄 MBD概念MBD工具箱介紹MBD專欄介紹MBD概念 MBD : Model-Based Design,基于模型的設計方法是一種系統開發方法論,即對系統進行建模、分析、驗證,然后基于模型自動生成代碼、測試用例和文檔的設計開發過程MBD采用的是基于自然語言和圖形語言的雙重建模方式,讓模型與用…

港中文聯合MIT提出超長上下文LongLoRA大模型微調算法

論文名稱&#xff1a; LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models 文章鏈接&#xff1a;https://arxiv.org/abs/2309.12307 代碼倉庫&#xff1a; https://github.com/dvlab-research/LongLoRA 現階段&#xff0c;上下文窗口長度基本上成為了評估…