??作者:銀河罐頭
??系列專欄:JavaEE
??“種一棵樹最好的時間是十年前,其次是現(xiàn)在”
什么是 Spring MVC
SSM = Spring Boot + Spring Web(Spring MVC) + MyBatis
Spring Web MVC 是基于 Servlet API 構(gòu)建的原始 Web 框架,從?開始就包含在 Spring 框架中。它的正式名稱"Spring Web MVC"來自其源模塊的名稱(Spring-webmvc), 但它通常被稱為"Spring MVC".
- Spring MVC 是?個 Web 框架。
- Spring MVC 是基于 Servlet API 構(gòu)建的。
MVC 定義
MVC 是 Model View Controller 的縮寫,它是軟件?程中的?種軟件架構(gòu)模式,它把軟件系統(tǒng)分為模型、視圖和控制器三個基本部分。
怎么學 Spring MVC
學習 Spring MVC 我們只需要掌握以下 3 個功能:
1.連接的功能:將?戶(瀏覽器)和 Java 程序連接起來,也就是訪問?個地址能夠調(diào)?到我們的 Spring 程序
2.獲取參數(shù)的功能:?戶訪問的時候會帶?些參數(shù),在程序中要想辦法獲取到參數(shù)。
3.輸出數(shù)據(jù)的功能:執(zhí)?了業(yè)務(wù)邏輯之后,要把程序執(zhí)?的結(jié)果返回給?戶。
對于 Spring MVC 來說,掌握了以上 3 個功能就相當于掌握了 Spring MVC。
Spring MVC 創(chuàng)建和連接
創(chuàng)建 Spring MVC 項目
2018年之前,使用 maven 項目添加 Spring MVC 框架的方式來創(chuàng)建,太復雜。
2018年之后 ,使用 Spring Boot 來創(chuàng)建 Spring MVC 項目。
@RestController
public class UserController {
@RequestMapping("/say")//可以是 1 級路由,也可以是 n 級路由
public String sayHi(){
return "hi spring mvc";
}
}
實現(xiàn)用戶到 spring 程序的連接。
@RequestMapping 注解介紹
它支持 GET 請求
那它是否支持 post 請求?
用 postman 測試:
得出結(jié)論:它也支持 POST 請求.
GET, HEAD, POST,PUT, PATCH, DELETE, OPTIONS, TRACE 都支持。
在瀏覽器地址欄輸入地址,默認是 GET 請求。
- 如果我想設(shè)置成只支持其中某一種請求類型,如何實現(xiàn)?
@RestController
public class UserController {
@RequestMapping(value = "/sayhi",method = RequestMethod.POST)
public String sayHi(){
return "hi spring mvc";
}
}
設(shè)置成只支持 POST 請求,再發(fā) GET 請求就失敗了。
@PostMapping
除了通過 @RequestMapping 來設(shè)置 POST,還可以通過@PostMapping 來設(shè)置。
@PostMapping("/sayhello")
public String sayHello(){
return "hello spring mvc";
}
小結(jié):
2種實現(xiàn)路由連接的方式 :@RequestMapping 和 @PostMapping
@GetMapping("/hi")
public String hi(){
return "spring mvc hi";
}
獲取參數(shù)
獲取單個參數(shù)
@RequestMapping("/sayhi")
public String sayHi(String name){
return "hi " + name;
}
這里地址欄里 key 必須寫"name", 才能成功拿到 value
如果傳了錯誤的 key 或者不傳參數(shù) ,結(jié)果就是String 的默認值 null
@RequestMapping("/sayhi2")
public String sayHi2(Integer id){
return "hi " + id;
}
@RequestMapping("/sayhi3")
public String sayHi3(int id){
return "hi " + id;
}
參數(shù)傳遞不要使用基本數(shù)據(jù)類型(如 int)。
@RequestMapping("/sayhi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response){
return "hi " + request.getParameter("name");
}
@RequestMapping("/sayhi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect("https://www.sogou.com");
}
還可以實現(xiàn)重定向跳轉(zhuǎn)頁面。
獲取多個參數(shù)
@RequestMapping("/sayhi")
public String sayHi(String name, String password){
return "name = " + name + " | password = " + password;
}
參數(shù)順序不重要,保證 key 正確就行。
傳遞對象
@Data
public class Userinfo {
private int id;
private String name;
private String password;
private int age;
}
//獲取對象
@RequestMapping("/reg")
public Object reg(Userinfo userinfo){
return userinfo;
}
@RequestMapping("/h1")
public Object getH1(){
return "<h1>我是 h1</h1>";
}
后端參數(shù)重命名
某些特殊的情況下,前端傳遞的參數(shù) key 和我們后端接收的 key 可以不?致, 比如前端傳遞一個 username 給后端,后端用 name 接收,這樣就會出現(xiàn)參數(shù)接收不到的情況,如果出現(xiàn)這種情況,我們就可以使用@RequestParam 來重命名前后端的參數(shù)值。
@RequestMapping("/reg2")
public Object reg(@RequestParam("username") String name, String password){
return "name = " + name + " | password = " + password;
}
如果前端傳的是 name, 會怎樣?
規(guī)定 前端必須傳 “username”.
@RequestMapping("/reg2")
public Object reg(@RequestParam(value = "username",required = false) String name,
String password){
return "name = " + name + " | password = " + password;
}
required = false 設(shè)置之后
前端:對象/JSON 對象字符串
后端:對象/JSON 對象字符串
@RequestBody 接收JSON對象
用之前接收對象的方式,不能成功接收到 JSON 對象。
@RequestMapping("/reg")
public Object reg(Userinfo userinfo){
System.out.println(userinfo);
return userinfo;
}
用 postman 發(fā)送一個 post 請求。
用 @RequestBody 這個注解就可以成功接收到 JSON 對象了。
@RequestMapping("/reg3")
public Object reg3(@RequestBody Userinfo userinfo){
return userinfo;
}
獲取URL中參數(shù)@PathVariable
/user?uid=12345
/user/12345 優(yōu)點:搜索引擎抓取關(guān)鍵字權(quán)重更高,更簡潔
@RequestMapping("/reg4/{name}/{password}")
public Object reg4(@PathVariable String name, @PathVariable String password){
return "name = " + name + " | password = " + password;
}
如果把路徑里的 password 改成 pwd,會怎樣?
這個參數(shù)是必須的。所以會報錯。
@RequestMapping("/reg4/{name}/{pwd}")
public Object reg4(@PathVariable String name, @PathVariable(required = false) String password){
return "name = " + name + " | password = " + password;
}
加 required = false 之后就不會報錯,但是 還是得不到 password 的值。
小結(jié):
@PathVariable: 基礎(chǔ) url 里面的參數(shù)(? 之前的參數(shù))
@RequestParam: url 參數(shù)部分的參數(shù)(? 之后的參數(shù))
@RequestMapping("/reg4/{name}/{pwd}")
public Object reg4(@PathVariable String name, @PathVariable(required = false,name = "pwd") String password){
return "name = " + name + " | password = " + password;
}
上傳文件@RequestPart
@RequestMapping("/myupload")
public Object upload(@RequestPart("myimg")MultipartFile file){
File saveFile = new File("D:\\Data\\myimg.png");
try {
file.transferTo(saveFile);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
用 postman 發(fā)送 post 請求:
文件上傳成功。
默認要求上傳單個文件大小不超過 1MB.
Common Application Properties (spring.io)
如果我要上傳的文件很大怎么辦?
可以設(shè)置上傳文件大小。
有一個問題,后面上傳的文件會把之前的文件覆蓋。
MySQL -> InnoDB(5.5) -> B+存儲 -> 聚簇索引樹
葉子(數(shù)據(jù)頁) 主鍵(如果有) + 數(shù)據(jù)
- 如何保證每次上傳的文件不會覆蓋?也就是最終保存的是不同的文件名。
UUID。
//上傳文件
@RequestMapping("/myupload")
public Object upload(@RequestPart("myimg")MultipartFile file){
String fileName = UUID.randomUUID() + //文件名
file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//后綴名
File saveFile = new File("D:\\Data\\" + fileName);
try {
file.transferTo(saveFile);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
成功上傳,沒有覆蓋原有的。
獲取Cookie/Session/header
//獲取 cookie
@RequestMapping("/getCookie")
public Object getCookie(@CookieValue(value = "java",required = false) String java){
return "java = " + java;
}
我們可以手動構(gòu)造一個 cookie。
- 獲取 Header
//獲取 header
@RequestMapping("/header")
public Object getHeader(@RequestHeader("user-agent") String userAgent){
return "userAgent = " + userAgent;
}
- 獲取 Session
private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
//存儲 session
@RequestMapping("/setSession")
public void setSession(HttpServletRequest request){
HttpSession session = request.getSession();//沒有就創(chuàng)建,默認是 true
session.setAttribute(SESSION_KEY,"zhangsan");
}
//獲取 session
@RequestMapping("/session")
public Object getSession(@SessionAttribute(SESSION_KEY) String name){
return "session = " + name;
}
返回數(shù)據(jù)
1)返回靜態(tài)頁面
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/getIndex")
public Object getIndex(){
return "index.html";
}
}
確認 target 下有 index.html.
那是什么原因?
加了"/"之后就能訪問成功了。
加了"/“表示是 從根目錄去找"index.html”, 不加"/"是在 test 目錄下去找 "index.html"就找不到.
2)請求轉(zhuǎn)發(fā)或請求重定向
1.請求轉(zhuǎn)發(fā)
//請求轉(zhuǎn)發(fā)
@RequestMapping("/forward")
public String forward(){
return "forward:/index.html";
//return "/index.html"; 默認就是請求轉(zhuǎn)發(fā)
}
2.請求重定向
//請求重定向
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/index.html";
}
@RequestMapping("/redirect2")
public void redirect2(HttpServletResponse response) throws IOException {
response.sendRedirect("https://www.baidu.com");
}
forward 和 redirect 具體區(qū)別如下:
- 請求重定向(redirect)將請求重新定位到資源;請求轉(zhuǎn)發(fā)(forward)服務(wù)器端轉(zhuǎn)發(fā)。
- 請求重定向地址發(fā)生變化,請求轉(zhuǎn)發(fā)地址不發(fā)?變化。
- 請求重定向,不存在原來的外部資源不能訪問;請求轉(zhuǎn)發(fā)服務(wù)器端轉(zhuǎn)發(fā) 有可能造成原外部資源不能訪問。
舉例:
請求轉(zhuǎn)發(fā):張三找李四借錢,李四自己也沒錢,李四又去找王五借,最終張三只借了一次錢,剩下的事都是 李四干的。
請求重定向:張三找李四借錢,李四自己也沒錢,李四告訴張三說自己沒錢讓張三去找王五借錢。然后張三又去找王五借到了錢。文章來源:http://www.zghlxwxcb.cn/news/detail-462161.html
請求轉(zhuǎn)發(fā)和請求重定向有什么區(qū)別? | Java?? 面試突擊 (javacn.site)文章來源地址http://www.zghlxwxcb.cn/news/detail-462161.html
到了這里,關(guān)于SpringMVC 程序開發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!