1、什么是REST?
- REST(Representational State Transfer),表述性狀態轉換,它是一種軟件架構風格。
- 傳統URL風格如下:
http://localhost:8080/user/getById?id=1 GET:查詢id為1的用戶
http://localhost:8080/user/saveUser POST:新增用戶
http://localhost:8080/user/updateUser POST:修改用戶
http://localhost:8080/user/deleteUser?id=1 GET:刪除id為1的用戶
我們看到,原始的傳統URL呢,定義比較復雜,而且將資源的訪問行為對外暴露出來了。
- 基于REST風格URL如下:
http://localhost:8080/users/1 GET:查詢id為1的用戶
http://localhost:8080/users POST:新增用戶
http://localhost:8080/users PUT:修改用戶
http://localhost:8080/users/1 DELETE:刪除id為1的用戶
其中總結起來,就一句話:通過URL定位要操作的資源,通過HTTP動詞(請求方式)來描述具體的操作。
- 在REST風格的URL中,通過四種請求方式,來操作數據的增刪改查。
- GET : 查詢
- POST :新增
- PUT :修改
- DELETE :刪除
我們看到如果是基于REST風格,定義URL,URL將會更加簡潔、更加規范、更加優雅。
- 注意事項:
- REST是風格,是約定方式,約定不是規定,可以打破
- 描述模塊的功能通常使用復數,也就是加s的格式來描述,表示此類資源,而非單個資源。
如:users、emps、books…
2、開發規范-統一響應結果
前后端工程在進行交互時,使用統一響應結果 Result。
package com.itheima.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Integer code;//響應碼,1 代表成功; 0 代表失敗
private String msg; //響應信息 描述字符串
private Object data; //返回的數據
//增刪改 成功響應
public static Result success(){
return new Result(1,"success",null);}
//查詢 成功響應
public static Result success(Object data){
return new Result(1,"success",data);}
//失敗響應
public static Result error(String msg){
return new Result(0,msg,null);}
}
3、小tips
- 1、如何限定請求方式是POST?
@PostMapping
- 2、怎么在controller中接收json格式的請求參數?
@RequestBody //把前端傳遞的json數據填充到實體類中
- 3、如果請求路徑,存在一個共同點:都是以 /depts 作為開頭。(重復了)
在Spring當中為了簡化請求路徑的定義,可以把公共的請求路徑,直接抽取到類上,在類上加一個注解
@RequestMapping,并指定請求路徑"/depts"。
//注意事項:一個完整的請求路徑,應該是類上@RequestMapping的value屬性 + 方法上的
//@RequestMapping的value屬性
- 4、怎么在controller中接收請求路徑中的路徑參數?
@PathVariable - 5、在Mapper接口中,執行delete操作的SQL語句時,條件中的id值是不確定的是動態的,
怎么實現呢?
Mybatis中的動態SQL:foreach - 6、如果表單項的名字和方法中形參名不一致,該怎么辦?
public Result upload(String username,
Integer age,
MultipartFile file) //file形參名和請求參數
名image不一致
解決:使用**@RequestParam注解**進行參數綁定
public Result upload(String username,
Integer age,
@RequestParam("image") MultipartFile
file)
4、分頁插件
介紹
PageHelper是Mybatis的一款功能強大、方便易用的分頁插件,支持任何形式的單標、多表的
分頁查詢。
官網:https://pagehelper.github.io/
在執行empMapper.list()方法時,就是執行:select * from emp 語句,怎么能夠
實現分頁操作呢?
分頁插件幫我們完成了以下操作:
1. 先獲取到要執行的SQL語句:select * from emp
2. 把SQL語句中的字段列表,變為:count(*)
3. 執行SQL語句:select count(*) from emp //獲取到總記錄數
4. 再對要執行的SQL語句:select * from emp 進行改造,在末尾添加 limit ? ,
?
5. 執行改造后的SQL語句:select * from emp limit ? , ?
代碼實現
1、在pom.xml引入依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
2、EmpMapper
@Mapper
public interface EmpMapper {
//獲取當前頁的結果列表
@Select("select * from emp")
public List<Emp> page(Integer start, Integer pageSize);
}
3、EmpServiceImpl
@Override
public PageBean page(Integer page, Integer pageSize) {
// 設置分頁參數
PageHelper.startPage(page, pageSize);
// 執行分頁查詢
List<Emp> empList = empMapper.list(name,gender,begin,end);
// 獲取分頁結果
Page<Emp> p = (Page<Emp>) empList;
//封裝PageBean
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
5、文件上傳
簡介
- 文件上傳,是指將本地圖片、視頻、音頻等文件上傳到服務器,供其他用戶瀏覽或下載的過程。
- 文件上傳在項目中應用非常廣泛,我們經常發微博、發微信朋友圈都用到了文件上傳功能。
- 上傳文件的原始form表單,要求表單必須具備以下三點(上傳文件頁面三要素):
- 表單必須有file域,用于選擇要上傳的文件
<input type="file" name="image"/>
- 表單提交方式必須為POST
通常上傳的文件會比較大,所以需要使用 POST 提交方式
- 表單的編碼類型enctype必須要設置為:multipart/form-data
普通默認的編碼格式是不適合傳輸大型的二進制數據的,所以在文件上傳時,表單的編碼格 式必須設置為multipart/form-data
本地存儲
代碼實現
在服務器本地磁盤上創建images目錄,用來存儲上傳的文件(例:E盤創建images目錄)
@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();}
}
使用MultipartFile類提供的API方法,把臨時文件轉存到本地磁盤目錄下
MultipartFile 常見方法:
String getOriginalFilename(); //獲取原始文件名
String getName(); //獲取表單文件名
void transferTo(File dest); //將接收的文件轉存到磁盤文件中
long getSize(); //獲取文件的大小,單位:字節
byte[] getBytes(); //獲取文件內容的字節數組
InputStream getInputStream(); //獲取接收到的文件內容的輸入流
重名問題如何解決的方案:保證每次上傳文件時文件名都唯一的(使用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();}
}
在SpringBoot中,文件上傳時默認單個文件最大大小為1M
如果需要上傳大文件,可以在application.properties進行如下配置:
#配置單個文件最大上傳大小
spring.servlet.multipart.max-file-size=10MB
#配置單個請求最大上傳大小(一次請求可以上傳多個文件)
spring.servlet.multipart.max-request-size=100MB
6、阿里云OSS
- 阿里云對象存儲OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存儲服務。使用OSS,您可以通過網絡隨時存儲和調用包括文本、圖片、音頻和視頻等在內的各種文件。
- SDK:Software Development Kit 的縮寫,軟件開發工具包,包括輔助軟件開發的依賴(jar包)、代碼示例等,都可以叫做SDK。
- Bucket:存儲空間是用戶用于存儲對象(Object,就是文件)的容器,所有的對象都必須隸屬于某個存儲空間。
在Maven項目中加入依賴項(推薦方式):
//阿里云OSS依賴,導入pom.xml中
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version>
</dependency>
如果使用的是Java 9及以上的版本,則需要添加JAXB相關依賴。添加JAXB相關依賴示例代碼如下:
<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version>
</dependency>
<dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version>
</dependency>
- 引入阿里云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-cnshanghai.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("."));
//上傳文件到 OSS
OSS ossClient = new OSSClientBuilder().build(endpoint,
accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, fileName, inputStream);
//文件訪問路徑
String url = endpoint.split("//")[0] + "//" + bucketName +
"." + endpoint.split("//")[1] + "/" + fileName;
// 關閉ossClient
ossClient.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 {
@Autowired
private AliOSSUtils aliOSSUtils;
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
//調用阿里云OSS工具類,將上傳上來的文件存入阿里云
String url = aliOSSUtils.upload(image);
//將圖片上傳完成后的url返回,用于瀏覽器回顯展示
return Result.success(url);}
}
7、配置文件
常見配置文件格式對比:
- XML(臃腫)
<server><port>8080</port><address>127.0.0.1</address>
</server>
- properties(層級結構不清晰)
server.port=8080
server.address=127.0.0.1
- yml/yaml**(推薦)**(簡潔、數據為中心)
server:port: 8080address: 127.0.0.1
yml基本語法:
- 大小寫敏感
- 數值前邊必須有空格,作為分隔符
- 使用縮進表示層級關系,縮進時,不允許使用Tab鍵,只能用空格(idea中會自動將Tab轉換為空格)
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
# 表示注釋,從這個字符一直到行尾,都會被解析器忽略
yml數據格式:
- 對象/Map集合:
user:
# key:valuename: zhangsanage: 18password: 123456
- 數組/List/Set集合:
hobby:- java- game- sport
yml配置
在application.properties中的配置案例相關的配置項
#驅動類名稱
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#數據庫連接的url
spring.datasource.url=jdbc:mysql://localhost:3306/tlias
#連接數據庫的用戶名
spring.datasource.username=root
#連接數據庫的密碼
spring.datasource.password=1234#配置mybatis的日志, 指定輸出到控制臺
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#開啟mybatis的駝峰命名自動映射開關 a_column ------> aCloumn
mybatis.configuration.map-underscore-to-camel-case=true#配置單個文件上傳大小限制
spring.servlet.multipart.max-file-size=10MB
#配置單個請求最大大小的限制 (一次請求中是可以上傳多個文件)
spring.servlet.multipart.max-request-size=100MB#阿里云OSS配置
aliyun.oss.endpoint=https://oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId=LTAI4GCH1vX6DKqJWxd6nEuW
aliyun.oss.accessKeySecret=yBshYweHOpqDuhCArrVHwIiBKpyqSL
aliyun.oss.bucketName=web-tlias
在application.yml中的配置案例相關的配置項
spring:#數據庫連接信息datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tliasusername: rootpassword: 1234#文件上傳的配置servlet:multipart:max-file-size: 10MBmax-request-size: 100MB
#Mybatis配置
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true#阿里云OSS
aliyun:oss:endpoint: https://oss-cn-hangzhou.aliyuncs.comaccessKeyId: LTAI4GCH1vX6DKqJWxd6nEuWaccessKeySecret: yBshYweHOpqDuhCArrVHwIiBKpyqSLbucketName: web-tlias
@ConfigurationProperties
- Spring提供的簡化方式套路:
- 需要創建一個實現類,且實體類中的屬性名和配置文件當中key的名字必須要一致
比如:配置文件當中叫endpoints,實體類當中的屬性也得叫endpoints,另外實體類當
中的屬性還需要提供 getter / setter方法
- 需要將實體類交給Spring的IOC容器管理,成為IOC容器當中的bean對象
@Component
- 在實體類上添加 @ConfigurationProperties 注解,并通過perfect屬性來指定配置參數項的前綴
@ConfigurationProperties可以批量的將外部的屬性配置注入到bean對象的屬性中。
- 實體類: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;
//身份ID
private 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 {
//注入配置參數實體類對象
@Autowired
private AliOSSProperties aliOSSProperties;
/**
* 實現上傳圖片到OSS
*/
public String upload(MultipartFile multipartFile) throws
IOException {
//獲取阿里云OSS參數
String endpoint = aliOSSProperties.getEndpoint();
String accessKeyId = aliOSSProperties.getAccessKeyId();
String accessKeySecret = aliOSSProperties.getAccessKeySecret();
String bucketName = aliOSSProperties.getBucketName();
// 獲取上傳的文件的輸入流
InputStream inputStream = multipartFile.getInputStream();
// 避免文件覆蓋
String originalFilename =
multipartFile.getOriginalFilename();
String fileName = UUID.randomUUID().toString() +
originalFilename.substring(originalFilename.lastIndexOf("."));
//上傳文件到 OSS
OSS 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;
// 關閉ossClient
ossClient.shutdown();
return url;// 把上傳到oss的路徑返回}
pom.xml 引入依賴:提示阿里云 OSS 相關的配置項
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>