使用反射自定义序列化方法

前端之家收集整理的这篇文章主要介绍了使用反射自定义序列化方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在使用JSONObject和JSONArray的过程中,往往让人惊叹它的神奇之处,能够很方面的把json对象和bean互相转换,一直在思考究竟后台如何实现的,虽然通过看源码可以得出答案,但毕竟源码过于繁复,短时间内难以尽解,不如自己思考:如果这个功能是我设计的,我会怎么实现呢?其实无非就是使用反射而已,加上循环和迭代,把集合类型和嵌套的对象都迭代出来。

被序列化的类详见:http://blog.csdn.net/salerzhang/article/details/41259471

初始化一个对象:

<span style="white-space:pre">	</span>Student student = new Student();
		student.setName("zxl");
		student.setGerder("M");
		//student.setAddress("beijing");
		Classes cs = new Classes();
		cs.setClaName("计算机1");
		cs.setClsNum("07060341");
		cs.setWay("wentaoyuan1");
		List<Student> list = new ArrayList<Student>();
		list.add(student);
		cs.setStudents(list);
		cs.setStudent(student);

被反序列化的数据:
JSONObject jo = JSONObject.fromObject("{'clsNum':'123','claName':'计算机2','student':{'gerder':'F','name':'zxl'},'students':[{'address':'shanghai','gerder':'M','name':'xxx'}],'way':'wentaoyuan1'}");

JsonConfig:
Map<String,Class<?>> clazz = new HashMap<String,Class<?>>();
		clazz.put("student",Student.class);
		clazz.put("students",Student.class);
		
		JsonConfig jc = new JsonConfig();
		jc.setClassMap(clazz);

private static Object jsonObjectIterator(Object root,JSONObject jo,JsonConfig jc) throws InstantiationException,IllegalAccessException,ClassNotFoundException,SecurityException,NoSuchMethodException,IllegalArgumentException,InvocationTargetException,NoSuchFieldException {

		Iterator<String> keys = jo.keys();
		Map<String,Class<?>> clazz = jc.getClassMap();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			if (jo.get(key) instanceof JSONObject) {//嵌套对象
				Object o = Class.forName(clazz.get(key).getName()).newInstance();

				String setMethodName = "set" + key.substring(0,1).toUpperCase() + key.substring(1);
				o = jsonObjectIterator(o,jo.getJSONObject(key),jc);
				Method setMethod = root.getClass().getMethod(setMethodName,clazz.get(key));
				setMethod.invoke(root,o);
			} else if (jo.get(key) instanceof JSONArray) {//嵌套数组
				JSONArray ja = jo.getJSONArray(key);
				List<Object> list = new ArrayList<Object>();
				Method method = list.getClass().getMethod("add",Object.class);
				for (int i = 0; i < ja.size(); i++) {
					Object o = Class.forName(clazz.get(key).getName()).newInstance();
					jsonObjectIterator(o,ja.getJSONObject(i),jc);
					method.invoke(list,o);
				}
				String setMethodName = "set" + key.substring(0,1).toUpperCase() + key.substring(1);
				Method setMethod = root.getClass().getMethod(setMethodName,List.class);
				setMethod.invoke(root,list);
			} else {//本级属性
				Field field = root.getClass().getDeclaredField(key);
				if (field.getName().equals(key)) {
					Type type = field.getGenericType();
					String fieldName = key.substring(0,1).toUpperCase() + key.substring(1);
					setObjectByString(root,jo.getString(key),fieldName,type);
				}
			}
		}
		//		root = setObjectByJson(root,jo,false);

		return root;
	}

方法需要配置三个参数:

* @param root 主类对象 注意参数是对象而不是类的Class
* @param jo 被反序列化的内容 需要转换成JSONObject再传入
* @param jc classMap 包括classMap的配置等

方法等的大概逻辑:

遍历JSONObject对象,分三个逻辑处理:

1,属性:按类型处理,不同类型的参数要进行转换,使用方法

private static void setObjectByString(Object o,String valueFromJson,String name,Type type)
			throws NoSuchMethodException,InvocationTargetException {
		String t = type.toString();
		if (t.equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
			Method m = o.getClass().getMethod("get" + name);
			String value = (String) m.invoke(o); // 调用getter方法获取属性值
			// if (value == null) {
			m = o.getClass().getMethod("set" + name,String.class);
			m.invoke(o,valueFromJson);
			// }
		}
		if (t.equals("class java.lang.Integer")) {
			Method m = o.getClass().getMethod("get" + name);
			Integer value = (Integer) m.invoke(o);
			if (value == null) {
				m = o.getClass().getMethod("set" + name,Integer.class);
				m.invoke(o,StringParseUtil.parse2Integer(valueFromJson));
			}
		}
		if (t.equals("class java.lang.Boolean")) {
			Method m = o.getClass().getMethod("get" + name);
			Boolean value = (Boolean) m.invoke(o);
			if (value == null) {
				m = o.getClass().getMethod("set" + name,Boolean.class);
				m.invoke(o,StringParseUtil.parse2Boolean(valueFromJson));
			}
		}
		if (t.equals("class java.util.Date")) {
			Method m = o.getClass().getMethod("get" + name);
			Date value = (Date) m.invoke(o);
			if (value == null) {
				m = o.getClass().getMethod("set" + name,Date.class);
				m.invoke(o,StringParseUtil.parse2Date(valueFromJson));
			}
		}
	}

2,JSONObject类型,获取类型迭代

注意:要找到嵌套类的类路径,这个在ClassMap中,迭代完成后,需要把嵌套对象放进主类对象中。

3,JSONArray类型,先遍历数组,然后迭代

注意:要判断集合的类型,本例中只默认使用List类型,在获取setter方法时,一定要传入集合的的类型,这个类型要与声明的集合类一致(不是实际类型),比如:Classes对象中有一个集合类型的成员变量:private List<Student> students; List是一个接口,在实例化的时候,很可能是ArrayList对象,但这里我们只能用List.class标识setter方法的参数类型,而不能用ArrayList.class。

当集合类型是Map或Set到时候,从本质来说没有大的区别,这里不再赘述。

猜你在找的Json相关文章