一 SpringMVC簡介
1 SpringMVC概述
問題導(dǎo)入
SpringMVC框架有什么優(yōu)點(diǎn)?
1.1 SpringMVC概述
- SpringMVC是一種基于Java實(shí)現(xiàn)MVC模型的輕量級Web框架
- 優(yōu)點(diǎn)
- 使用簡單,開發(fā)便捷(相比于Servlet)
- 靈活性強(qiáng)
2 入門案例
問題導(dǎo)入
在Controller中如何定義訪問路徑,如何響應(yīng)數(shù)據(jù)?
2.0 回顧Servlet技術(shù)開發(fā)web程序流程
- 創(chuàng)建web工程(Maven結(jié)構(gòu))
- 設(shè)置tomcat服務(wù)器,加載web工程(tomcat插件)
- 導(dǎo)入坐標(biāo)(Servlet)
- 定義處理請求的功能類(UserServlet)
- 設(shè)置請求映射(配置映射關(guān)系)
2.1 使用SpringMVC技術(shù)開發(fā)web程序流程
- 創(chuàng)建web工程(Maven結(jié)構(gòu))
- 設(shè)置tomcat服務(wù)器,加載web工程(tomcat插件)
- 導(dǎo)入坐標(biāo)(SpringMVC+Servlet)
- 定義處理請求的功能類(UserController)
- 設(shè)置請求映射(配置映射關(guān)系)
- 編寫SpringMVC配置類,加載處理請求的Bean。
- 加載SpringMVC配置,并設(shè)置SpringMVC請求攔截的路徑
- 將SpringMVC設(shè)定加載到Tomcat容器中
2.2 代碼實(shí)現(xiàn)
【第一步】創(chuàng)建web工程(Maven結(jié)構(gòu))
【第二步】設(shè)置tomcat服務(wù)器,加載web工程(tomcat插件)
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
【第三步】導(dǎo)入坐標(biāo)(SpringMVC+Servlet)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
【第四步】定義處理請求的功能類(UserController)
//定義表現(xiàn)層控制器bean
@Controller
public class UserController {
//設(shè)置映射路徑為/save,即外部訪問路徑
@RequestMapping("/save")
//設(shè)置當(dāng)前操作返回結(jié)果為指定json數(shù)據(jù)(本質(zhì)上是一個字符串信息)
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
}
注意事項(xiàng):
對于SpringMVC而言,Controller方法返回值默認(rèn)表示要跳轉(zhuǎn)的頁面,沒有對應(yīng)的頁面就會報錯。如果不想跳轉(zhuǎn)頁面而是響應(yīng)數(shù)據(jù),那么就需要在方法上使用@ResponseBody注解。
【第五步】編寫SpringMVC配置類,加載處理請求的Bean。
//springmvc配置類,本質(zhì)上還是一個spring配置類
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
【第六步】加載SpringMVC配置,并設(shè)置SpringMVC請求攔截的路徑
//web容器配置類
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加載springmvc配置類,產(chǎn)生springmvc容器(本質(zhì)還是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext對象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加載指定配置類
ctx.register(SpringMvcConfig.class);
return ctx;
}
//設(shè)置由springmvc控制器處理的請求映射路徑
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加載spring配置類
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
2.3 運(yùn)行結(jié)果
2.4 案例注解和類解析
2.4.1 @Controller注解
- 名稱:@Controller
- 類型:類注解
- 位置:SpringMVC控制器類定義上方
- 作用:設(shè)定SpringMVC的核心控制器bean
- 范例
@Controller
public class UserController {
}
2.4.2 @RequestMapping注解
- 名稱:@RequestMapping
- 類型:方法注解
- 位置:SpringMVC控制器方法定義上方
- 作用:設(shè)置當(dāng)前控制器方法請求訪問路徑
- 范例
@RequestMapping("/save")
public void save(){
System.out.println("user save ...");
}
注意:其實(shí)@RequestMapping注解還可以寫到類上面
2.4.3 @ResponseBody注解
- 名稱:@ResponseBody
- 類型:方法注解
- 位置:SpringMVC控制器方法定義上方
- 作用:設(shè)置當(dāng)前控制器方法響應(yīng)內(nèi)容為當(dāng)前返回值,無需解析
- 范例
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
2.4.4 AbstractDispatcherServletInitializer類
- AbstractDispatcherServletInitializer類是SpringMVC提供的快速初始化Web3.0容器的抽象類
- AbstractDispatcherServletInitializer提供三個接口方法供用戶實(shí)現(xiàn)
- createServletApplicationContext()方法,創(chuàng)建Servlet容器時,加載SpringMVC對應(yīng)的bean并放入WebApplicationContext對象范圍中,而WebApplicationContext的作用范圍為ServletContext范圍,即整個web容器范圍。
//加載springmvc配置類,產(chǎn)生springmvc容器(本質(zhì)還是spring容器) protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMvcConfig.class); return ctx; }
- getServletMappings()方法,設(shè)定SpringMVC對應(yīng)的請求映射路徑,設(shè)置為/表示攔截所有請求,任意請求都將轉(zhuǎn)入到SpringMVC進(jìn)行處理。
//設(shè)置由springmvc控制器處理的請求映射路徑 protected String[] getServletMappings() { return new String[]{"/"}; }
- createRootApplicationContext()方法,如果創(chuàng)建Servlet容器時需要加載非SpringMVC對應(yīng)的bean,使用當(dāng)前方法進(jìn)行,使用方式同createServletApplicationContext()
//加載spring配置類 protected WebApplicationContext createRootApplicationContext() { return null; }
2.5 入門程序開發(fā)總結(jié)(1+N)
- 一次性工作
- 創(chuàng)建工程,設(shè)置服務(wù)器,加載工程
- 導(dǎo)入坐標(biāo)
- 創(chuàng)建web容器啟動類,加載SpringMVC配置,并設(shè)置SpringMVC請求攔截路徑
- SpringMVC核心配置類(設(shè)置配置類,掃描controller包,加載Controller控制器bean)
- 多次工作
- 定義處理請求的控制器類
- 定義處理請求的控制器方法,并配置映射路徑(@RequestMapping)與返回json數(shù)據(jù)(@ResponseBody)
3 入門案例工作流程分析
3.1 啟動服務(wù)器初始化過程
- 服務(wù)器啟動,執(zhí)行ServletContainersInitConfig類,初始化web容器
- 執(zhí)行createServletApplicationContext方法,創(chuàng)建了WebApplicationContext對象
- 加載SpringMvcConfig配置類
- 執(zhí)行@ComponentScan加載對應(yīng)的bean
- 加載UserController,每個@RequestMapping的名稱對應(yīng)一個具體的方法
- 執(zhí)行g(shù)etServletMappings方法,定義所有的請求都通過SpringMVC
3.2 單次請求過程
- 發(fā)送請求localhost/save
- web容器發(fā)現(xiàn)所有請求都經(jīng)過SpringMVC,將請求交給SpringMVC處理
- 解析請求路徑/save
- 由/save匹配執(zhí)行對應(yīng)的方法save()
- 執(zhí)行save()
- 檢測到有@ResponseBody直接將save()方法的返回值作為響應(yīng)求體返回給請求方
4 Controller加載控制
問題導(dǎo)入
因?yàn)楣δ懿煌绾伪苊釹pring錯誤的加載到SpringMVC的bean?
4.1 Controller加載控制與業(yè)務(wù)bean加載控制
- SpringMVC相關(guān)bean(表現(xiàn)層bean)
- Spring控制的bean
- 業(yè)務(wù)bean(Service)
- 功能bean(DataSource等)
- SpringMVC相關(guān)bean加載控制
- SpringMVC加載的bean對應(yīng)的包均在com.itheima.controller包內(nèi)
- Spring相關(guān)bean加載控制
- 方式一:Spring加載的bean設(shè)定掃描范圍為com.itheima,排除掉controller包內(nèi)的bean
- 方式二:Spring加載的bean設(shè)定掃描范圍為精準(zhǔn)范圍,例如service包、dao包等
- 方式三:不區(qū)分Spring與SpringMVC的環(huán)境,加載到同一個環(huán)境中
4.2 方式一代碼實(shí)現(xiàn)
- 名稱:@ComponentScan
- 類型:類注解
- 范例
@Configuration
@ComponentScan(value = "com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
- 屬性
- excludeFilters:排除掃描路徑中加載的bean,需要指定類別(type)與具體項(xiàng)(classes)
- includeFilters:加載指定的bean,需要指定類別(type)與具體項(xiàng)(classes)
4.3 Bean的加載格式
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
簡化格式
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class}
};
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
}
5 PostMan
5.1 PostMan介紹
- Postman是一款功能強(qiáng)大的網(wǎng)頁調(diào)試與發(fā)送網(wǎng)頁HTTP請求的Chrome插件。
- 作用:常用于進(jìn)行接口測試
- 特征
- 簡單
- 實(shí)用
- 美觀
- 大方
5.2 PostMan安裝
官網(wǎng):https://www.postman.com/
雙擊“Postman-Setup.exe”即可自動按照,打開之后需要注冊,如果底部有如下鏈接,可以點(diǎn)擊跳過注冊
5.3 PostMan的使用
5.3.1 創(chuàng)建WorkSpace工作空間
5.3.2 發(fā)送請求獲取json數(shù)據(jù)
5.3.3 保存當(dāng)前請求
注意:第一次請求需要創(chuàng)建一個新的目錄,后面就不需要創(chuàng)建新目錄,直接保存到已經(jīng)創(chuàng)建好的目錄即可。
5.4 PostMan漢化
5.4.1 下載&安裝 Postman
- 想要漢化 Postman, 就必須導(dǎo)入漢化補(bǔ)丁包
- 補(bǔ)丁包的版本號需與 Postman 版本號一致才行,否則大概率無法漢化。
- 所以,需先確認(rèn)漢化補(bǔ)丁包的版本號,再下載對應(yīng)版本的 Postman 使用。
漢化補(bǔ)丁下載鏈接:https://github.com/hlmd/Postman-cn/releases
目前補(bǔ)丁包版本為9.12.2
確認(rèn)了補(bǔ)丁包版本號后,再下載對應(yīng)版本的 Postman :
Postman 歷史版本下載 | 請把下面鏈接的"版本號"替換為指定的版本號, 然后瀏覽器中訪問即可直接下載 |
---|---|
Windows64位 | https://dl.pstmn.io/download/version/版本號/win64 |
Windows32位 | https://dl.pstmn.io/download/version/版本號/win32 |
Mac Intel Chip | https://dl.pstmn.io/download/version/版本號/osx_64 |
Mac Apple Chip | https://dl.pstmn.io/download/version/版本號/osx_arm64 |
Linux | https://dl.pstmn.io/download/version/版本號/linux |
比如當(dāng)前補(bǔ)丁版本號為 9.12.2
, 如果想要下載 Windows 64 位的 Postman,則下載鏈接為 https://dl.pstmn.io/download/version/9.12.2/win64,瀏覽器訪問該地址,可直接下載。下載成功后雙擊安裝即可。
5.4.2 開始漢化 Postman
- Windows 系統(tǒng)
- 下載好對應(yīng)版本的漢化補(bǔ)丁包 app.zip;
- 進(jìn)入到 Postman 安裝目錄下的 /resources 文件夾中:
- 桌面找到 Postman 應(yīng)用程序右鍵 -> 打開文件所在位置,再進(jìn)入 app-..*/resources 目錄下, 默認(rèn)安裝地址:C:/Users/用戶名/AppData/Local/Postman, 示例:C:/Users/用戶名/AppData/Local/Postman/app-8.8.0/resources
- 桌面找到 Postman 應(yīng)用程序右鍵 -> 打開文件所在位置,再進(jìn)入 app-..*/resources 目錄下, 默認(rèn)安裝地址:C:/Users/用戶名/AppData/Local/Postman, 示例:C:/Users/用戶名/AppData/Local/Postman/app-8.8.0/resources
- 復(fù)制 app.zip 到 resources 目錄,將app.zip解壓到當(dāng)前文件夾會生成一個app目錄,如上圖所示;
- 重啟 Postman 即可看到已經(jīng)漢化成功~
- Mac 系統(tǒng)
- 下載對應(yīng)版本的 app.zip;
- 解壓 app.zip;
- 進(jìn)入 訪達(dá)/應(yīng)用程序/Postman.app/Contents/Resources/:
- 進(jìn)入訪達(dá)/應(yīng)用程序找到Postman.app右鍵查看包內(nèi)容,再進(jìn)入Contents/Resources
- 替換 app 文件夾
- 如果目錄下沒有 app 文件夾,那么直接解壓 app.zip 得到 app 文件夾即可 將app.zip解壓出來的app文件夾復(fù)制到Resources目錄,替換原本的app文件夾 可以先刪除或重命名原本的app文件夾
- 重啟 Postman 就可以了~
- Linux 系統(tǒng)
- 下載對應(yīng)版本的 app.zip:
# 下方為Github地址 將版本號替換為對應(yīng)版本號,例如:8.8.0 uwget https://github.com/hlmd/Postman-cn/releases/download/版本號/app.zip
- 解壓&&替換app文件夾:
# Postman安裝地址 自行替換 unzip -o -d Postman安裝地址/app/resources app.zip
5.4.3 禁掉 Postman 自動更新
- Windows
- Windows 刪除安裝目錄的 update.exe 即可。
- Mac / Linux
-
將此解析加入你電腦的主機(jī)文件 hosts :
0.0.0.0 dl.pstmn.io
-
注意:這是一項(xiàng)危險操作,將會使你的電腦無法與 Postman 下載服務(wù)器連接,當(dāng)然這就可以使你的 Postman 應(yīng)用程序不再更新, 如果想更新請將此解析注釋或移除。
-
hosts 文件在哪里?
- Windows:
C:/Windows/System32/drivers/etc/hosts
- Linux & Mac:
/etc/hosts
- Windows:
-
6 ApiFox
6.1 ApiFox的介紹
- API 文檔、API 調(diào)試、API Mock、API 自動化測試
- API 一體化協(xié)作平臺
- 更先進(jìn)的 API 設(shè)計(jì)/開發(fā)/測試工具
- Apifox = Postman + Swagger + Mock + JMeter
6.2 ApiFox的安裝
官網(wǎng):https://apifox.com/
下一步指定安裝位置即可
6.3 ApiFox的使用
6.3.1 新建團(tuán)隊(duì)新建項(xiàng)目
6.3.2 發(fā)送請求獲取json數(shù)據(jù)
6.3.3 保存當(dāng)前請求
二 請求與響應(yīng)
1 請求映射路徑
問題導(dǎo)入
@RequestMapping注解注解可以寫在哪?有什么作用?
1.1 @RequestMapping注解
- 名稱:@RequestMapping
- 類型:方法注解 類注解
- 位置:SpringMVC控制器方法定義上方
- 作用:設(shè)置當(dāng)前控制器方法請求訪問路徑,如果設(shè)置在類上統(tǒng)一設(shè)置當(dāng)前控制器方法請求訪問路徑前綴
- 范例
@Controller
//類上方配置的請求映射與方法上面配置的請求映射連接在一起,形成完整的請求映射路徑
@RequestMapping("/user")
public class UserController {
//請求路徑映射
@RequestMapping("/save") //此時save方法的訪問路徑是:/user/save
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
}
2 請求參數(shù)
2.1 發(fā)送普通類型參數(shù)
問題導(dǎo)入
如何解決POST請求中文亂碼問題?
2.1.1 請求方式
- GET請求
- POST請求
2.1.2 GET請求傳遞普通參數(shù)
- 普通參數(shù):url地址傳參,地址參數(shù)名與形參變量名相同,定義形參即可接收參數(shù)
//普通參數(shù):請求參數(shù)與形參名稱對應(yīng)即可完成參數(shù)傳遞
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通參數(shù)傳遞 name ==> "+name);
System.out.println("普通參數(shù)傳遞 age ==> "+age);
return "{'module':'common param'}";
}
- 問題:如果同學(xué)們傳遞的參數(shù)是中文試試,你們會發(fā)現(xiàn)接收到的參數(shù)出現(xiàn)了中文亂碼問題。
- 原因:tomcat 8.5版本之后GET請求就不再出現(xiàn)中文亂碼問題,但是我們使用的是tomcat7插件,所以會出現(xiàn)GET請求中文亂碼問題。
- 解決:在pom.xml添加tomcat7插件處配置UTF-8字符集,解決GET請求中文亂碼問題。
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port><!--tomcat端口號-->
<path>/</path> <!--虛擬目錄-->
<uriEncoding>UTF-8</uriEncoding><!--訪問路徑編解碼字符集-->
</configuration>
</plugin>
</plugins>
</build>
2.1.3 POST請求傳遞普通參數(shù)
- 普通參數(shù):form表單post請求傳參,表單參數(shù)名與形參變量名相同,定義形參即可接收參數(shù)
//普通參數(shù):請求參數(shù)與形參名稱對應(yīng)即可完成參數(shù)傳遞
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通參數(shù)傳遞 name ==> "+name);
System.out.println("普通參數(shù)傳遞 age ==> "+age);
return "{'module':'common param'}";
}
問題:我們發(fā)現(xiàn),POST請求傳遞的參數(shù)如果包含中文那么就會出現(xiàn)中文亂碼問題,說明我們之前配置的tomcat插件uri路徑編解碼字符集無法解決POST請求中文亂碼問題。那么如何解決呢?
2.1.4 POST請求中文亂碼處理
在加載SpringMVC配置的配置類中指定字符過濾器。
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//亂碼處理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
2.2 五種類型參數(shù)傳遞
問題導(dǎo)入
當(dāng)請求參數(shù)名與形參變量名不同,該如何接收請求參數(shù)?
2.2.1 五種類型參數(shù)介紹
- 普通參數(shù)
- POJO類型參數(shù)
- 嵌套POJO類型參數(shù)
- 數(shù)組類型參數(shù)
- 集合類型參數(shù)
2.2.2 普通參數(shù)
- 普通參數(shù):當(dāng)請求參數(shù)名與形參變量名不同,使用@RequestParam綁定參數(shù)關(guān)系
//普通參數(shù):請求參數(shù)名與形參名不同時,使用@RequestParam注解關(guān)聯(lián)請求參數(shù)名稱與形參名稱之間的關(guān)系
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
System.out.println("普通參數(shù)傳遞 userName ==> "+userName);
System.out.println("普通參數(shù)傳遞 age ==> "+age);
return "{'module':'common param different name'}";
}
- 名稱:@RequestParam
- 類型:形參注解
- 位置:SpringMVC控制器方法形參定義前面
- 作用:綁定請求參數(shù)與處理器方法形參間的關(guān)系
- 參數(shù):
- required:是否為必傳參數(shù)
- defaultValue:參數(shù)默認(rèn)值
2.2.3 POJO類型參數(shù)
- POJO參數(shù):請求參數(shù)名與形參對象屬性名相同,定義POJO類型形參即可接收參數(shù)
public class User {
private String name;
private int age;
//同學(xué)們自己添加getter/setter/toString()方法
}
//POJO參數(shù):請求參數(shù)與形參對象中的屬性對應(yīng)即可完成參數(shù)傳遞
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo參數(shù)傳遞 user ==> "+user);
return "{'module':'pojo param'}";
}
注意事項(xiàng):請求參數(shù)key的名稱要和POJO中屬性的名稱一致,否則無法封裝。
2.2.4 嵌套POJO類型參數(shù)
- POJO對象中包含POJO對象
public class User {
private String name;
private int age;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
public class Address {
private String province;
private String city;
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
- 嵌套POJO參數(shù):請求參數(shù)名與形參對象屬性名相同,按照對象層次結(jié)構(gòu)關(guān)系即可接收嵌套POJO屬性參數(shù)
//嵌套POJO參數(shù):嵌套屬性按照層次結(jié)構(gòu)設(shè)定名稱即可完成參數(shù)傳遞
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo參數(shù)傳遞 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
注意事項(xiàng):請求參數(shù)key的名稱要和POJO中屬性的名稱一致,否則無法封裝。
2.2.5 數(shù)組類型參數(shù)
- 數(shù)組參數(shù):請求參數(shù)名與形參對象屬性名相同且請求參數(shù)為多個,定義數(shù)組類型即可接收參數(shù)
//數(shù)組參數(shù):同名請求參數(shù)可以直接映射到對應(yīng)名稱的形參數(shù)組對象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("數(shù)組參數(shù)傳遞 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
2.2.6 集合類型參數(shù)
- 集合保存普通參數(shù):請求參數(shù)名與形參集合對象名相同且請求參數(shù)為多個,@RequestParam綁定參數(shù)關(guān)系
//集合參數(shù):同名請求參數(shù)可以使用@RequestParam注解映射到對應(yīng)名稱的集合對象中作為數(shù)據(jù)
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合參數(shù)傳遞 likes ==> "+ likes);
return "{'module':'list param'}";
}
2.3 json數(shù)據(jù)參數(shù)傳遞
問題導(dǎo)入
問題:@EnableWebMvc注解和@ResponseBody注解有什么用?
2.3.1 json數(shù)據(jù)參數(shù)介紹
- json普通數(shù)組([“”,“”,“”,…])
- json對象({key:value,key:value,…})
- json對象數(shù)組([{key:value,…},{key:value,…}])
2.3.2 傳遞json普通數(shù)組
2.3.2.1 代碼演示
- 添加json數(shù)據(jù)轉(zhuǎn)換相關(guān)坐標(biāo)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
- 設(shè)置發(fā)送json數(shù)據(jù)(請求body中添加json數(shù)據(jù))
- 開啟自動轉(zhuǎn)換json數(shù)據(jù)的支持
@Configuration
@ComponentScan("com.itheima.controller")
//開啟json數(shù)據(jù)類型自動轉(zhuǎn)換
@EnableWebMvc
public class SpringMvcConfig {
}
注意事項(xiàng):
@EnableWebMvc注解功能強(qiáng)大,該注解整合了多個功能,此處僅使用其中一部分功能,即json數(shù)據(jù)進(jìn)行自動類型轉(zhuǎn)換
4. 在Controller中編寫方法接收json參數(shù)
//集合參數(shù):json格式
//1.開啟json數(shù)據(jù)格式的自動轉(zhuǎn)換,在配置類中開啟@EnableWebMvc
//2.使用@RequestBody注解將外部傳遞的json數(shù)組數(shù)據(jù)映射到形參的集合對象中作為數(shù)據(jù)
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)參數(shù)傳遞 list ==> "+likes);
return "{'module':'list common for json param'}";
}
2.3.2.2 @EnableWebMvc注解介紹
- 名稱:@EnableWebMvc
- 類型:配置類注解
- 位置:SpringMVC配置類定義上方
- 作用:開啟SpringMVC多項(xiàng)輔助功能
- 范例:
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
2.3.2.3 @RequestBody注解介紹
- 名稱:@RequestBody
- 類型:形參注解
- 位置:SpringMVC控制器方法形參定義前面
- 作用:將請求中請求體所包含的數(shù)據(jù)傳遞給請求參數(shù),此注解一個處理器方法只能使用一次
- 范例:
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)參數(shù)傳遞 list ==> "+likes);
return "{'module':'list common for json param'}";
}
2.3.3 傳遞json對象
- POJO參數(shù):json數(shù)據(jù)與形參對象屬性名相同,定義POJO類型形參即可接收參數(shù)
//POJO參數(shù):json格式
//1.開啟json數(shù)據(jù)格式的自動轉(zhuǎn)換,在配置類中開啟@EnableWebMvc
//2.使用@RequestBody注解將外部傳遞的json數(shù)據(jù)映射到形參的實(shí)體類對象中,要求屬性名稱一一對應(yīng)
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)參數(shù)傳遞 user ==> "+user);
return "{'module':'pojo for json param'}";
}
2.3.4 傳遞json對象數(shù)組
- POJO集合參數(shù):json數(shù)組數(shù)據(jù)與集合泛型屬性名相同,定義List類型形參即可接收參數(shù)
//集合參數(shù):json格式
//1.開啟json數(shù)據(jù)格式的自動轉(zhuǎn)換,在配置類中開啟@EnableWebMvc
//2.使用@RequestBody注解將外部傳遞的json數(shù)組數(shù)據(jù)映射到形參的保存實(shí)體類對象的集合對象中,要求屬性名稱一一對應(yīng)
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)參數(shù)傳遞 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
2.3.5 @RequestBody與@RequestParam區(qū)別
- 區(qū)別
- @RequestParam用于接收url地址傳參,表單傳參【application/x-www-form-urlencoded】
- @RequestBody用于接收json數(shù)據(jù)【application/json】
- 應(yīng)用
- 后期開發(fā)中,發(fā)送json格式數(shù)據(jù)為主,@RequestBody應(yīng)用較廣
- 如果發(fā)送非json格式數(shù)據(jù),選用@RequestParam接收請求參數(shù)
3 日期類型參數(shù)傳遞
問題導(dǎo)入
@DateTimeFormat注解的作用是什么?
3.1 代碼演示
- 日期類型數(shù)據(jù)基于系統(tǒng)不同格式也不盡相同
2088-08-18
2088/08/18
08/18/2088 - 接收形參時,根據(jù)不同的日期格式設(shè)置不同的接收方式
//日期參數(shù) http://localhost:80/dataParam?date=2088/08/08&date1=2088-08-18&date2=2088/08/28 8:08:08
//使用@DateTimeFormat注解設(shè)置日期類型數(shù)據(jù)格式,默認(rèn)格式y(tǒng)yyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("參數(shù)傳遞 date ==> "+date);
System.out.println("參數(shù)傳遞 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("參數(shù)傳遞 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
3.2 @DateTimeFormat注解介紹
- 名稱:@DateTimeFormat
- 類型:形參注解
- 位置:SpringMVC控制器方法形參前面
- 作用:設(shè)定日期時間型數(shù)據(jù)格式
- 屬性:pattern:指定日期時間格式字符串
3.3 工作原理
- 其內(nèi)部依賴Converter接口
public interface Converter<S, T> {
@Nullable
T convert(S var1);
}
- 請求參數(shù)年齡數(shù)據(jù)(String→Integer)
- json數(shù)據(jù)轉(zhuǎn)對象(json → POJO)
- 日期格式轉(zhuǎn)換(String → Date)
3.4 注意事項(xiàng)
傳遞日期類型參數(shù)必須在配置類上使用@EnableWebMvc注解。其功能之一:根據(jù)類型匹配對應(yīng)的類型轉(zhuǎn)換器。
4 響應(yīng)
問題導(dǎo)入
如何響應(yīng)json數(shù)據(jù)?
4.1響應(yīng)頁面
@Controller
public class UserController {
//響應(yīng)頁面/跳轉(zhuǎn)頁面
//返回值為String類型,設(shè)置返回值為頁面名稱,即可實(shí)現(xiàn)頁面跳轉(zhuǎn)
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳轉(zhuǎn)頁面");
return "page.jsp";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>Hello Spring MVC!</h2>
</body>
</html>
4.2 文本數(shù)據(jù)
//響應(yīng)文本數(shù)據(jù)
//返回值為String類型,設(shè)置返回值為任意字符串信息,即可實(shí)現(xiàn)返回指定字符串信息,需要依賴@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回純文本數(shù)據(jù)");
return "response text";
}
4.3 json數(shù)據(jù)
//響應(yīng)POJO對象
//返回值為實(shí)體類對象,設(shè)置返回值為實(shí)體類類型,即可實(shí)現(xiàn)返回對應(yīng)對象的json數(shù)據(jù),需要依賴@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json對象數(shù)據(jù)");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
//響應(yīng)POJO集合對象
//返回值為集合對象,設(shè)置返回值為集合類型,即可實(shí)現(xiàn)返回對應(yīng)集合的json數(shù)組數(shù)據(jù),需要依賴@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合數(shù)據(jù)");
User user1 = new User();
user1.setName("傳智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑馬程序員");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
注意:需要添加jackson-databind依賴以及在SpringMvcConfig配置類上添加@EnableWebMvc注解
4.4 @RequestBody注解介紹
- 名稱:@RequestBody
- 類型:方法注解
- 位置:SpringMVC控制器方法定義上方
- 作用:設(shè)置當(dāng)前控制器返回值作為響應(yīng)體
- 范例
@RequestMapping("/save")
@ResponseBody
public void save(){
System.out.println("save()...");
retuen "{'info':'springmvc'}"
}
4.5 轉(zhuǎn)Json原理/過程
- HttpMessageConverter接口
三 REST風(fēng)格
1 REST簡介
問題導(dǎo)入
Rest風(fēng)格使用了幾種請求方式定義訪問行為?
1.1 REST介紹
- REST(Representational State Transfer),表現(xiàn)形式狀態(tài)轉(zhuǎn)換
- 傳統(tǒng)風(fēng)格資源描述形式
- http://localhost/user/getById?id=1
- http://localhost/user/saveUser
- REST風(fēng)格描述形式
- http://localhost/user/1
- http://localhost/user
- 傳統(tǒng)風(fēng)格資源描述形式
- 優(yōu)點(diǎn):
- 隱藏資源的訪問行為,無法通過地址得知對資源是何種操作
- 書寫簡化
1.2 RESTful介紹
- 按照REST風(fēng)格訪問資源時使用行為動作區(qū)分對資源進(jìn)行了何種操作
鏈接 | 操作 | 如何區(qū)分 |
---|---|---|
http://localhost/users | 查詢?nèi)坑脩粜畔?/td> | GET查詢 |
http://localhost/users/1 | 查詢指定用戶信息 | GET查詢 |
http://localhost/users | 添加用戶信息 | POST(新增/保存) |
http://localhost/users | 修改用戶信息 | PUT(修改/更新) |
http://localhost/users/1 | 刪除用戶信息 | DELETE(刪除) |
- 根據(jù)REST風(fēng)格對資源進(jìn)行訪問稱為RESTful
1.3 注意事項(xiàng)
- 上述行為是約定方式,約定不是規(guī)范,可以打破,所以稱REST風(fēng)格,而不是REST規(guī)范
- 描述模塊的名稱通常使用復(fù)數(shù),也就是加s的格式描述,表示此類資源,而非單個資源,例如:users、books、accounts……
2 RESTful入門案例
問題導(dǎo)入
Rest風(fēng)格如何通過路徑傳遞參數(shù)?
2.1 快速入門
做法:在Controller中定義方法時設(shè)定"http請求動作(請求方式)“和"設(shè)定請求參數(shù)(路徑變量)”
@Controller
public class UserController {
//設(shè)置當(dāng)前請求方法為POST,表示REST風(fēng)格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//設(shè)置當(dāng)前請求方法為DELETE,表示REST風(fēng)格中的刪除操作
//@PathVariable注解用于設(shè)置路徑變量(路徑參數(shù)),要求路徑上設(shè)置對應(yīng)的占位符,并且占位符名稱與方法形參名稱相同
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//設(shè)置當(dāng)前請求方法為PUT,表示REST風(fēng)格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
//設(shè)置當(dāng)前請求方法為GET,表示REST風(fēng)格中的查詢操作
//@PathVariable注解用于設(shè)置路徑變量(路徑參數(shù)),要求路徑上設(shè)置對應(yīng)的占位符,并且占位符名稱與方法形參名稱相同
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//設(shè)置當(dāng)前請求方法為GET,表示REST風(fēng)格中的查詢操作
@RequestMapping(value = "/users",method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
2.2 @PathVariable介紹
- 名稱:@PathVariable
- 類型:形參注解
- 位置:SpringMVC控制器方法形參定義前面
- 作用:綁定路徑參數(shù)與處理器方法形參間的關(guān)系,要求路徑參數(shù)名與形參名一一對應(yīng)
2.3 @RequestBody、@RequestParam、@PathVariable區(qū)別和應(yīng)用
- 區(qū)別
- @RequestBody:接收請求體參數(shù)
- 用于接收json數(shù)據(jù)
- @RequestParam:接收路徑參數(shù)
- 用于接收url地址傳參或表單傳參
- @PathVariable:接收路徑變量
- 用于接收路徑參數(shù),使用{參數(shù)名稱}描述路徑參數(shù)
- @RequestBody:接收請求體參數(shù)
- 應(yīng)用
- 后期開發(fā)中,發(fā)送請求參數(shù)超過1個時,以json格式為主,@RequestBody應(yīng)用較廣
- 如果發(fā)送非json格式數(shù)據(jù),選用@RequestParam接收請求參數(shù)
- 采用RESTful進(jìn)行開發(fā),當(dāng)參數(shù)數(shù)量較少時,例如1個,可以采用@PathVariable接收請求路徑變量,通常用于傳遞id值
3 REST快速開發(fā)
3.1 代碼中的問題
以上截圖中的代碼和我們之前寫的UserController中的方法類似,其中圖中兩個方法都有三處是有問題的,可以進(jìn)行優(yōu)化。存在的問題如下:
問題1:每個方法的@RequestMapping注解中都定義了訪問路徑/books,重復(fù)性太高。
問題2:每個方法的@RequestMapping注解中都要使用method屬性定義請求方式,重復(fù)性太高。
問題3:每個方法響應(yīng)json都需要加上@ResponseBody注解,重復(fù)性太高。
3.2 Rest快速開發(fā)
解決以上三個問題
解決問題1:在Controller類上使用@RequestMapping定義共同的訪問路徑。
@Controller
@RequestMapping("/books")
public class BookController {
@RequestMapping(method = RequestMethod.POST)
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
@RequestMapping(method = RequestMethod.PUT)
public String update(@RequestBody Book book){
System.out.println("book update..."+book);
return "{'module':'book update'}";
}
@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
public String getById(@PathVariable Integer id){
System.out.println("book getById..."+id);
return "{'module':'book getById'}";
}
@RequestMapping(method = RequestMethod.GET)
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
解決問題2:使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替@RequestMapping(method=RequestMethod.XXX)
@Controller
@RequestMapping("/books")
public class BookController {
// @RequestMapping( method = RequestMethod.POST)
@PostMapping//使用@PostMapping簡化Post請求方法對應(yīng)的映射配置
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping簡化DELETE請求方法對應(yīng)的映射配置
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
// @RequestMapping(method = RequestMethod.PUT)
@PutMapping //使用@PutMapping簡化Put請求方法對應(yīng)的映射配置
public String update(@RequestBody Book book){
System.out.println("book update..."+book);
return "{'module':'book update'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
@GetMapping("/{id}") //使用@GetMapping簡化GET請求方法對應(yīng)的映射配置
public String getById(@PathVariable Integer id){
System.out.println("book getById..."+id);
return "{'module':'book getById'}";
}
// @RequestMapping(method = RequestMethod.GET)
@GetMapping //使用@GetMapping簡化GET請求方法對應(yīng)的映射配置
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
- 名稱:@GetMapping @PostMapping @PutMapping @DeleteMapping
- 類型:方法注解
- 位置:基于SpringMVC的RESTful開發(fā)控制器方法定義上方
- 作用:設(shè)置當(dāng)前控制器方法請求訪問路徑與請求動作,每種對應(yīng)一個請求動作,例如@GetMapping對應(yīng)GET請求
- 屬性:value(默認(rèn)):請求訪問路徑
解決問題3:在Controller類上使用@RestController注解,等同于@Controller與@ResponseBody兩個注解組合功能
@RestController //使用@RestController注解替換@Controller與@ResponseBody注解,簡化書寫
@RequestMapping("/books")
public class BookController {
//方法省略了沒寫
}
- 名稱:@RestController
- 類型:類注解
- 位置:基于SpringMVC的RESTful開發(fā)控制器類定義上方
- 作用:設(shè)置當(dāng)前控制器類為RESTful風(fēng)格,等同于@Controller與@ResponseBody兩個注解組合功能
4 案例:基于RESTful頁面數(shù)據(jù)交互
4.1 案例效果和環(huán)境準(zhǔn)備
4.1.1 案例效果
文章來源:http://www.zghlxwxcb.cn/news/detail-637349.html
4.1.2 環(huán)境準(zhǔn)備
//POJO實(shí)體類
public class Book {
private Integer id;
private String type;
private String name;
private String description;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", type='" + type + '\'' +
", name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
}
//SpringMVC容器初始化類
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//亂碼處理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
//SpringMVC配置類
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
4.2 代碼實(shí)現(xiàn)
4.2.1 制作SpringMVC控制器,并通過PostMan測試接口功能
@RestController
@RequestMapping("/books")
public class BookController {
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save ==> "+ book);
return "{'module':'book save success'}";
}
@GetMapping
public List<Book> getAll(){
System.out.println("book getAll is running ...");
List<Book> bookList = new ArrayList<Book>();
Book book1 = new Book();
book1.setType("計(jì)算機(jī)");
book1.setName("SpringMVC入門教程");
book1.setDescription("小試牛刀");
bookList.add(book1);
Book book2 = new Book();
book2.setType("計(jì)算機(jī)");
book2.setName("SpringMVC實(shí)戰(zhàn)教程");
book2.setDescription("一代宗師");
bookList.add(book2);
Book book3 = new Book();
book3.setType("計(jì)算機(jī)叢書");
book3.setName("SpringMVC實(shí)戰(zhàn)教程進(jìn)階");
book3.setDescription("一代宗師嘔心創(chuàng)作");
bookList.add(book3);
return bookList;
}
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-637349.html
4.2.2 設(shè)置對靜態(tài)資源的訪問放行
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
//設(shè)置靜態(tài)資源訪問過濾,當(dāng)前類需要設(shè)置為配置類,并被掃描加載
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//當(dāng)訪問/pages/????時候,從/pages目錄下查找內(nèi)容
registry.addResourceHandler("/pages/**")
.addResourceLocations("/pages/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**")
.addResourceLocations("/plugins/");
}
}
4.2.3 前端頁面通過異步提交訪問后臺控制器
//添加
saveBook () {
axios.post("/books",this.formData).then((res)=>{
});
},
//主頁列表查詢
getAll() {
axios.get("/books").then((res)=>{
this.dataList = res.data;
});
},
到了這里,關(guān)于DAY04_SpringMVC—SpringMVC簡介&PostMan和ApiFox工具使用&SpringMVC請求與響應(yīng)&REST風(fēng)格的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!