<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
眾所周知,springmvc是用來處理頁面的一些請求,然後將資料再通過檢視返回給使用者的,前面的幾篇博文中使用的都是靜態資料,為了能快速入門springmvc,在這一篇博文中,我將總結一下springmvc中如何接收前臺頁面的引數,即springmvc中的引數繫結問題。
我們可以回憶一下,在struts2中,是通過在Action中定義一個成員變數來接收前臺傳進來的引數,而在springmvc中,接收頁面提交的資料是通過方法形參來接收的。從使用者端請求的key/value資料,經過引數繫結,將key/value資料繫結到controller方法的形參上,然後就可以在controller中使用該引數了。來看一下這個過程:
所以我們知道,是springmvc提供了很多轉換器來將頁面引數繫結到controller方法的形參上,關於自定義converter,我下面會提到。大概瞭解了該過程後,下面開始做具體的總結。
springmvc中,有支援的預設型別的繫結。也就是說,直接在controller方法形參上定義預設型別的物件,就可以使用這些物件。
HttpServletRequest物件HttpServletResponse物件HttpSession物件Model/ModelMap物件
在引數繫結過程中,如果遇到上面型別就直接進行繫結。也就是說,我們可以在controller的方法的形參中直接定義上面這些型別的引數,springmvc會自動繫結。這裡要說明一下的就是Model/ModelMap物件,Model是一個介面,ModelMap是一個介面實現 ,作用是將Model資料填充到request域,跟ModelAndView類似,關於它的使用,我在下面和簡單型別引數繫結一起說。
總結這個還是以需求為例吧,這樣比較容易理解,假設現在有個需求:根據商品的id來修改對應點商品資訊。所以前臺頁面肯定要傳進來該商品的id,然後springmvc的controller進行處理,返回一個修改商品資訊的頁面。關於前臺頁面的東西都很簡單,我就不貼程式碼了,主要部分截個圖,具體的程式碼在文章最後有下載地址。
前臺頁面通過url將引數傳遞過來,請求的是editItems.action。
下面寫controller中的editItems方法:
@RequestMapping("/editItems") public String editItems(Model model, Integer id) throws Exception { //根據id查詢對應的Items ItemsCustom itemsCustom = itemsService.findItemsById(id); model.addAttribute("itemsCustom", itemsCustom); //通過形參中的model將model資料傳到頁面 //相當於modelAndView.addObject方法 return "/WEB-INF/jsp/items/editItems.jsp"; }
這是個很簡單的demo,從上面的程式碼中可以看出model可以直接作為引數,springmvc預設會繫結它,然後使用model將查詢到的資料放到request域中,這樣就可以在前臺頁面取出該資料了。
要注意一點的是,簡單型別的繫結中,方法形參中的引數名要和前臺傳進來的名一樣才能完成引數的繫結。那有人要問了,如果有特殊需求(比如更好的可讀性?),這裡定義的引數名就是不一樣,那咋整呢?有解決辦法麼?有!我們可以使用註解@RequestParam對簡單的型別進行引數繫結,如下:
所以說,如果不使用@RequestParam,要求request傳入引數名稱和controller方法的形參名稱一致,方可繫結成功。如果使用@RequestParam,不用限制request傳入引數名稱和controller方法的形參名稱一致。通過@RequestParam中的required屬性指定引數是否必須要傳入,如果設定為true,沒有傳入引數就會報錯。
再來總結下pojo型別的繫結,繼續上面的案例,當頁面展示了商品詳細資訊後,我做了修改,然後點選提交,後臺應該將我提交的這些引數全部更新到資料庫的items表中,也就是說,我提交的這些引數要繫結到Items物件或者其擴充套件物件中。先看一下Items中都有哪些屬性:
可以看到,有各種型別的屬性,當我們提交後,要將這些屬性全部封裝到一個pojo中,然後去更新資料庫。
繫結很簡單,對於基本型別,要求頁面中input標籤的name屬性值和controller的pojo形參中的屬性名稱一致,即可將頁面中資料繫結到pojo。也就是說前臺頁面傳進來的name要和要封裝的pojo屬性名一模一樣,然後就可以將該pojo作為形參放到controller的方法中,如下:
這樣就能將前臺表單傳進來的不同屬性值封裝到ItemsCustom中了。但是執行一下就會發現報錯,報錯的資訊是無法將String型別轉換成java.util.Date型別,因為上面Items中有一個屬性是Date型別的createtime。這就需要我們自己定義轉換器了,這也是這部分的重點,下面我們自己定義一個日期轉換器:
//需要實現Converter介面,這裡是將String型別轉換成Date型別 public class CustomDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { //實現 將日期串轉成日期型別(格式是yyyy-MM-dd HH:mm:ss) SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { //轉成直接返回 return simpleDateFormat.parse(source); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } //如果引數繫結失敗返回null return null; } }
定義好了轉換器後,需要在springmvc.xml中進行如下設定:
現在就可以了,springmvc就能根據這個轉換器將String型別正確轉換成Date型別,然後封裝到ItemsCustom中去了。
這裡說一個小小的插曲:修改商品詳細資訊後提交,可能會有中文亂碼問題,表達提交都是post方式,springmvc中關於post方式的中文亂碼問題可以在web.xml中設定一個過濾器來解決,如下:
這個包裝型別pojo與上面普通的pojo有啥區別呢?包裝型別pojo指的是pojo中有另一個也是pojo的屬性,即pojo套pojo,為什麼會設計這種pojo呢?在前面的博文中我也有提到,這種組合的設計方法對於後期程式的擴充套件很有用,比如複雜的查詢條件就需要包裝到這種包裝型別中。
那麼該如何繫結呢?有兩個思路:
在形參中新增HttpServletRequest request引數,通過request接收查詢條件引數。在形參中讓包裝型別的pojo接收查詢條件引數。
第一種方式就跟原始servlet差不多,這裡使用第二種方法,我們傳進來一個包裝型別的pojo。看一下這個包裝型別的pojo:
這個包裝pojo中還有一個ItemsCustom類,這個類繼承了Items類,並且用來擴充套件與Items相關的User物件中的相關資訊。所以這個ItemsCustom中有name屬性,假如我們要想將前臺傳進來的name屬性封裝到ItemsCustom中的name屬性中,該如何傳入呢?這就是包裝型別的pojo引數繫結問題。
很簡單,在前臺我們可以通過這種方式來傳:
然後controller中方法的形參傳入包裝型別的pojo,即ItemsQueryVo,打個斷點,即可檢視值有沒有傳進來。如下:
這樣就能根據使用者傳進來的引數,進行復制的查詢操作了。
陣列的繫結指的是前臺傳來多個同一型別的資料,我們在controller中使用陣列形參來接收前臺傳來的資料。還是以案例來驅動這部分內容,比如現在我們要批次刪除商品,那麼我們需要勾選好幾個商品,這些商品都有id號,在controller中,我們需要將這些id號全部獲取並放到一個陣列中,然後再根據陣列中的id號挨個刪除資料庫中對應的項。那麼該如何繫結呢?其實也很簡單,如下:
controller的方法定義為:
對應前臺傳入的引數為:
這樣就能將前臺傳入的多個id繫結到陣列中,然後我們就可以從陣列中拿出要刪除的商品的id了。
通常在需要批次提交資料時,將提交的資料繫結到list<pojo>
中,比如:成績錄入(錄入多門課成績,批次提交),在這裡我們假設有需求:批次商品修改,在頁面輸入多個商品資訊,將多個商品資訊提交到controller方法中,即一次性更新多個商品資訊。
所以思路是在擴充套件類ItemsQueryVo中新新增一個List<ItemsCustom>
,然後將不同商品的資訊都存到這個List中,所以修改如下:
controller方法的定義:
1、進入批次商品修改頁面
2、批次修改商品提交
所以controller中應該有兩個方法,如下:
前臺jsp頁面中是如何傳入引數的呢?這是我們所關心的問題,因為後臺形參中接收資料用的就是包裝類ItemsQueryVo。看下面:
所以我們知道了,前臺是通過類似於list[i].name這種形式來傳遞引數的。list[i]表示第i個ItemsCustom,然後 list[i].屬性 表示第i個ItemsCustom中對應的屬性。
Map的繫結其實和List的繫結是差不多的,首先也是在包裝的pojo中新新增一個Map型別的屬性,如(我隨便舉個例子,跟本例無關了)
Public class QueryVo { private Map<String, Student> itemInfo = new HashMap<String, Student>(); //get/set方法.. }
關鍵是前臺傳參的時候和List不太一樣,Map是這樣傳的,比如:
<tr> <td>學生資訊:</td> <td> 姓名:<input type="text" name="itemInfo['name']"/> 年齡:<input type="text" name="itemInfo['price']"/> .. .. .. </td> </tr>
我們可以看到,Map的引數繫結傳來的是Map中的key,然後value會自動繫結到Map中的那個物件的屬性中。在controller中的方法裡,形參就直接使用QueryVo接收即可,也很簡單。
關於springmvc的引數繫結基本就總結到這了,其實原理都差不多,只是針對於不同的型別,繫結的方式有些區別而已,多想想多寫寫,基本就能掌握這些了。
學習筆記原始碼下載地址:https://github.com/eson15/SpringMVC_Study
到此這篇關於SpringMVC中引數繫結問題的文章就介紹到這了,更多相關SpringMVC引數繫結內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45