JavaWeb开发中form、ajax提交数据Model转化

来源:互联网 发布:js中name选择器 编辑:程序博客网 时间:2024/06/14 19:40

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的原理了,我会晕掉的。
为了彻底解决这个问题,我就自己写了一个类,采用递归方式。下来来分析下

  1. 首先需要一个通过参数获取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();        }    }}

这个方法主要就是根据参数的规则,然后判断数据的类型,然后进行对应的转化,这个里面用了递归,原因大家应该知道,我就不多说了。

最后

大概的思路就是这样:判断参数+反射;反射是为了数据的准确性。
最终版本:下载

1 0