標籤:javaweb 參數model 萬能model
JavaWeb開發中form、ajax提交資料Model轉化問題
最近學習MongoDB資料庫,作為java開發的我,當然需要做個小的web程式來測試一番了。在html中我採取ajax提交方式,因為我要類比各種類型的資料,基礎資料類型、數組、對象等。然而,最終發現了個不同的地方:Form和ajax提交資料,在HttpServletRequest中盡然參數名有所不同。
資料類型 |
form |
ajax |
基礎資料 |
para=value |
para=value |
數組 |
para[]={“aaa”,”bbb”} |
para[][]={“aaa”,”bbb”} |
對象 |
obj.sex=女(和基礎資料一樣,只不過用了obj.) |
obj[sex]=女 |
對象數組 |
obj[0].sex |
obj[0][sex]=女 |
form提交,以上的參數方式,需要在input的name屬性定義,常用的都是springmvc的資料繫結;ajax提交,參數來自data提交的對象的屬性。
$.ajax({ type: "post", dataType: "json", url: "${ctx}/api/manage/save", data: { test: [‘aab‘, ‘bbb‘, ‘ccc‘], table: ‘tableName‘, fields: [{ ‘field‘: ‘f‘, ‘type‘: ‘t‘, ‘desc‘: ‘d‘ }, { ‘field‘: ‘f1‘, ‘type‘: ‘t1‘, ‘desc‘: ‘d1‘ ] }}).success(function(data) { alert(data.msg);});
如上,就是一個ajax提交。
解決
發現了這個差異化,起始也沒什麼。但是在提交的時候,擷取資料並解析有時候確實有些麻煩,即是spring等架構能夠完美支援,但是還是應該搞懂原理。所以我也不打算去看spring的原理了,我會暈掉的。
為了徹底解決這個問題,我就自己寫了一個類,採用遞迴方式。下來來分析下
- 首先需要一個通過參數擷取T的一個方法,如下
public static <T> T getModel(Map<String, String[]> map, Class<T> clazz) { Map<String, Object> jsonMap = new HashMap<String, Object>(); for (String key : map.keySet()) { String[] values = map.get(key); //$.ajax提交data:{arr:[‘aaa‘,‘bbb‘]},到這裡key是arr[][] if (key.endsWith("[]")) key = key.substring(0, key.length() - 2); parseKey(key, values, clazz, jsonMap); } return JSON.parseObject(JSON.toJSONString(jsonMap), clazz);}
在這個方法中有兩點:
1、ajax提交數組[][],需要去掉一個保持key的一致性
2、將Map轉化為T對象,這裡是通過fastjson來做的轉化(現將Map轉成json,然後再講json轉回T,因為直接轉化有點難度)
parseKey方法
private static void parseKey(String key, String[] values, Class<?> clazz, Map<String, Object> jsonMap) { if (hasSubClass(key)) {//數組或對象的對象 String field = key.substring(0, key.indexOf("[")); String classField = ""; if (key.contains(".")) { //將form中的. 統一轉化為[]來操作 key = key.replace("].", pattern).replace(".", pattern); key = key + "]"; } if (key.indexOf(pattern) != key.lastIndexOf(pattern)) {//可能是數組對象 classField = key.substring(key.indexOf(pattern) + 2, key.length()).replaceFirst("]", ""); } else { classField = key.substring(key.indexOf(pattern) + 2, key.length() - 1); } if (jsonMap.get(field) == null) { jsonMap.put(field, new ArrayList<Map<String, Object>>()); } List<Map<String, Object>> list = (List) jsonMap.get(field); int i = Integer.parseInt(key.substring(field.length() + 1, field.length() + 2)) + 1; for (int j = 0; j < i; j++) { try { list.get(j); continue; } catch (Exception e) { list.add(j, new HashMap<String, Object>()); } } Class<?> subClass = null; try { ParameterizedType cl = (ParameterizedType) clazz .getDeclaredField(field).getGenericType(); subClass = (Class<?>) cl.getActualTypeArguments()[0]; parseKey(classField, values, subClass, list.get(i - 1)); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } else {//基本資料或對象 try { load(key, values, clazz, jsonMap); } catch (Exception e) { e.printStackTrace(); } }}
這個方法主要就是根據參數的規則,然後判斷資料的類型,然後進行對應的轉化,這個裡面用了遞迴,原因大家應該知道,我就不多說了。
最後
大概的思路就是這樣:判斷參數+反射;反射是為了資料的準確性。
最終版本:下載
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
JavaWeb開發中form、ajax提交資料Model轉化