今天在完善登陸模塊的時候發現了一個小問題,將代碼做簡化如下
<form id="loginForm"> <label for="username">用戶名</label> <input type="text" name="username" autocomplete="off" placeholder="請輸入用戶名"> <label for="password">密碼</label> <input type="password" name="password" placeholder="請輸入密碼"> <button type="submit" id="loginbtn">登陸</button> </form>
這樣一個簡單的表單,提交到SpringMVC映射的路徑,可以直接用Bean做參數來接收
@RequestMapping(value="login",method=RequestMethod.POST) @ResponseBody //直接寫回字符串而不是跳轉 public ModelAndView loginCheck(UserVo user, HttpServletRequest request, Model model) throws IOException{
System.out.println(user); //這里可以直接取到user,username和password都與表單提交來的屬性相同
//然而通過以下四種方式都取不到user
System.out.println(request.getAttribute("user")); //null System.out.println(request.getAttribute("userVo")); //null System.out.println(request.getSession().getAttribute("user")); //null System.out.println(request.getSession().getAttribute("userVo")); //null System.out.println("==================");
//原來user被封裝在了model對象中
System.out.println(model.containsAttribute("userVo")); //true
//*****調用service進行驗證返回業務對象的實例userBo*****
//ajax返回驗證結果給前端
JsonResult result = new JsonResult();
result.setResultCode(1);
result.setData(userBo.getUserNum());
mm.addAttribute("result", result);
return new ModelAndView(new MappingJackson2JsonView(), mm);
}
乍一看好像不是什么大問題,Spring愛封裝就讓他封裝,我們只要使用就好了,然而-------
我在前端用ajax成功的回調函數打出接收到的json數據,不看不知道,一看嚇一跳
{ "userVo":{ "username":"1", "password":"123"}, "result":{ "resultCode":1, "resultMessage":"ajax成功", "data":1} }
上次提交的密碼赫然在列,也就是說Model在請求前后之間是保留傳遞的,雖然servlet中我們已經習慣了請求帶參數轉發給下個頁面的模式,會對一些參數進行銷毀,但是在springmvc中,很可能被框架本身的調試折騰的焦頭爛額,從而忽略了這些細節
那么,怎么像servlet中的request.removeAttibute一樣移除這個我們不想傳遞的user呢?
注意到在整個login方法中我並沒有操作傳入的參數model,這說明model的傳輸是由框架幫我們完成的,所以首先想到的是直接操作model,發現沒有remove之類的方法,換個思路,對SpringMVC略有了解的同學應該知道Controller中的方法支持傳入多種類型的參數,他們之間也是可以相互轉換的,利用的原理就是Map,想到這一點,再看model的方法,其中有一個叫asMap(),問題就豁然開朗了,只需要在你想清除掉密碼的位置加一行代碼
model.asMap().remove("userVo");
其中userVo是該函數傳入的參數 (UserVo user, *,*,*)的類型,這一點從前面的json數據也可以看出來
public ModelAndView loginCheck(UserVo user, HttpServletRequest request,HttpServletResponse response, Model model)
SpringMVC利用利用反射,幫我們完成了表單提交過來的數據的封裝,實在是方便,不過還是要記得及時處理不需要或不可傳輸的數據,以保證我們程序的安全和潔凈,又要兩點啦,開工, Fighting~~
