麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Java > 正文

Spring MVC中基于自定義Editor的表單數據處理技巧分享

2019-11-26 15:52:08
字體:
來源:轉載
供稿:網友

面向對象的編程方式極大地方便了程序員在管理數據上所花費的精力。在基于Spring MVC的Web開發過程當中,可以通過對象映射的方式來管理表單提交上來的數據,而不用去一個一個地從request中提取出來。另外,這一功能還支持基本數據類型的映射。例如in、long、float等等。這樣我們就能從傳統單一的String類型中解脫出來。然而,應用是靈活的。我們對數據的需求是千變萬化的。有些時候我們需要對表單的數據進行兼容處理。

例如日期格式的兼容:

中國的日期標注習慣采用yyyy-MM-dd格式,歐美習慣采用MM/dd/yyyy。雖然兩種格式都是日期的標注方法,但是往往我們要想達到兼容的目的必須做繁瑣的轉換。

例如價格的兼容:

價格無非就是一串數字,我們經常用的就是0.00這種表達形式,而對于金額較大的價格我們還習慣采用0,000.00這樣帶有逗號分隔的價格表述形式。

其實Spring MVC中已經考慮到了這個問題,在Controller中可以在初始化綁定的時候注冊一個編輯器。當表單提交過來的數據映射到某一特定類型(甚至是特定參數)時可以按照自定義的方法進行轉換。(除二進制方式傳輸過來的數據以外,通常我們認為所有傳過來的參數不論是什么內容,一律認為是字符串)

下面我虛構了一個需求:

我有一個表單,里面需要填寫用戶名、生日和積分。這分別代表了String類型、Date類型和Long類型。下面是表單內容:

復制代碼 代碼如下:

<form action="getObj.do" method="post">
 <table>
  <tr>
   <td>用戶名:</td>
   <td><input type="text" name="userName" value="Name Test" /></td>
   <td>*普通字符串</td>
  </tr>
  <tr>
   <td>生日:</td>
   <td><input type="text" name="birthday" value="2013-3-7" /></td>
   <td>*支持格式: yyyy-MM-dd 或 MM/dd/yyyy</td>
  </tr>
  <tr>
   <td>積分:</td>
   <td><input type="text" name="score" value="1,000" /></td>
   <td>*支持純數字或帶逗號分隔的數字</td>
  </tr>
  <tr>
   <td colspan="3"><input type="submit" value="提交" /></td>
  </tr>
 </table>
</form>

這里根據表單,我們映射了如下的一個表單對象,這里對象的屬性名稱要和上面表單的字段name一致:
復制代碼 代碼如下:

package blog.csdn.net.chaijunkun.formObjs;

import java.util.Date;

public class UserInfo {

 private String userName;

 private Date birthday;

 private Long score;

 //getters and setters...

}


那么我們想接收這樣一個表單數據,可以寫一個對表單處理的方法:
復制代碼 代碼如下:

package blog.csdn.net.chaijunkun.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import blog.csdn.net.chaijunkun.formObjs.UserInfo;

@Controller
public class ObjController {

 private static Logger logger= Logger.getLogger(ObjController.class);

 public ObjController(){
  logger.info("對象映射控制器初始化");
 }

 @RequestMapping(value="/getObj.do")
 public String modifyUser(HttpServletRequest request,
   HttpServletResponse response,Map<String, Object> model,
   UserInfo userInfo){
  logger.info("收集對象信息");
  model.put("userInfo", userInfo);  
  return "user";
 }

}


如果僅僅是這么寫,當然還不能做到多格式兼容。我們需要寫一個針對日期和Long型的格式兼容編輯器。編輯器需要至少繼承自類:java.beans.PropertyEditorSupport。當然,也可以繼承Spring內置的一些編輯器,例如:org.springframework.beans.propertyeditors.CustomNumberEditor,這個是專門用來處理數字轉換的。無論是繼承哪一個,方法都是一樣的:

第一步:重寫公有的void setAsText(String text)方法;

第二步:將轉換好的數據調用setValue(Object obj)進行寫入。

下面我們先實現一個日期兼容的編輯器:

復制代碼 代碼如下:

package blog.csdn.net.chaijunkun.editors;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyDateEditor extends PropertyEditorSupport {

 @Override
 /**
  * text是表單傳入的數據內容
  */
 public void setAsText(String text){
  Date value= null;
  SimpleDateFormat sdf= new SimpleDateFormat();
  sdf.applyPattern("yyyy-MM-dd");
  try{
   value= sdf.parse(text);
  }catch(ParseException e1){
   sdf.applyPattern("MM/dd/yyyy");
   try {
    value= sdf.parse(text);
   } catch (ParseException e2) {
    value= null;
   }
  }
  //這一步將轉換好的數據寫入到對象映射的屬性中
  setValue(value);
 }

}


然后我們再來寫一個針對Long型的編輯器,可以支持帶逗號分隔和不帶逗號分隔的數值表達形式:
復制代碼 代碼如下:

package blog.csdn.net.chaijunkun.editors;

import org.springframework.beans.propertyeditors.CustomNumberEditor;

public class MyLongEditor extends CustomNumberEditor  {

 public MyLongEditor(){
  super(Long.class, true);
 }

 @Override
 public void setAsText(String text){
  if ((text== null) || text.trim().equals("")){
   setValue(null);
  }else{
   Long value= null;
   try{
    //按照標準的數字格式嘗試轉換
    value= Long.parseLong(text);
   }catch(NumberFormatException e){
    //嘗試去除逗號 然后再轉換
    text= text.replace(",", "");
    value= Long.parseLong(text);
   }
   //轉好之后將值返給被映射的屬性
   setValue(value);   
  }
 }

}


好了,這兩個編輯器寫好了,如何讓它們發揮作用呢?這需要在Controller內加一個數據轉換時的綁定方法:
復制代碼 代碼如下:

@InitBinder
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder){
 binder.registerCustomEditor(Date.class, new MyDateEditor());
 binder.registerCustomEditor(Long.class, new MyLongEditor());
}

上面的代碼作用就是:當接收到表單數據,Spring發現參數名能夠與對象屬性相對應,而轉換的類型恰好也是在上述代碼中注冊過的類似,則會將數據內容按照指定的編輯器來做轉換。

我們來試一下:

如下圖所示:

同樣,數據被正確識別了。

通過以上方法,我們成功地兼容了多種數據格式。

寫在后面:

其實針對日期格式,我開始的時候想寫成下面代碼那樣來實現兼容:

復制代碼 代碼如下:

@InitBinder
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder){
 binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
 binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy"), true));
}

后來我發現,這樣寫之后只支持MM/dd/yyyy格式的日期,提交yyyy-MM-dd格式的日期后會拋出異常。看來,對于同一類型,在一個控制器里只能注冊一個編輯器,而且是最后一個被注冊的才起作用。

另外,在文章剛開始的時候寫到,不僅可以按類型,甚至是某一類型的某個屬性都可以按照自己的要求定制編輯器,同時不影響其它同類型的屬性。這個很容易,在registerCustomEditor方法中還有一個重載的方法,第二個參數可以指定具體的屬性名稱。這樣就很容易控制細粒度了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 精品一区二区久久久久久按摩 | 国产一区视频观看 | 天天看天天摸天天操 | 污片视频网站 | 在线成人影视 | 男女一边摸一边做羞羞视频免费 | 俄罗斯hdxxx| 久久国产精品免费视频 | 中文字幕在线观看精品 | 在线香蕉视频 | 国产精品久久久久久模特 | 国内精品伊人久久久久网站 | qyl在线视频精品免费观看 | 久草在线看片 | av在线播放观看 | 中文字幕涩涩久久乱小说 | 男女羞羞视频 | 精品一区二区三区免费毛片爱 | 欧美精品免费一区二区三区 | 日韩精品久久久久久 | 色柚视频网站ww色 | 精品一区二区电影 | 欧美一区在线观看视频 | 免费a级黄色毛片 | 亚洲成人高清电影 | 激情小视频在线观看 | 91精品久久久久久久久久久 | 欧美视频在线观看一区 | 国产永久免费观看 | 日本精品久久久久 | 日本黄色a视频 | 成年人毛片视频 | 国产69精品久久久久久野外 | 精品国产91久久久久久久妲己 | 欧美日在线观看 | 欧美日韩大片在线观看 | 久久影院国产精品 | av最新在线 | 高颜值美女啪啪 | 欧美一级黄色免费 | 国产精品99久久99久久久二 |