使用json-lib封装json

前言

这是一个使用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,封装,json-lib)