日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

@RequestParam详解

發(fā)布時間:2025/3/12 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 @RequestParam详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

@RequestParam

主要用于將請求參數(shù)區(qū)域的數(shù)據(jù)映射到控制層方法的參數(shù)上

首先我們需要知道@RequestParam注解主要有哪些參數(shù)

  • value:請求中傳入?yún)?shù)的名稱,如果不設(shè)置后臺接口的value值,則會默認(rèn)為該變量名。比如上圖中第一個參數(shù)如果不設(shè)置value=“page”,則前端傳入的參數(shù)名必須為pageNum,否則在后臺接口中pageNum將接收不到對應(yīng)的數(shù)據(jù)

  • required:該參數(shù)是否為必傳項。默認(rèn)是true,表示請求中一定要傳入對應(yīng)的參數(shù),否則會報404錯誤,如果設(shè)置為false時,當(dāng)請求中沒有此參數(shù),將會默認(rèn)為null,而對于基本數(shù)據(jù)類型的變量,則必須有值,這時會拋出空指針異常。如果允許空值,則接口中變量需要使用包裝類來聲明。

  • defaultValue:參數(shù)的默認(rèn)值,如果請求中沒有同名的參數(shù)時,該變量默認(rèn)為此值。注意默認(rèn)值可以使用SpEL表達(dá)式,如"#{systemProperties[‘java.vm.version’]}"

  • 如果在請求中傳入多個同名參數(shù),比如:url?userName=zhl&userName=holley時怎么辦?

    其實此時傳入的數(shù)據(jù)格式是:“zhl,holley”,即多個數(shù)據(jù)之間使用逗號分隔開,在后臺接口中可以使用數(shù)組或者list類型的變量來接收:

    public String requestparam8(@RequestParam(value="userName") String [] userNames) 或者 public String requestparam8(@RequestParam(value="list") List<String> list)

    @PathVariable綁定uri模板變量值:通過@PathVariable可以綁定占位符參數(shù)到方法參數(shù)中,例如:


    如果請求為"url/info/16",則spring會自動將16綁定到通過@PathVariable注解的同名變量uid上

    @CookieValue綁定Cookie數(shù)據(jù)值

    @CookieValue用于將請求的Cookie數(shù)據(jù)映射到功能處理方法的參數(shù)上。

    public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId)

    如上配置將自動將JSESSIONID值入?yún)⒌絪essionId參數(shù)上,defaultValue表示Cookie中沒有JSESSIONID時默認(rèn)為空。

    public String test2(@CookieValue(value="JSESSIONID", defaultValue="") Cookie sessionId)

    傳入?yún)?shù)類型也可以是javax.servlet.http.Cookie類型

    測試代碼在CookieValueTypeController中。@CookieValue也擁有和@RequestParam相同的三個參數(shù),含義一樣。

    @RequestHeader綁定請求頭數(shù)據(jù)

    @RequestHeader用于將請求的頭信息區(qū)數(shù)據(jù)映射到功能處理方法的參數(shù)上。

    @RequestMapping(value="/header") public String test( @RequestHeader("User-Agent") String userAgent, @RequestHeader(value="Accept") String[] accepts)

    如上配置將自動將請求頭“User-Agent”值入?yún)⒌絬serAgent參數(shù)上,并將“Accept”請求頭值入?yún)⒌絘ccepts參數(shù)上。測試代碼在HeaderValueTypeController中。

    @RequestHeader也擁有和@RequestParam相同的三個參數(shù),含義一樣。

    @ModelAttribute綁定請求參數(shù)到命令對象

    @ModelAttribute一個具有如下三個作用:

    ①綁定請求參數(shù)到命令對象:放在功能處理方法的入?yún)⑸蠒r,用于將多個請求參數(shù)綁定到一個命令對象,從而簡化綁定流程,而且自動暴露為模型數(shù)據(jù)用于視圖頁面展示時使用;

    ②暴露表單引用對象為模型數(shù)據(jù):放在處理器的一般方法(非功能處理方法)上時,是為表單準(zhǔn)備要展示的表單引用對象,如注冊時需要選擇的所在城市等,而且在執(zhí)行功能處理方法(@RequestMapping注解的方法)之前,自動添加到模型對象中,用于視圖頁面展示時使用;

    ③暴露@RequestMapping方法返回值為模型數(shù)據(jù):放在功能處理方法的返回值上時,是暴露功能處理方法的返回值為模型數(shù)據(jù),用于視圖頁面展示時使用。

    一、綁定請求參數(shù)到命令對象

    如用戶登錄,我們需要捕獲用戶登錄的請求參數(shù)(用戶名、密碼)并封裝為用戶對象,此時我們可以使用@ModelAttribute綁定多個請求參數(shù)到我們的命令對象。

    public String test1(@ModelAttribute("user") UserModel user)

    它的作用是將該綁定的命令對象以“user”為名稱添加到模型對象中供視圖頁面展示使用。我們此時可以在視圖頁面使用${user.username}來獲取綁定的命令對象的屬性。

    綁定請求參數(shù)到命令對象支持對象圖導(dǎo)航式的綁定,如請求參數(shù)包含“?username=zhang&password=123&workInfo.city=bj”自動綁定到user中的workInfo屬性的city屬性中。

    @RequestMapping(value="/model2/{username}") public String test2(@ModelAttribute("model") DataBinderTestModel model) {

    DataBinderTestModel相關(guān)模型請從第三章拷貝過來,請求參數(shù)到命令對象的綁定規(guī)則詳見【4.16.1、數(shù)據(jù)綁定】一節(jié),URI模板變量也能自動綁定到命令對象中,當(dāng)你請求的URL中包含“bool=yes&schooInfo.specialty=computer&hobbyList[0]=program&hobbyList[1]=music&map[key1]=value1&map[key2]=value2&state=blocked”會自動綁定到命令對象上。

    當(dāng)URI模板變量和請求參數(shù)同名時,URI模板變量具有高優(yōu)先權(quán)。

    二、暴露表單引用對象為模型數(shù)據(jù)

    @ModelAttribute("cityList") public List<String> cityList() { return Arrays.asList("北京", "山東"); }

    如上代碼會在執(zhí)行功能處理方法之前執(zhí)行,并將其自動添加到模型對象中,在功能處理方法中調(diào)用Model 入?yún)⒌腸ontainsAttribute(“cityList”)將會返回true。

    @ModelAttribute("user") //① public UserModel getUser(@RequestParam(value="username", defaultValue="") String username) { //TODO 去數(shù)據(jù)庫根據(jù)用戶名查找用戶對象 UserModel user = new UserModel(); user.setRealname("zhang"); return user; }

    如你要修改用戶資料時一般需要根據(jù)用戶的編號/用戶名查找用戶來進行編輯,此時可以通過如上代碼查找要編輯的用戶。

    也可以進行一些默認(rèn)值的處理。

    @RequestMapping(value="/model1") //② public String test1(@ModelAttribute("user") UserModel user, Model model)

    此處我們看到①和②有同名的命令對象,那Spring Web MVC內(nèi)部如何處理的呢:

    (1、首先執(zhí)行@ModelAttribute注解的方法,準(zhǔn)備視圖展示時所需要的模型數(shù)據(jù);@ModelAttribute注解方法形式參數(shù)規(guī)則和@RequestMapping規(guī)則一樣,如可以有@RequestParam等;

    (2、執(zhí)行@RequestMapping注解方法,進行模型綁定時首先查找模型數(shù)據(jù)中是否含有同名對象,如果有直接使用,如果沒有通過反射創(chuàng)建一個,因此②處的user將使用①處返回的命令對象。即②處的user等于①處的user。

    三、暴露@RequestMapping方法返回值為模型數(shù)據(jù)

    public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user)

    大家可以看到返回值類型是命令對象類型,而且通過@ModelAttribute(“user2”)注解,此時會暴露返回值到模型數(shù)據(jù)(名字為user2)中供視圖展示使用。那哪個視圖應(yīng)該展示呢?此時Spring Web MVC會根據(jù)RequestToViewNameTranslator進行邏輯視圖名的翻譯.

    此時又有問題了,@RequestMapping注解方法的入?yún)ser暴露到模型數(shù)據(jù)中的名字也是user2,其實我們能猜到:

    (3、@ModelAttribute注解的返回值會覆蓋@RequestMapping注解方法中的@ModelAttribute注解的同名命令對象。

    四、匿名綁定命令參數(shù)

    public String test4(@ModelAttribute UserModel user, Model model)public String test5(UserModel user, Model model)

    此時我們沒有為命令對象提供暴露到模型數(shù)據(jù)中的名字,此時的名字是什么呢?Spring Web MVC自動將簡單類名(首字母小寫)作為名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字為“userModel”。

    public @ModelAttribute List<String> test6()public @ModelAttribute List<UserModel> test7()

    對于集合類型(Collection接口的實現(xiàn)者們,包括數(shù)組),生成的模型對象屬性名為“簡單類名(首字母小寫)”+“List”,如List生成的模型對象屬性名為“stringList”,List生成的模型對象屬性名為“userModelList”。

    其他情況一律都是使用簡單類名(首字母小寫)作為模型對象屬性名,如Map<String, UserModel>類型的模型對象屬性名為“map”。

    @SessionAttributes綁定命令對象到session

    有時候我們需要在多次請求之間保持?jǐn)?shù)據(jù),一般情況需要我們明確的調(diào)用HttpSession的API來存取會話數(shù)據(jù),如多步驟提交的表單。Spring Web MVC提供了@SessionAttributes進行請求間透明的存取會話數(shù)據(jù)。

    //1、在控制器類頭上添加@SessionAttributes注解 @SessionAttributes(value = {"user"}) //① public class SessionAttributeController //2、@ModelAttribute注解的方法進行表單引用對象的創(chuàng)建 @ModelAttribute("user") //② public UserModel initUser() //3、@RequestMapping注解方法的@ModelAttribute注解的參數(shù)進行命令對象的綁定 @RequestMapping("/session1") //③ public String session1(@ModelAttribute("user") UserModel user) //4、通過SessionStatus的setComplete()方法清除@SessionAttributes指定的會話數(shù)據(jù) @RequestMapping("/session2") //③ public String session(@ModelAttribute("user") UserModel user, SessionStatus status) { if(true) { //④ status.setComplete(); } return "success"; }

    @SessionAttributes(value = {“user”})含義:

    @SessionAttributes(value = {“user”}) 標(biāo)識將模型數(shù)據(jù)中的名字為“user” 的對象存儲到會話中(默認(rèn)HttpSession),此處value指定將模型數(shù)據(jù)中的哪些數(shù)據(jù)(名字進行匹配)存儲到會話中,此外還有一個types屬性表示模型數(shù)據(jù)中的哪些類型的對象存儲到會話范圍內(nèi),如果同時指定value和types屬性則那些名字和類型都匹配的對象才能存儲到會話范圍內(nèi)。

    包含@SessionAttributes的執(zhí)行流程如下所示:

    ① 首先根據(jù)@SessionAttributes注解信息查找會話內(nèi)的對象放入到模型數(shù)據(jù)中;

    ② 執(zhí)行@ModelAttribute注解的方法:如果模型數(shù)據(jù)中包含同名的數(shù)據(jù),則不執(zhí)行@ModelAttribute注解方法進行準(zhǔn)備表單引用數(shù)據(jù),而是使用①步驟中的會話數(shù)據(jù);如果模型數(shù)據(jù)中不包含同名的數(shù)據(jù),執(zhí)行@ModelAttribute注解的方法并將返回值添加到模型數(shù)據(jù)中;

    ③ 執(zhí)行@RequestMapping方法,綁定@ModelAttribute注解的參數(shù):查找模型數(shù)據(jù)中是否有@ModelAttribute注解的同名對象,如果有直接使用,否則通過反射創(chuàng)建一個;并將請求參數(shù)綁定到該命令對象;

    此處需要注意:如果使用@SessionAttributes注解控制器類之后,③步驟一定是從模型對象中取得同名的命令對象,如果模型數(shù)據(jù)中不存在將拋出HttpSessionRequiredException Expected session attribute ‘user’(Spring3.1)

    或HttpSessionRequiredException Session attribute ‘user’ required - not found in session(Spring3.0)異常。

    ④ 如果會話可以銷毀了,如多步驟提交表單的最后一步,此時可以調(diào)用SessionStatus對象的setComplete()標(biāo)識當(dāng)前會話的@SessionAttributes指定的數(shù)據(jù)可以清理了,此時當(dāng)@RequestMapping功能處理方法執(zhí)行完畢會進行清理會話數(shù)據(jù)。

    我們通過Spring Web MVC的源代碼驗證一下吧,此處我們分析的是Spring3.1的RequestMappingHandlerAdapter,讀者可以自行驗證Spring3.0的AnnotationMethodHandlerAdapter,流程一樣:

    (1、RequestMappingHandlerAdapter.invokeHandlerMethod

    //1、RequestMappingHandlerAdapter首先調(diào)用ModelFactory的initModel方法準(zhǔn)備模型數(shù)據(jù): modelFactory.initModel(webRequest, mavContainer, requestMappingMethod); //2、調(diào)用@RequestMapping注解的功能處理方法 requestMappingMethod.invokeAndHandle(webRequest, mavContainer); //3、更新/合并模型數(shù)據(jù) modelFactory.updateModel(webRequest, mavContainer);

    (2、ModelFactory.initModel

    Map<String, ?> attributesInSession = this.sessionAttributesHandler.retrieveAttributes(request); //1.1、將與@SessionAttributes注解相關(guān)的會話對象放入模型數(shù)據(jù)中 mavContainer.mergeAttributes(attributesInSession); //1.2、調(diào)用@ModelAttribute方法添加表單引用對象 invokeModelAttributeMethods(request, mavContainer); //1.3、驗證模型數(shù)據(jù)中是否包含@SessionAttributes注解相關(guān)的會話對象,不包含拋出異常 for (String name : findSessionAttributeArguments(handlerMethod)) { if (!mavContainer.containsAttribute(name)) { //1.4、此處防止在@ModelAttribute注解方法又添加了會話對象 //如在@ModelAttribute注解方法調(diào)用session.setAttribute("user", new UserModel()); Object value = this.sessionAttributesHandler.retrieveAttribute(request, name); if (value == null) { throw new HttpSessionRequiredException("Expected session attribute '" + name + "'"); } mavContainer.addAttribute(name, value); }

    (3、ModelFactory.invokeModelAttributeMethods

    for (InvocableHandlerMethod attrMethod : this.attributeMethods) { String modelName = attrMethod.getMethodAnnotation(ModelAttribute.class).value(); //1.2.1、如果模型數(shù)據(jù)中包含同名數(shù)據(jù)則不再添加 if (mavContainer.containsAttribute(modelName)) { continue; } //1.2.2、調(diào)用@ModelAttribute注解方法并將返回值添加到模型數(shù)據(jù)中,此處省略實現(xiàn)代碼 }

    (4、requestMappingMethod.invokeAndHandle 調(diào)用功能處理方法,此處省略

    (5、ModelFactory.updateMode 更新模型數(shù)據(jù)

    //3.1、如果會話被標(biāo)識為完成,此時從會話中清除@SessionAttributes注解相關(guān)的會話對象 if (mavContainer.getSessionStatus().isComplete()){ this.sessionAttributesHandler.cleanupAttributes(request); } //3.2、如果會話沒有完成,將模型數(shù)據(jù)中的@SessionAttributes注解相關(guān)的對象添加到會話中 else { this.sessionAttributesHandler.storeAttributes(request, mavContainer.getModel()); } //省略部分代碼

    到此@SessionAtrribute介紹完畢,測試代碼在cn.javass.chapter6.web.controller.paramtype.SessionAttributeController中。

    另外cn.javass.chapter6.web.controller.paramtype.WizardFormController是一個類似于【AbstractWizardFormController】多步驟提交表單需要考慮會話超時問題,這種方式可能對用戶不太友好,我們可以采取隱藏表單(即當(dāng)前步驟將其他步驟的表單隱藏)或表單數(shù)據(jù)存數(shù)據(jù)庫(每步驟更新下數(shù)據(jù)庫數(shù)據(jù))等方案解決。

    @Value綁定SpEL表示式

    @Value用于將一個SpEL表達(dá)式結(jié)果映射到到功能處理方法的參數(shù)上。

    public String test(@Value("#{systemProperties['java.vm.version']}") String jvmVersion)

    到此數(shù)據(jù)綁定我們就介紹完了,對于沒有介紹的方法參數(shù)和注解(包括自定義注解)在后續(xù)章節(jié)進行介紹。接下來我們學(xué)習(xí)下數(shù)據(jù)類型轉(zhuǎn)換吧。

    總結(jié)

    以上是生活随笔為你收集整理的@RequestParam详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。