日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

使用 Spring 2.5 基于注解驱动的 Spring MVC(二)

發布時間:2025/4/5 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 Spring 2.5 基于注解驱动的 Spring MVC(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們在 ② 處添加了一個 ModelMap 屬性,其屬性名為 currUser,而 ① 處通過 @SessionAttributes 注解將 ModelMap 中名為 currUser 的屬性放置到 Session 中,所以我們不但可以在 listBoardTopic() 請求所對應的 JSP 視圖頁面中通過 request.getAttribute(“currUser”) 和 session.getAttribute(“currUser”) 獲取 user 對象,還可以在下一個請求所對應的 JSP 視圖頁面中通過 session.getAttribute(“currUser”) 或 ModelMap#get(“currUser”) 訪問到這個屬性。

這里我們僅將一個 ModelMap 的屬性放入 Session 中,其實 @SessionAttributes 允許指定多個屬性。你可以通過字符串數組的方式指定多個屬性,如 @SessionAttributes({“attr1”,”attr2”})。此外,@SessionAttributes 還可以通過屬性類型指定要 session 化的 ModelMap 屬性,如 @SessionAttributes(types = User.class),當然也可以指定多個類,如 @SessionAttributes(types = {User.class,Dept.class}),還可以聯合使用屬性名和屬性類型指定:@SessionAttributes(types = {User.class,Dept.class},value={“attr1”,”attr2”})。

上面 講述了如何往ModelMap中放置屬性以及如何使ModelMap中的屬性擁有Session域的作用范圍。除了在JSP視圖頁面中通過傳統的方法訪問 ModelMap中的屬性外,讀者朋友可能會問:是否可以將ModelMap中的屬性綁定到請求處理方法的入參中呢?答案是肯定的。Spring為此提供 了一個@ModelAttribute的注解,下面是使用@ModelAttribute注解的例子:

清單 11. 使模型對象的特定屬性具有 Session 范圍的作用域

package com.baobaotao.web;import com.baobaotao.service.BbtForumService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.annotation.ModelAttribute;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;@Controller @RequestMapping("/bbtForum.do") @SessionAttributes("currUser") //①讓ModelMap的currUser屬性擁有session級作用域 public class BbtForumController {@Autowired private BbtForumService bbtForumService;@RequestMapping(params = "method=listBoardTopic")public String listBoardTopic(@RequestParam("id")int topicId, User user, ModelMap model) {bbtForumService.getBoardTopics(topicId);System.out.println("topicId:" + topicId);System.out.println("user:" + user);model.addAttribute("currUser",user); //②向ModelMap中添加一個屬性return "listTopic";}@RequestMapping(params = "method=listAllBoard")//③將ModelMap中的 public String listAllBoard(@ModelAttribute("currUser") User user) { //currUser屬性綁定到user入參中。bbtForumService.getAllBoard();System.out.println("user:"+user);return "listBoard";} }

?

在 ② 處,我們向 ModelMap 中添加一個名為 currUser 的屬性,而 ① 外的注解使這個 currUser 屬性擁有了 session 級的作用域。所以,我們可以在 ③ 處通過 @ModelAttribute 注解將 ModelMap 中的 currUser 屬性綁定以請求處理方法的 user 入參中。

所以當我們先調用以下 URL 請求: http://localhost/bbtForum.do?method=listBoardTopic&id=1&userName=tom&dept.deptId=12

以執行listBoardTopic()請求處理方法,然后再訪問以下URL: http://localhost/sample/bbtForum.do?method=listAllBoard

你將可以看到 listAllBoard() 的 user 入參已經成功綁定到 listBoardTopic() 中注冊的 session 級的 currUser 屬性上了。

?



回頁首


請求處理方法的簽名規約

方法入參

我們知道標注了 @RequestMapping 注解的 Controller 方法就成為了請求處理方法,Spring MVC 允許極其靈活的請求處理方法簽名方式。對于方法入參來說,它允許多種類型的入參,通過下表進行說明:

請求處理方法入參的可選類型說明
Java 基本數據類型和 String默認情況下將按名稱匹配的方式綁定到 URL 參數上,可以通過 @RequestParam 注解改變默認的綁定規則
request/response/session既可以是 Servlet API 的也可以是 Portlet API 對應的對象,Spring 會將它們綁定到 Servlet 和 Portlet 容器的相應對象上
org.springframework.web.context.request.WebRequest內部包含了 request 對象
java.util.Locale綁定到 request 對應的 Locale 對象上
java.io.InputStream/java.io.Reader可以借此訪問 request 的內容
java.io.OutputStream / java.io.Writer可以借此操作 response 的內容
任何標注了 @RequestParam 注解的入參被標注 @RequestParam 注解的入參將綁定到特定的 request 參數上。
java.util.Map / org.springframework.ui.ModelMap它綁定 Spring MVC 框架中每個請求所創建的潛在的模型對象,它們可以被 Web 視圖對象訪問(如 JSP)
命令/表單對象(注:一般稱綁定使用 HTTP GET 發送的 URL 參數的對象為命令對象,而稱綁定使用 HTTP POST 發送的 URL 參數的對象為表單對象)它們的屬性將以名稱匹配的規則綁定到 URL 參數上,同時完成類型的轉換。而類型轉換的規則可以通過 @InitBinder 注解或通過 HandlerAdapter 的配置進行調整
org.springframework.validation.Errors / org.springframework.validation.BindingResult為屬性列表中的命令/表單對象的校驗結果,注意檢驗結果參數必須緊跟在命令/表單對象的后面
rg.springframework.web.bind.support.SessionStatus可以通過該類型 status 對象顯式結束表單的處理,這相當于觸發 session 清除其中的通過 @SessionAttributes 定義的屬性

Spring MVC 框架的易用之處在于,你可以按任意順序定義請求處理方法的入參(除了 Errors 和 BindingResult 必須緊跟在命令對象/表單參數后面以外),Spring MVC 會根據反射機制自動將對應的對象通過入參傳遞給請求處理方法。這種機制讓開發者完全可以不依賴 Servlet API 開發控制層的程序,當請求處理方法需要特定的對象時,僅僅需要在參數列表中聲明入參即可,不需要考慮如何獲取這些對象,Spring MVC 框架就象一個大管家一樣“不辭辛苦”地為我們準備好了所需的一切。下面演示一下使用 SessionStatus 的例子:


清單 12. 使用 SessionStatus 控制 Session 級別的模型屬性

@RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) {//<——①new OwnerValidator().validate(owner, result);if (result.hasErrors()) {return "ownerForm";}else {this.clinic.storeOwner(owner);status.setComplete();//<——②return "redirect:owner.do?ownerId=" + owner.getId();} }

?

processSubmit() 方法中的 owner 表單對象將綁定到 ModelMap 的“owner”屬性中,result 參數用于存放檢驗 owner 結果的對象,而 status 用于控制表單處理的狀態。在 ② 處,我們通過調用 status.setComplete() 方法,該 Controller 所有放在 session 級別的模型屬性數據將從 session 中清空。

方法返回參數

在低版本的 Spring MVC 中,請求處理方法的返回值類型都必須是 ModelAndView。而在 Spring 2.5 中,你擁有多種靈活的選擇。通過下表進行說明:

請求處理方法入參的可選類型說明
void

此時邏輯視圖名由請求處理方法對應的 URL 確定,如以下的方法:

@RequestMapping("/welcome.do") public void welcomeHandler() { }

對應的邏輯視圖名為“welcome”

String

此時邏輯視圖名為返回的字符,如以下的方法:

@RequestMapping(method = RequestMethod.GET) public String setupForm(@RequestParam("ownerId") int ownerId, ModelMap model) {Owner owner = this.clinic.loadOwner(ownerId);model.addAttribute(owner);return "ownerForm"; }

對應的邏輯視圖名為“ownerForm”

org.springframework.ui.ModelMap

和返回類型為 void 一樣,邏輯視圖名取決于對應請求的 URL,如下面的例子:

@RequestMapping("/vets.do") public ModelMap vetsHandler() {return new ModelMap(this.clinic.getVets()); }

對應的邏輯視圖名為“vets”,返回的 ModelMap 將被作為請求對應的模型對象,可以在 JSP 視圖頁面中訪問到。

ModelAndView當然還可以是傳統的 ModelAndView。

應該說使用 String 作為請求處理方法的返回值類型是比較通用的方法,這樣返回的邏輯視圖名不會和請求 URL 綁定,具有很大的靈活性,而模型數據又可以通過 ModelMap 控制。當然直接使用傳統的 ModelAndView 也不失為一個好的選擇。

?



回頁首


注冊自己的屬性編輯器

Spring MVC 有一套常用的屬性編輯器,這包括基本數據類型及其包裹類的屬性編輯器、String 屬性編輯器、JavaBean 的屬性編輯器等。但有時我們還需要向 Spring MVC 框架注冊一些自定義的屬性編輯器,如特定時間格式的屬性編輯器就是其中一例。

Spring MVC 允許向整個 Spring 框架注冊屬性編輯器,它們對所有 Controller 都有影響。當然 Spring MVC 也允許僅向某個 Controller 注冊屬性編輯器,對其它的 Controller 沒有影響。前者可以通過 AnnotationMethodHandlerAdapter 的配置做到,而后者則可以通過 @InitBinder 注解實現。

下面先看向整個 Spring MVC 框架注冊的自定義編輯器:


清單 13. 注冊框架級的自定義屬性編輯器

>bean class="org.springframework.web.servlet.mvc.annotation. AnnotationMethodHandlerAdapter"<>property name="webBindingInitializer"<>bean class="com.baobaotao.web.MyBindingInitializer"/<>/property< >/bean<

?

MyBindingInitializer 實現了 WebBindingInitializer 接口,在接口方法中通過 binder 注冊多個自定義的屬性編輯器,其代碼如下所示:


清單 14.自定義屬性編輯器

package org.springframework.samples.petclinic.web;import java.text.SimpleDateFormat; import java.util.Date;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.samples.petclinic.Clinic; import org.springframework.samples.petclinic.PetType; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.context.request.WebRequest;public class MyBindingInitializer implements WebBindingInitializer {public void initBinder(WebDataBinder binder, WebRequest request) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");dateFormat.setLenient(false);binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));} }

?

如果希望某個屬性編輯器僅作用于特定的 Controller,可以在 Controller 中定義一個標注 @InitBinder 注解的方法,可以在該方法中向 Controller 了注冊若干個屬性編輯器,來看下面的代碼:


清單 15. 注冊 Controller 級的自定義屬性編輯器

@Controller public class MyFormController {@InitBinderpublic void initBinder(WebDataBinder binder) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");dateFormat.setLenient(false);binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));}… }

?

注意被標注 @InitBinder 注解的方法必須擁有一個 WebDataBinder 類型的入參,以便 Spring MVC 框架將注冊屬性編輯器的 WebDataBinder 對象傳遞進來。

?



回頁首


如何準備數據

在 編寫 Controller 時,常常需要在真正進入請求處理方法前準備一些數據,以便請求處理或視圖渲染時使用。在傳統的 SimpleFormController 里,是通過復寫其 referenceData() 方法來準備引用數據的。在 Spring 2.5 時,可以將任何一個擁有返回值的方法標注上 @ModelAttribute,使其返回值將會進入到模型對象的屬性列表中。來看下面的例子:


清單 16. 定義為處理請求準備數據的方法

package com.baobaotao.web;import com.baobaotao.service.BbtForumService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttributes;import java.util.ArrayList; import java.util.List; import java.util.Set;@Controller @RequestMapping("/bbtForum.do") public class BbtForumController {@Autowiredprivate BbtForumService bbtForumService;@ModelAttribute("items")//<——①向模型對象中添加一個名為items的屬性public List<String> populateItems() {List<String> lists = new ArrayList<String>();lists.add("item1");lists.add("item2");return lists;}@RequestMapping(params = "method=listAllBoard")public String listAllBoard(@ModelAttribute("currUser")User user, ModelMap model) {bbtForumService.getAllBoard();//<——②在此訪問模型中的items屬性System.out.println("model.items:" + ((List<String>)model.get("items")).size());return "listBoard";} }

?

在 ① 處,通過使用 @ModelAttribute 注解,populateItem() 方法將在任何請求處理方法執行前調用,Spring MVC 會將該方法返回值以“items”為名放入到隱含的模型對象屬性列表中。

所 以在 ② 處,我們就可以通過 ModelMap 入參訪問到 items 屬性,當執行 listAllBoard() 請求處理方法時,② 處將在控制臺打印出“model.items:2”的信息。當然我們也可以在請求的視圖中訪問到模型對象中的 items 屬性。

?



回頁首


小結

Spring 2.5 對 Spring MVC 進行了很大增強,現在我們幾乎完全可以使用基于注解的 Spring MVC 完全替換掉原來基于接口 Spring MVC 程序。基于注解的 Spring MVC 比之于基于接口的 Spring MVC 擁有以下幾點好處:

  • 方便請求和控制器的映射;
  • 方便請求處理方法入參綁定URL參數;
  • Controller 不必繼承任何接口,它僅是一個簡單的 POJO。

但 是基于注解的 Spring MVC 并不完美,還存在優化的空間,因為在某些配置上它比基于 XML 的配置更繁瑣。比如對于處理多個請求的 Controller 來說,假設我們使用一個 URL 參數指定調用的處理方法(如 xxx.do?method=listBoardTopic),當使用注解時,每個請求處理方法都必須使用 @RequestMapping() 注解指定對應的 URL 參數(如 @RequestMapping(params = "method=listBoardTopic")),而在 XML 配置中我們僅需要配置一個 ParameterMethodNameResolver 就可以了。

轉載于:https://www.cnblogs.com/sunwei2012/archive/2010/05/11/1732521.html

總結

以上是生活随笔為你收集整理的使用 Spring 2.5 基于注解驱动的 Spring MVC(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。