您的位置:首页 > Web前端 > JavaScript

使用json-lib封装json

2015-10-10 06:31 579 查看

前言

这是一个使用json-lib来封装json的json工具类,我也是从公司框架中反编译提取出来,并做了适当的改动。虽然感觉技术都比较老了,但是里面的封装还是值得学习和研究的

正文

封装的json-lib代码

package myblog.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.ezmorph.Morpher;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.bean.BeanMorpher;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.JSONUtils;

public class JsonUtils {

public JsonUtils() {
}

public static String toJson(Object obj) {
String s = null;
if (obj == null) {
throw new  AppException("转换json的时候传入的object[" + obj + "]为空");
}
if (!(obj instanceof Collection) && !(obj.getClass().isArray()) && !(obj instanceof JSONArray)) {
s = JSONObject.fromObject(obj, config).toString();
} else {
s = JSONArray.fromObject(obj, config).toString();
}
return s;
}

/**
* json转换成Bean,clazz指定的整个json转换的类型
* 如果这个bean里面还有其他自定义类型(List,Array不包括,会自动转换)不知道如何转换只能用MorphDynaBean
* 解决办法请看jsonToBean(String s, Class clazz, Map map)中的map来指定类型
* jsonToBean只适合JsonObject,isArray为true不满足,json形式最外层为{}而不能为[]
*/
public static Object jsonToBean(String s, Class<?> clazz) {
return jsonToBean(s, clazz, null);
}

public static Object jsonToBean(String s, Class<?> clazz, Map<String,?> typemap) {
return trans2Bean(JSONObject.fromObject(s), clazz, typemap);
}

/*private void exampleForTypeMap() {
String json2 ="{'k1':{'age':10,'sex':'男','userName':'xiapi1'},'k2':{'age':12,'sex':'女','userName':'xiapi2'}}";
Map<String, java.lang.Class<?>> typeMap = new HashMap<String, java.lang.Class<?>>();
//指定map中花括号里面的json转换成Student
typeMap.put("k1", Student.class);
//map中k2中的json转换成Map,这里当然可以转换成Student啦
typeMap.put("k2", Map.class);
//如果没有typeMap,那么{'age':10,'sex':'男','userName':'xiapi1'}转换成MorphDynaBean类型
Map stu = (Map) JsonUtils.jsonToBean(json2, Map.class, typeMap);
System.out.println(stu.get("k1"));
}*/

private static Object trans2Bean(JSONObject jsonobject, Class<?> class1, Map<String,?> map) {
return JSONObject.toBean(jsonobject, class1, map);
}

/**
* 将MorphDynaBean类型的对象转换成指定的类型对象
* 这个写着玩
*/
public static Object translateMorphDynaBean(Class<?> outclazz, Object obj) {
MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
Morpher dynaMorpher = new BeanMorpher(outclazz,morpherRegistry);
morpherRegistry.registerMorpher(dynaMorpher);
return morpherRegistry.morph(outclazz,obj);

}

@SuppressWarnings("rawtypes")
public static List jsonArrayToList(String json) {
return JSONArray.fromObject(json);
}

/**
* 将最外层为[]的json转换成List对象
* jsonToBean只适合json最外层为{}形式
* 可以指定class,里面元素形式为{} 将元素转换成指定类型  [{},{}]
* 但是要求里面元素必须是{}包含,如果如[[],[]]json形式不适合JsonObject
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static List jsonArrayToList(String json, Class clazz) {
if (json == null || "".equals(json)) {
throw new AppException("需要转换的json文本不能为空");
}
if (clazz == null) {
return JSONArray.fromObject(json);
}
List arraylist = new ArrayList();
for (Iterator iterator = JSONArray.fromObject(json).iterator(); iterator.hasNext(); ) {
arraylist.add(trans2Bean(((JSONObject) iterator.next()), clazz, null));
};
return arraylist;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static List jsonArrayToList(String json,Class clazz, Map mapType) {
if (json == null || "".equals(json)) {
throw new AppException("需要转换的json文本不能为空");
}
if (clazz == null) {
return JSONArray.fromObject(json);
}
List arraylist = new ArrayList();
for (Iterator iterator = JSONArray.fromObject(json).iterator(); iterator.hasNext(); ) {
arraylist.add(trans2Bean(((JSONObject) iterator.next()), clazz, mapType));
};
return arraylist;
}

/** jsonArrayToList使用例子
* clazz指的是[{}]中的花括号需要转换的类型
* typemap是花括号里面students里面花括号需要转换的类型
*/
/*private void showExampleForjsonArrayToList() {
String json = "[{'name':'123','date':'2015-10-10',students: [{'userName':'good','sex':'girl','age':23}]}]";
Map<String,java.lang.Class<?>> typeMap = new HashMap<String, java.lang.Class<?>>();
typeMap.put("name", String.class);
typeMap.put("date", Date.class);
typeMap.put("students", Student.class);
List list = (List) JsonUtils.jsonArrayToList(json,Class.class,typeMap);
Class map = (Class) list.get(0);
System.out.println(map.getStudents().get(0).getAge());
}
*/

/**
* jsonToMap可以用jsonToBean来代替
* @param s
* @return
*/
@SuppressWarnings("rawtypes")
public static Map jsonToMap(String json) {
return JSONObject.fromObject(json);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map jsonToMap(String json, Class class1) {
if(json == null || "".equals(json)) {
throw new AppException("需要转换的json不能为空");
}
JSONObject jsonobject = JSONObject.fromObject(json);
HashMap hashmap = new HashMap();
String s1 = null;
for (Iterator iterator = jsonobject.keys(); iterator.hasNext(); ) {
s1 = (String) iterator.next();
hashmap.put(s1,trans2Bean(jsonobject.getJSONObject(s1), class1, null));
}

return hashmap;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map jsonToMap(String json, Class class1, Map map) {
if(json == null || "".equals(json)) {
throw new AppException("需要转换的json不能为空");
}
JSONObject jsonobject = JSONObject.fromObject(json);
HashMap hashmap = new HashMap();
String s1;
for (Iterator iterator = jsonobject.keys(); iterator.hasNext(); ) {
s1 = (String) iterator.next();
hashmap.put(s1,trans2Bean(jsonobject.getJSONObject(s1), class1, map));
}

return hashmap;
}

/*public void exampleJsonToMap() {
String json = "{'id':{'name':'123','date':'2015-10-10',students: [{'userName':'good','sex':'girl','age':23}]}}";
Map<String,java.lang.Class<?>> typeMap = new HashMap<String, java.lang.Class<?>>();
typeMap.put("students", Student.class);
Map list = (Map) JsonUtils.jsonToMap(json, Class.class,typeMap);
System.out.println(((Class)list.get("id")).getStudents());
}*/

public static String escape(String s) {
Pattern pattern = Pattern.compile("[\\\\|'|\\r|\\n]");
Matcher matcher = pattern.matcher(s);
StringBuffer stringbuffer = new StringBuffer();
while (matcher.find())
if ("\\".equals(matcher.group()))
matcher.appendReplacement(stringbuffer, "\\\\\\\\");
else if ("'".equals(matcher.group()))
matcher.appendReplacement(stringbuffer, "\\\\'");
else if ("\r".equals(matcher.group()))
matcher.appendReplacement(stringbuffer, "\\\\r");
else if ("\n".equals(matcher.group()))
matcher.appendReplacement(stringbuffer, "\\\\n");
matcher.appendTail(stringbuffer);
return stringbuffer.toString();
}

private static final JsonConfig config;
//private static final String bL = "yyyy-MM-dd HH:mm:ss";
//private static final String bJ = "yyyy-MM-dd";

static {
config = new JsonConfig();
//使用jsonConfig的setCycleDetectionStrategy()方法进行忽略死循环。
//bK.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
//需要注意的是完整的放到最前面,如果简单的放到前面,匹配范围变大了如:yyyy-MM-dd 匹配2012-05-21 13:13:11
JSONUtils.getMorpherRegistry()
.registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd"}));
//时间如java.sql.Date的处理
config.registerJsonValueProcessor(java.sql.Date.class, new DateJsonValueProcessor("yyyy-MM-dd"));
//时间为java.util.Date处理
config.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
//时间为java.sql.Timestamp处理
config.registerJsonValueProcessor(java.sql.Timestamp.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
//时间为java.math.BigDecimal处理
config.registerJsonValueProcessor(java.math.BigDecimal.class, new NumberJsonValueProcessor());
}

// 时间转换内部类
public static class DateJsonValueProcessor implements JsonValueProcessor {
private static final String defaultFormat = "yyyy-MM-dd";
private DateFormat dataFormat;
// 构造函数
public DateJsonValueProcessor() {
dataFormat = new SimpleDateFormat(defaultFormat);
}

public DateJsonValueProcessor(String s) {
dataFormat = new SimpleDateFormat(s);
}

//如果是List<Date>类型,这里面obj值得是集合一个元素Date
public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
return process(obj);
}

@Override
public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
return process(obj);
}

//如果是java.sql.Date类型,这里强转是否会存在问题
//这里因为Date是java.util.Date类型,java.sql.Date是java.util.Date的子类
//自动向上转型可以知道,这里强转是合理的
private Object process(Object obj) {
return obj != null ? dataFormat.format((Date)obj) : "";
}
}

//BigDecimal转换为Json发生截断 处理
public static class NumberJsonValueProcessor implements JsonValueProcessor {

@Override
public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
return process(obj);
}

@Override
public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
return process(obj);
}

private Object process(Object obj) {
return obj != null ? obj.toString() : "";
}
}

}


问题列表

一、java.sql.Date与java.util.Date的区别?

java.utilDate是java.sql.Date的父类,java.sql.Date的创建需要依赖于java.util.Date,它没有无参构造器,而java.util.Date是包含一个无参构造器的。由于父子类关系,由多态可以知道,java.sql.Date向上转型成java.util.Date是合理的,下面代码bean转换成json,java.util.Date的子类java.sql.Date、java.sql.Timestamp、java.math.BigDecimal也是通过这种关系来完成的**

二、bean转换json,里面的时间如何处理?

bean转换json处理时间,有很多种方法,我这里采用了实现JsonValueProcessor接口,对java.sql.Date、java.sql.Timestamp、java.math.BigDecimal以及java.util.Date做转化。具体代码如下

config = new JsonConfig();
//时间如java.sql.Date的处理
config.registerJsonValueProcessor(java.sql.Date.class, new DateJsonValueProcessor("yyyy-MM-dd"));
//时间为java.util.Date处理
config.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
//时间为java.sql.Timestamp处理
config.registerJsonValueProcessor(java.sql.Timestamp.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));


在fromObject(obj, config)第二个参数需要指定这个config,它里面包含了如何转换的信息。当我们bean转换成json到时候,根据时间类型来自动帮你调用具体的转化方法。如属性Date date 是 java.sql.Date类型,并注册了这个转化,在fromObject的源码中就会去调用所实现的转化方法

三、json转换bean,里面的时间如何处理?

json转换成bean,在json里面包含一个时间,这个时间需要做处理,使用json-lib提供的工具方法,如下

JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd"}));


我把它写在static域中,只要执行了,就不需要管了,在转换的时候也是自动帮你处理好的,这里需要解释一下new String[]{}里面的字符串,这些字符串是提供匹配的,如果属性里面的时间不匹配这里面的字符串,那就赶紧加入能匹配的字符串吧,不然就抛异常了。还需要注意的时候,越详细的匹配写到前面去,我试了一下yyyy-MM-dd写到前面,它可以匹配属性值为2012-05-21 13:13:11,结果 出现了2012-05-21 00:00:00,后面时间消失了

四、BigDecimal类型发生截断如何处理?

和时间处理一样,需要实现JsonValueProcessor接口,我这里用一个内部类NumberJsonValueProcessor表示,只要将内容toString就可以了

五、json转换bean的时候typeMap有何作用?

jsonToBean(String,Class,Map),这里面的Map是干什么的?Class与Map由有什么区别?,先看一段json

String json2 ="{'k1':{'age':10,'sex':'男','userName':'xiapi1'},'k2':{'age':12,'sex':'女','userName':'xiapi2'}}


我要将这个json转换成Map,这是可行的,因为map的json形式就是符合上面的json格式,那么只要指定Class为Map.class,它才会得到期望的map,但是里面{}又该转换成什么类型呢,如果我什么都不做,它得到是MorphDynaBean类型,我想让它变成Student类型,那么就用到typeMap了

Map<String, java.lang.Class<?>> typeMap = new HashMap<String, java.lang.Class<?>>();
typeMap.put("k1", Student.class);


这里指定“K1”花括号是Student类型,那么map.get(“k1”)得到的就不是MorphDynaBean,而是Student.简单来说typeMap就是指定元素所需要转换的类型,如果是List,就指定List元素中的类型

六、JSONArray与JSONObject的区别是什么?

JSONObject是不会处理isArray为true的变量,而JSONArray可以处理所有变量,JSONArray转换成json最外层是[]形式,JSONObject转换成json是{}形式

JSONObject.toBean是不会处理最外层为[]的json的,所以上面代码将json转换成集合需要单独封装一个方法

七、如何将json转换成Bean?(bean | Map)

使用JSONObject.toBean,将json最外层格式为{}的json根据指定的Class、typeMap转换成所期望的对象

八、如何将json转换成数组(Collection | JSONArray | clazz.isArray)

json转换成数组、集合。使用JSONArray.fromObject,返回的是JSONArray,这个类实现了List,所以由向上转型直接可以赋给List。当然上面代码通过判断是否指定Class来为里面的元素转换成Class所属的对象,如果这个元素里面还有{}代表自定义的对象,那么还需要typeMap,如

String json = "[{'name':'123','date':'2015-10-10',students: [{'userName':'good','sex':'girl','age':23}]}]";
Map<String,java.lang.Class<?>> typeMap = new HashMap<String, java.lang.Class<?>>();
typeMap.put("name", String.class);
typeMap.put("date", Date.class);
typeMap.put("students", Student.class);
List list = (List) JsonUtils.jsonArrayToList(json,Class.class,typeMap);


Class是一个班级类,花括号代表一个班级的对象,存放到list中,这个是有Class来指定的,但是json里面还有一个students: [{}],需要指定typeMap,类型为Student,不指定通过list得到的student是MorphDynaBean类型

功能封装罗列

将bean转换成json的通用方法

public static String toJson(Object obj) {
String s = null;
if (obj == null) {
throw new  AppException("转换json的时候传入的object[" + obj + "]为空");
}
if (!(obj instanceof Collection) && !(obj.getClass().isArray()) && !(obj instanceof JSONArray)) {
s = JSONObject.fromObject(obj, config).toString();
} else {
s = JSONArray.fromObject(obj, config).toString();
}
return s;
}


将最外层形式为{}的json转化成Bean,2个重载方法供选择

public static Object jsonToBean(String s, Class<?> clazz) {
return jsonToBean(s, clazz, null);
}

public static Object jsonToBean(String s, Class<?> clazz, Map<String,?> typemap) {
return trans2Bean(JSONObject.fromObject(s), clazz, typemap);
}


将最外层形式为[]的json转成list,使用了Class 和 typeMap对里面元素做类型的指定,包含两个重载方法

public static List jsonArrayToList(String json, Class clazz) {
if (json == null || "".equals(json)) {
throw new AppException("需要转换的json文本不能为空");
}
if (clazz == null) {
return JSONArray.fromObject(json);
}
List arraylist = new ArrayList();
for (Iterator iterator = JSONArray.fromObject(json).iterator(); iterator.hasNext(); ) {
arraylist.add(trans2Bean(((JSONObject) iterator.next()), clazz, null));
};
return arraylist;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static List jsonArrayToList(String json,Class clazz, Map mapType) {
if (json == null || "".equals(json)) {
throw new AppException("需要转换的json文本不能为空");
}
if (clazz == null) {
return JSONArray.fromObject(json);
}
List arraylist = new ArrayList();
for (Iterator iterator = JSONArray.fromObject(json).iterator(); iterator.hasNext(); ) {
arraylist.add(trans2Bean(((JSONObject) iterator.next()), clazz, mapType));
};
return arraylist;
}


将最外层为{}格式的json转换成map,和jsonToBean功能是一样的

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map jsonToMap(String json, Class class1) {
if(json == null || "".equals(json)) {
throw new AppException("需要转换的json不能为空");
}
JSONObject jsonobject = JSONObject.fromObject(json);
HashMap hashmap = new HashMap();
String s1 = null;
for (Iterator iterator = jsonobject.keys(); iterator.hasNext(); ) {
s1 = (String) iterator.next();
hashmap.put(s1,trans2Bean(jsonobject.getJSONObject(s1), class1, null));
}

return hashmap;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map jsonToMap(String json, Class class1, Map map) {
if(json == null || "".equals(json)) {
throw new AppException("需要转换的json不能为空");
}
JSONObject jsonobject = JSONObject.fromObject(json);
HashMap hashmap = new HashMap();
String s1;
for (Iterator iterator = jsonobject.keys(); iterator.hasNext(); ) {
s1 = (String) iterator.next();
hashmap.put(s1,trans2Bean(jsonobject.getJSONObject(s1), class1, map));
}

return hashmap;
}


参考资料

细细品味Web——Json-Lib类库使用手册

http://www.cnblogs.com/xia520pi/archive/2012/05/22/2513369.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  json-lib json 封装