【Spring MVC】Spring MVC基于注解的程序開發

目錄

一、什么是Spring MVC

?二、Spring MVC項目的創建和使用

1、實現客戶端和服務器端之間的連接

1.1、RequsestMapping注解

1.2、@RequestMapper的簡單使用?

1.3、使用@GetMapping和@POSTMapping注解來實現HTTP連接

三、獲取參數

1、實現獲取單個參數

2、實現獲取對象

3、后端參數重命名(@RequestParam參數映射)

?4、@RequestParam參數必傳設置

?5、接收JSON對象(@RequestBody)

6、獲取URL中參數(@PathVariable)

?7、上傳文件(@RequestPart)

8、獲取Cookie/Session/header

四、返回數據

1、返回一個靜態頁面

?2、返回一個數據

?3、返回text/html

4、請求轉發和請求重定向


一、什么是Spring MVC

官方的描述為Spring Web MVC是基于Servlet API的原始Web框架,從一開始就包含在Spring框架中。它的正式名稱Spring Web MVC”來自它的源模塊(Spring -webmvc)的名稱,但它更常被稱為“Spring MVC”。

?理解Web框架

Web框架(Web framework)是用來進行Web應用開發的一個軟件架構。主要用于動態網絡開發,Web應用框架提供了一套開發和部署網站的方式。開發者基于框架實現自己的業務邏輯。使用Web框架很多的業務邏輯的功能不需要自己去完善,而是使用框架已有的功能就可以。

?什么是MVC?

MVC是Model View Controller的縮寫,它是軟件工程中的一種軟件件架構模式,他將一個項目分為三部分:View(試圖),Controller(控制器),Model(模型)。MVC是一種思想

  • Model(模型):項目中用于處理程序數據邏輯的部分,負責在數據庫中查找和存儲數據。
  • View(試圖):是項目中將得到的數據進行處理之后,顯示給用戶一個界面的部分。
  • Controller(控制器):是項目中處理用戶交互的部分,負責讀取用戶的請求,向模型提價請求,讀取模型的響應,將數據交給View部分。

?MVC和Spring MVC的關系

MVC是一種思想,Spring MVC是對MVC思想的具體實現。

Spring MVC是一個實現了MVC模式,并繼承了Servlwt API的Web框架。

?二、Spring MVC項目的創建和使用

Spring MVC項目的創建步驟和Spring Boot的創建步驟是相同的,我們之前創建的Spring Boot項目就相當于是一個Spring Web項目,我們在添加Spring Boot框架的時候,已經引入了Spring MVC。

下圖中spring-boot-starter-web表示的就是Spring MVC框架。

1、實現客戶端和服務器端之間的連接

1.1、RequsestMapping注解

@ResquestMapping是Spring Web應用程序中最常用到的注解之一,他是用來注冊接口的的路由映射的。

路由映射:所謂的路由隱射指的就是,當用戶訪問一個URL時,將用戶的請求對應到程序中某個類的某個方法的過程就叫做路由映射。

? @RequestMapping注解的參數

  • value:指定請求的實際訪問地址,value屬性是@RequestMapping注解的默認屬性,如果只有唯一一個屬性,則可以省略value字段,如果參數中有多個屬性,則必須寫上value屬性名。
  • path:與value同義,他們在源碼中相互引用,value和path都是用來作為映射使用的。
  • method:用來指定請求的類型,當在一個方法的注解@RequestMapping的參數中寫道method = RequestMethod.GET表示這個方法只支持GET請求。
  • params:該屬性指定,請求中必須包含params屬性指定的參數時,才能執行該請求。
  • headers:該屬性指定,請求中必須包含某些指定的header值,才能夠讓該方法處理請求。
  • consumes:指定處理請求的提交內容類型(Content-Type),才能讓該方法處理請求
  • produces:指定返回的內容類型,返回的內容類型必須時request請求頭中所包含的類型。這個屬性還可以指定返回值的編碼。

1.2、@RequestMapper的簡單使用?

  • @RequestMapping既可以修飾類,也可以修飾方法,當同時修飾類和方法時,類上的@ResquestMapping注解的參數value/path,表示的是URL中的一級路由,方法上的參數的value/path表示的是URL的二級路由。
  • @RequestMapper注解默認情況下支持GET和POST請求。

🍂下面我們創建一個類,來實現客戶端和Spring程序的連接,使用postman模擬客戶端發送請求。驗證@RequsetMapper注解既可以修飾類也可以修飾方法和@RequestMapper注解默認支持GET和POST請求。

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping("/sayHi")public String sayHi(){return "你好 Spring MVC";}
}

?我們使用URL為127.0.0.1:8080/test/sayHi

1??我們使用POST請求,可以收到響應。

?2??我們使用GET方法發送請求,也可以收到響應

?🍂當然我們可以設置@RequestMapping注解的Method屬性值為RequeatMethod.POST,表示這個方法只支持POST請求

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {//當這個注解中的參數有多個的時候,就需要添加屬性名稱@RequestMapping(value = "/sayHi",method = RequestMethod.POST)public String sayHi(){return "你好 Spring MVC";}
}

?

?🍂@RequestMapper支持設置多級目錄

@RequestMapping("/sayHi/mvc")

?


1.3、使用@GetMapping和@POSTMapping注解來實現HTTP連接

@GetMapping注解只能實現GET請求的連接,@POSTMapping注解只能實現POST請求的連接。

🍂@GetMapping注解

package com.example.demo.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@GetMapping("sayhi2")public String sayHi2(){return "你好,世界";}
}

?

?🍂@PostMapping注解

package com.example.demo.controller;import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@PostMapping("sayhello")public String sayHi2(){return "你好,世界";}
}

?

?


三、獲取參數

1、實現獲取單個參數

1??使用servlet的寫法(getParameter)來實現獲取單個參數


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;@RestController
@RequestMapping("/test2")
public class TestController2 {@RequestMapping("/getname")public String getName(HttpServletRequest request){return "Name:"+ request.getParameter("name");}
}

?2??使用更簡單的獲取單個參數的方法

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test2")
public class TestController2 {@RequestMapping("/getname2")public String getName2(String name){return "Name: "+name;}
}

?


2、實現獲取對象

上面獲取單個參數的方式,當參數個數固定的時候可以使用,但是如果參數個數不確定,隨時都需要添加參數的時候,我們這個時候可以使用獲取對象的方式獲取參數,前端沒有對象的概念,傳遞的都是對象的屬性,后端代碼中需要創建一個(用戶)類的對象,用來接收前端傳過來的屬性的值。

package com.example.demo.model;import lombok.Data;@Data
public class User {private int id;private String name;private String password;private int age;
}package com.example.demo.controller;import com.example.demo.model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/add")public User add(User user){return user;}
}

?當前端的屬性和后端中類的屬性對應不全的時候,如果后端沒有相應的屬性,那么前端的屬性賦值不到后端的代碼中,如果前端沒有相應的后端代碼中的屬性,那么后端中類的屬性的值就是默認值。


3、后端參數重命名(@RequestParam參數映射)

特殊情況下,前端傳遞的參數key和我們后端接收的key可以不一致,比如前端傳遞了一個n給后端,而后端使用的時name參數來接收的,這個時候就會出現參數接收不到的問題,我們可以使用@RequestParam注解來重命名前后端的參數。


import com.example.demo.model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/name")public String name(@RequestParam ("n") String name){return name;}
}

?4、@RequestParam參數必傳設置

使用@RequestParam注解之后,那么這個屬性就變成了必傳的參數了,不傳這個參數就會報錯,原因是因為@RequestParam注解中有一個required屬性等于true,表示這個參數為必傳的,我們只需要設置這個屬性為false即可解決必傳的問題。

?

    @RequestMapping("/name")public String name(@RequestParam (value="n",required = false) String name){return name;}

?5、接收JSON對象(@RequestBody)

這里只需要使用@RequestBody就可以拿到前端傳遞的JSON對象

    @RequestMapping("/add_json")public User addByJson(@RequestBody User user){return user;}

?


6、獲取URL中參數(@PathVariable)

之前我們是通過URL中的查詢字符串的部分獲取的參數,也就是name="xxx"&id=123的部分。但是有點網站不是通過這樣的方式傳遞參數的,就像掘金一樣。訪問它的有些頁面時URL是這樣的https://juejin.cn/user/61228381386487。他沒有通過查詢字符串的方式傳遞。

1??從前端獲取一個參數

    @RequestMapping("/detial/{id}")public Integer detail(@PathVariable("id") Integer id){return id;}

?這里表示前端要傳遞的參數為id,所以這里需要使用一個{}將這個參數括起來

2??表示從前端獲取多參數

    @RequestMapping("/detial/{id}/{name}")public String detail(@PathVariable("id") Integer id,@PathVariable("name") String name){return "id: "+id+" "+"name: "+name;}

?7、上傳文件(@RequestPart)

@RequestPart用于將multiparty/form-data類型的數據映射到控制器處理方法的參數中。

    @RequestMapping("/upload")public String upload(@RequestPart("myfile") MultipartFile file) throws IOException {String path = "D:/img.png";file.transferTo(new File(path));return path;}
}

這里@RequestPart("file")表示從請求中獲取名為"file"的文件,長傳的文件將被存儲在file對象中,我們可以是以哦那個file對象的方法類處理上傳的文件。

?在D盤中獲取到了這個圖片文件,并將圖片名字改為了img

但是這樣編寫的后端代碼存在問題,就是客戶端每次訪問服務器程序,服務器返回的圖片名字都是一樣的,那么在D盤中,后面獲取的圖片會將之前獲取的覆蓋掉,這是不完善的,如果在客戶端點擊上傳的圖片不同,最終服務器將不同的圖片名字改成一樣的,兩張不同的照片只能保存其中一個。

?下面我們來解決這個問題

這里將路徑中的文件名通過生成一個全球唯一id得到的,文件類型是截取原文件的。

    @RequestMapping("/upload")public String upload(@RequestPart("myfile") MultipartFile file) throws IOException {//1、生成一個唯一的id(UUID就是全球唯一ID,他是由MAC地址+隨機數+加密算法組成的,保證生成的id是全球唯一ID)String name = UUID.randomUUID().toString().replace("-","");//2、得到源文件的后綴名name += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));String path = "D:/"+name;//將文件保存在path路徑中file.transferTo(new File(path));return path;}

可以看見每次獲取的文件名稱都是不一樣的,也不會將之前獲取的文件覆蓋掉。

?


8、獲取Cookie/Session/header

?通過@CookieValue獲取Cookie

    @RequestMapping("/getcookie")public String getCookie(@CookieValue("java")String ck){return ck;}

?通過@CookieValue注解類獲取Session

    @RequestMapping("/getsess")//這里的value指的是session的名字public String getSess(@SessionAttribute(value="username",required = false) String username){return username;}

通過@RequestHeader獲取Header

// @RequestHeader 獲取 header
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {return "User-Agent: " + userAgent;
}

四、返回數據

1、返回一個靜態頁面

在項目中創建一個靜態的html頁面。使用@Controller注解默認的是返回一個頁面

package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class TestController3 {@RequestMapping("/hello")public String index(){return "hello.html";}}

?

?2、返回一個數據

使用@ResponseBody和@Controller注解搭配使用,讓返回的值是一個數據,也可以使用組合注解@RestController注解

package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@ResponseBody
public class TestController3 {@RequestMapping("/hello")public String index(){return "hello.html";}
}

?3、返回text/html

可以使用組合注解@RestController也可以使用@Controller和@ResponseBody搭配使用

@RestController
public class TestController3 {@RequestMapping("method")public String method(){return "<h1>hello,world!</h1>";}

4、請求轉發和請求重定向

return不僅可以返回一個試圖,還可以實現跳轉,跳轉的方式有兩種:

  • forward是請求轉發;
  • redirect是請求重定向。
// 請求重定向
@RequestMapping("/index1")
public String index1() {return "redirect:/index.html";
}
// 請求轉發
@RequestMapping("/index2")
public String index2() {return "forward:/index.html";
}

?請求重定向和請求轉發的區別

  • 請求轉發是一種服務器行為,客戶端只有一次請求,服務器接收到客戶端的請求之后,會先將請求轉發給目標地址,在將目標地址返回的結果轉發給客戶端。客戶端對這一切毫無感知。這就像A找B借錢,B沒有,B向C借到之后,將錢給了A,整個過程A就直借了一次錢。B向C借錢A不知道。
  • 請求重定向是指服務器端接收到客戶端的請求之后,會給客戶端返回一個臨時相應頭,這個響應頭中記錄了,客戶端需要再次發送請求(重定向)的URL地址,客戶端收到地址之后,會將請求發送到新的地址上,這就是請求重定向。就像A找B借錢,B沒有,但是B知道C有,B對A說C有,讓A 去C哪里借,然后A去找C去借,這個過程就是請求重定向。

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

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

相關文章

解決ubantu驅動掉了的問題

這里寫自定義目錄標題 解決ubuntu驅動掉了的問題 解決ubuntu驅動掉了的問題 首先確定是否有驅動&#xff1a; ls /usr/src | grep nvidia若有&#xff0c;則大概率是驅動版本與內核版本對應不上&#xff0c;則把內核版本切換為初始版本即可。參照&#xff1a;https://blog.cs…

書寫自動智慧:探索Python文本分類器的開發與應用:支持二分類、多分類、多標簽分類、多層級分類和Kmeans聚類

書寫自動智慧&#xff1a;探索Python文本分類器的開發與應用&#xff1a;支持二分類、多分類、多標簽分類、多層級分類和Kmeans聚類 文本分類器&#xff0c;提供多種文本分類和聚類算法&#xff0c;支持句子和文檔級的文本分類任務&#xff0c;支持二分類、多分類、多標簽分類…

nodejs+vue+elementui+express智慧社區小區物業管理系統的設計與實現_2p760

開發語言 node.js 框架&#xff1a;Express 前端:Vue.js 數據庫&#xff1a;mysql 數據庫工具&#xff1a;Navicat 開發軟件&#xff1a;VScode 前端nodejsvueelementuiexpress vue的文件結構其實就是一個index.html 中間的內容&#xff0c;用的是vue&#xff0c;但最終都會轉…

OpenCV圖像處理——形態學操作

目錄 連通性形態學操作腐蝕和膨脹開閉運算禮帽和黑帽 連通性 形態學操作 形態學轉換是基于圖像形狀的一些簡單操作。它通常在二進制圖像上執行。腐蝕和膨脹時兩個基本的形態學運算符。然后它的變體形式如開運算&#xff0c;閉運算&#xff0c;禮帽黑帽等 腐蝕和膨脹 cv.erode…

費曼學習法

費曼學習法 費曼學習法&#xff08;Feynman Technique&#xff09;是一種學習和理解復雜概念的方法&#xff0c;以理查德費曼&#xff08;Richard Feynman&#xff09;這位著名的理論物理學家命名。該方法的核心思想是通過將學習內容簡化并用自己的話解釋給別人&#xff0c;來…

Node.js學習筆記-04

這第九章也是個大重點 九、玩轉進程 Node在選型時決定在V8引擎之上構建&#xff0c;也就意味著它的模型與瀏覽器類似。 本章關于進程的介紹和討論將會解決如下兩個問題&#xff1a; 單進程單線程并非完美&#xff0c;如今CPU基本均是多核的&#xff0c;真正的服務器&#xf…

背上小書包準備面試之TypeScript篇

目錄 typescript是啥&#xff1f;與javascript的區別&#xff1f; typescript數據類型&#xff1f; typescript中枚舉類型&#xff1f;應用場景&#xff1f; typescript中接口的理解&#xff1f;應用場景&#xff1f; typescript中泛型的理解&#xff1f;應用場景&#xf…

輕薄的ESL電子標簽有哪些特性?

在智慧物聯逐漸走進千萬家的當下&#xff0c;技術變革更加日新月異。ESL電子標簽作為科技物聯的重要組成部分&#xff0c;是推動千行百業數字化轉型的重要技術&#xff0c;促進物聯網產業的蓬勃發展。在智慧零售、智慧辦公、智慧倉儲等領域&#xff0c;ESL電子標簽在未來是不可…

win11右下角圖標(網絡,音量,電量)點擊無反應問題,兩分鐘解決!

win11系統用的好好的&#xff0c;突然有一天任務欄右下角的常用三件套&#xff08;網絡&#xff0c;音量&#xff0c;電量&#xff09;左鍵單擊沒反應&#xff0c;無法方便的調節音量和連接wifi&#xff0c;如下圖所示&#xff0c;但是右鍵好用&#xff0c;不過不方便。網上查了…

嵌入式 C 語言程序數據基本存儲結構

一、5大內存分區 內存分成5個區&#xff0c;它們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。 1、棧區(stack)&#xff1a;FIFO就是那些由編譯器在需要的時候分配&#xff0c;在不需要的時候自動清除的變量的存儲區。里面的變量通常是局部變量、函數參數等。 ?…

【Windows API】獲取卷標、卷名

1、卷->卷標 使用FindFirstVolume()和FindNextVolume()函數體系&#xff0c;枚舉系統所有卷&#xff08;Volume&#xff09;的例子&#xff0c;然后獲取卷標、卷類型。這個方式可以枚舉出沒有驅動器號&#xff08;卷標&#xff09;的卷。 int TestMode1() {HANDLE hVolume…

Failed to connect to bitbucket.org port 443

瀏覽器可以訪問bitbucket&#xff0c;但是在終端或者sourcetree上死活無法進行pull, push等操作。 Root Cause&#xff1a;“【翻】【墻】軟件”使用了http proxy&#xff0c;所以也得為git設置相同的http proxy。 所以&#xff0c;解決方法是&#xff1a; 1&#xff0c;查看“…

網絡系統架構演變

1.系統架構演變 隨著互聯網的發展&#xff0c;網站應用的規模不斷擴大。需求的激增&#xff0c;帶來的是技術上的壓力。系統架構也因此不斷的演進、升級、迭代。從單一應用&#xff0c;到垂直拆分&#xff0c;到分布式服務&#xff0c;到SOA&#xff0c;以及現在火熱的微服務架…

【Django】無法從“django.utils.encoding”導入名稱“force_text”

整晚處理 Django 的導入錯誤。 我將把它作為提醒&#xff0c;希望處于相同情況的人數會減少。 原因 某些軟件包版本不支持Django 4 請看下表并決定Django和Python的版本 方案 如果出現難以響應&#xff0c;或者更改環境麻煩&#xff0c;請嘗試以下操作 例如出現以下錯誤 …

云計算的發展前景怎么樣

云計算是當前科技領域中最受關注的領域之一,它的出現改變了傳統的計算模式,使得企業和個人能夠更加便捷地訪問和使用計算資源。隨著云計算技術的不斷發展,它的前景也變得更加光明。 以下是云計算的發展前景: 云計算的市場份額將繼續增長:根據市場研究機構的報告,云計算的市場份…

vfuhyuuy

Sublime Text is an awesome text editor. If you’ve never heard of it, you shouldcheck it out right now. I’ve made this tutorial because there’s no installer for the Linux versions of Sublime Text. While that’s not a real problem, I feel there is a clean…

通過版本號控制強制刷新瀏覽器或清空瀏覽器緩存

背景介紹 在我們做 web 項目時&#xff0c;經常會遇到一個問題就是&#xff0c;需要 通知業務人員&#xff08;系統用戶&#xff09;刷新瀏覽器或者清空瀏覽器 cookie 緩存的情況。 而對于用戶而言&#xff0c;很多人一方面不懂如何操作&#xff0c;另一方面由于執行力問題&am…

Android descendantFocusability 屬性

view 焦點問題處理 作用 通過該屬性可以指定viewGroup和其子View到底誰獲取焦點&#xff0c; 直接在viewGroup上使用就行。 屬性值 屬性值含義beforeDescendantsviewgroup會優先其子類控件而獲取到焦點afterDescendantsviewgroup只有當其子類控件不需要獲取焦點時才獲取焦點…

MFC創建和使用OCX控件

文章目錄 MFC建立OCX控件注冊OCX控件與反注冊使用Internet Explorer測試ocx控件OCX控件添加方法OCX控件添加事件Web使用OCX控件MFC使用OCX控件使用OCX控件調用ocx的功能函數對ocx的事件響應OCX控件調試工具tstcon32.exe加載ocx控件使用tstcon32.exe調試ocxMFC建立OCX控件 新建…

【ChatGPT 指令大全】怎么使用ChatGPT來輔助知識學習

目錄 概念解說 簡易教學 深度教學 教學與測驗 解釋一個主題的背后原理 總結 在當今信息時代&#xff0c;互聯網的快速發展為我們獲取知識提供了前所未有的便利。而其中&#xff0c;人工智能技術的應用也為我們的學習和交流帶來了新的可能性。作為一種基于自然語言處理的人…