com.discovery.darchrow.tools.jsonlib.JsonUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.discovery.darchrow.tools.jsonlib.JsonUtil.java

Source

/*
 * Copyright (C) 2008 feilong
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.discovery.darchrow.tools.jsonlib;

import java.lang.reflect.Array;
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 org.apache.commons.collections.IteratorUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.discovery.darchrow.date.DatePattern;
import com.discovery.darchrow.lang.ArrayUtil;
import com.discovery.darchrow.tools.jsonlib.processor.DateJsonValueProcessor;
import com.discovery.darchrow.util.Validator;

import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSON;
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.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertyFilter;
import net.sf.json.util.PropertySetStrategy;
import net.sf.json.xml.XMLSerializer;

/**
 * json .
 * 
 * <h3>??jar:</h3>
 * 
 * <blockquote>
 * 
 * <pre>
 * {@code
 * <groupId>net.sf.json-lib</groupId>
 * <artifactId>json-lib</artifactId>
 * 
 * ?xml,?
 * <groupId>xom</groupId> 
 * <artifactId>xom</artifactId>
 * }
 * </pre>
 * 
 * </blockquote>
 * 
 * @author feilong
 * @version 1.0.5 Jan 26, 2013 8:02:09 PM
 * @since 1.0.5
 */
public final class JsonUtil {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);

    /** Don't let anyone instantiate this class. */
    private JsonUtil() {
        //AssertionError?. ?????. ???.
        //see Effective Java 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    /** The Constant DEFAULT_JSON_CONFIG. */
    private static final JsonConfig DEFAULT_JSON_CONFIG;

    /**
     * ??
     */
    static {
        // ????Json??
        String[] formats = { DatePattern.COMMON_DATE_AND_TIME, DatePattern.COMMON_TIME, DatePattern.COMMON_DATE };
        DateMorpher dateMorpher = new DateMorpher(formats);

        // 
        MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
        morpherRegistry.registerMorpher(dateMorpher);

        DEFAULT_JSON_CONFIG = getDefaultJsonConfig();
    }

    //***************************format********************************************************

    // [start] format

    /**
     * ?,?toJSON, toString(4, 4) .
     *
     * @param obj
     *            
     * @return the string
     * @see #format(Object, String[])
     * @see #format(Object, JsonConfig)
     */
    public static String format(Object obj) {
        String[] excludes = null;
        return format(obj, excludes);
    }

    /**
     * ?,?toJSON, toString(4, 4) .
     *
     * @param obj
     *            
     * @param excludes
     *            ???json, excludes isNotNullOrEmpty,?setExcludes
     * @return if null==obj will return {@code null}; {@link #format(Object, JsonConfig)}
     * @see #format(Object, JsonConfig)
     * @see <a href="http://feitianbenyue.iteye.com/blog/2046877">java.lang.ClassCastException: JSON keys must be strings</a>
     */
    public static String format(Object obj, String[] excludes) {
        return format(obj, excludes, 4, 4);
    }

    /**
     * Format.
     *
     * @param obj
     *            the obj
     * @param excludes
     *            the excludes
     * @param indentFactor
     *            the indent factor
     * @param indent
     *            the indent
     * @return the string
     */
    public static String format(Object obj, String[] excludes, int indentFactor, int indent) {
        if (null == obj) {
            return null;
        }
        JsonConfig jsonConfig = null;

        if (Validator.isNotNullOrEmpty(excludes)) {
            jsonConfig = getDefaultJsonConfig();
            jsonConfig.setExcludes(excludes);
        }

        JSON json = toJSON(obj, jsonConfig);
        String string = json.toString(indentFactor, indent);
        return string;
    }

    /**
     * ??key?formatjson?.
     *
     * @param obj
     *            the obj
     * @param includes
     *            the includes
     * @return the string
     * @since 1.0.8
     */
    public static String formatWithIncludes(Object obj, final String... includes) {

        if (null == obj) {
            return null;
        }

        JsonConfig jsonConfig = null;

        if (Validator.isNotNullOrEmpty(includes)) {
            jsonConfig = getDefaultJsonConfig();
            jsonConfig.setJsonPropertyFilter(new PropertyFilter() {

                @Override
                public boolean apply(Object source, String name, Object value) {
                    return !ArrayUtil.isContain(includes, name);
                }
            });

        }
        return format(obj, jsonConfig);
    }

    /**
     * JsonConfig.
     *
     * @return the default json config
     */
    private static JsonConfig getDefaultJsonConfig() {
        JsonConfig jsonConfig = new JsonConfig();

        // ,?? There is a cycle in the hierarchy!
        jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

        //see net.sf.json.JsonConfig.DEFAULT_EXCLUDES
        //key "class","declaringClass","metaClass"
        jsonConfig.setIgnoreDefaultExcludes(true);

        // ?
        jsonConfig.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor());

        // java.lang.ClassCastException: JSON keys must be strings
        // see http://feitianbenyue.iteye.com/blog/2046877
        jsonConfig.setAllowNonStringKeys(true);

        return jsonConfig;
    }

    /**
     * ?,?toJSON, toString(4, 4) .<br>
     *
     * @param obj
     *            the obj
     * @param jsonConfig
     *            the json config
     * @return if null==obj will return {@code null}; else return toJSON(obj, jsonConfig).toString(4, 4)
     * @see net.sf.json.JsonConfig
     * @see #toJSON(Object, JsonConfig)
     * @see net.sf.json.JSON#toString(int, int)
     * @see #format(Object, JsonConfig, int, int)
     * @since 1.0.7
     */
    public static String format(Object obj, JsonConfig jsonConfig) {
        return format(obj, jsonConfig, 4, 4);
    }

    /**
     * Make a prettyprinted JSON text.
     * <p>
     * Warning: This method assumes that the data structure is acyclical.
     * </p>
     *
     * @param obj
     *            the obj
     * @param jsonConfig
     *            the json config
     * @param indentFactor
     *            The number of spaces to add to each level of indentation.
     * @param indent
     *            The indentation of the top level.
     * @return a printable, displayable, transmittable representation of the object, beginning with { (left brace) and ending with } (right
     *         brace).
     * @since 1.0.8
     */
    public static String format(Object obj, JsonConfig jsonConfig, int indentFactor, int indent) {
        if (null == obj) {
            return null;
        }
        JSON json = toJSON(obj, jsonConfig);
        String string = json.toString(indentFactor, indent);
        return string;
    }

    // [end]

    // [start]toBean

    /**
     * json,??.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. {'name':'get','dateAttr':'2009-11-12'}<br>
     *            ? json,?JSONObject<br>
     *            Accepts JSON formatted strings, Maps, DynaBeans and JavaBeans. <br>
     *            ??: {@link JSONObject#fromObject(Object, JsonConfig)}
     * @param rootClass
     *            e.g. Person.class
     * @return the t
     */
    public static <T> T toBean(Object json, Class<T> rootClass) {
        return toBean(json, rootClass, null);
    }

    /**
     * json????Bean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. {'data':[{'name':'get'},{'name':'set'}]}
     * @param rootClass
     *            e.g. MyBean.class
     * @param classMap
     *            e.g. classMap.put("data", Person.class)
     * @return Object
     * @see #toBean(Object, JsonConfig)
     */
    // TODO
    @SuppressWarnings("unchecked")
    public static <T> T toBean(Object json, Class<T> rootClass, Map<String, Class<?>> classMap) {
        JSONObject jsonObject = JSONObject.fromObject(json);

        JsonConfig jsonConfig = getDefaultJsonConfig();
        jsonConfig.setRootClass(rootClass);

        if (Validator.isNotNullOrEmpty(classMap)) {
            jsonConfig.setClassMap(classMap);
        }
        return (T) toBean(jsonObject, jsonConfig);
    }

    /**
     * json,??.
     *
     * @param json
     *            the json
     * @param jsonConfig
     *            the json config
     * @return the object
     * @see net.sf.json.JSONObject#toBean(JSONObject, JsonConfig)
     */
    public static Object toBean(Object json, JsonConfig jsonConfig) {
        JSONObject jsonObject = JSONObject.fromObject(json);

        // Ignore missing properties with Json-Lib

        // ?? Unknown property 'orderIdAndCodeMap' on class 'class
        // com.baozun.trade.web.controller.payment.result.command.PaymentResultEntity' 
        jsonConfig.setPropertySetStrategy(new PropertyStrategyWrapper(PropertySetStrategy.DEFAULT));
        return JSONObject.toBean(jsonObject, jsonConfig);
    }

    // [end]

    // *****************************Array******************************************************
    // [start]toArray

    /**
     * json??.
     *
     * @param json
     *            e.g. ['get',1,true,null]
     * @return Object[]
     * @see net.sf.json.JSONArray#fromObject(Object)
     * @see net.sf.json.JSONArray#toArray()
     */
    public static Object[] toArray(String json) {
        JSONArray jsonArray = JSONArray.fromObject(json);
        return jsonArray.toArray();
    }

    /**
     * json,??.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. [{'name':'get'},{'name':'set'}]
     * @param clazz
     *            e.g. Person.class
     * @return Object[]
     * @see #toArray(String, Class, Map)
     */
    public static <T> T[] toArray(String json, Class<T> clazz) {
        return toArray(json, clazz, null);
    }

    /**
     * json????Bean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. [{'data':[{'name':'get'}]},{'data':[{'name':'set'}]}]
     * @param clazz
     *            e.g. MyBean.class
     * @param classMap
     *            e.g. classMap.put("data", Person.class)
     * @return T[]
     * @see net.sf.json.JSONArray#fromObject(Object)
     * @see net.sf.json.JSONArray#getJSONObject(int)
     * @see #toBean(Object, Class, Map)
     * @see java.lang.reflect.Array#newInstance(Class, int)
     */
    public static <T> T[] toArray(String json, Class<T> clazz, Map<String, Class<?>> classMap) {
        JSONArray jsonArray = JSONArray.fromObject(json);
        int size = jsonArray.size();

        @SuppressWarnings("unchecked")
        T[] t = (T[]) Array.newInstance(clazz, size);

        for (int i = 0; i < size; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            t[i] = toBean(jsonObject, clazz, classMap);
        }
        return t;
    }

    // [end]

    // *****************************List********************************************************
    // [start]toList

    /**
     * json???.
     *
     * @param json
     *            e.g. ['get',1,true,null]
     * @return List
     * @see net.sf.json.JSONArray#get(int)
     */
    public static List<Object> toList(String json) {
        JSONArray jsonArray = JSONArray.fromObject(json);
        int size = jsonArray.size();

        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < size; i++) {
            Object e = jsonArray.get(i);
            list.add(e);
        }
        return list;
    }

    /**
     * json????Bean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. [{'name':'get'},{'name':'set'}]
     * @param clazz
     *            the clazz
     * @return List
     * @see #toList(String, Class, Map)
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        return toList(json, clazz, null);
    }

    /**
     * json??????Bean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. [{'data':[{'name':'get'}]},{'data':[{'name':'set'}]}]
     * @param clazz
     *            e.g. MyBean.class
     * @param classMap
     *            e.g. classMap.put("data", Person.class)
     * @return List
     * @see net.sf.json.JSONArray#getJSONObject(int)
     * @see net.sf.json.JSONArray#fromObject(Object)
     * @see #toBean(Object, Class, Map)
     */
    // TODO
    public static <T> List<T> toList(String json, Class<T> clazz, Map<String, Class<?>> classMap) {
        JSONArray jsonArray = JSONArray.fromObject(json);
        List<T> list = new ArrayList<T>();

        int size = jsonArray.size();
        for (int i = 0; i < size; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            list.add(toBean(jsonObject, clazz, classMap));
        }
        return list;
    }

    // [end]

    // ********************************Map******************************************************

    // [start]toMap

    /**
     * json??map.
     *
     * @param json
     *            e.g. {'name':'get','int':1,'double',1.1,'null':null}
     * @return Map
     * @see net.sf.json.JSONObject#get(String)
     * @see net.sf.json.JSONObject#fromObject(Object)
     */
    public static Map<String, Object> toMap(String json) {
        JSONObject jsonObject = JSONObject.fromObject(json);

        Map<String, Object> map = new HashMap<String, Object>();

        @SuppressWarnings("unchecked")
        Iterator<String> keys = jsonObject.keys();

        while (keys.hasNext()) {
            String key = keys.next();
            Object value = jsonObject.get(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * json??mapmapBean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. {'data1':{'name':'get'}, 'data2':{'name':'set'}}
     * @param clazz
     *            e.g. Person.class
     * @return Map
     * @see #toMap(String, Class, Map)
     */
    public static <T> Map<String, T> toMap(String json, Class<T> clazz) {
        return toMap(json, clazz, null);
    }

    /**
     * json??mapmapBean??Bean.
     *
     * @param <T>
     *            the generic type
     * @param json
     *            e.g. {'mybean':{'data':[{'name':'get'}]}}
     * @param clazz
     *            e.g. MyBean.class
     * @param classMap
     *            e.g. classMap.put("data", Person.class)
     * @return Map
     * @see net.sf.json.JSONObject#keys()
     * @see #toBean(Object, Class, Map)
     */
    // TODO
    public static <T> Map<String, T> toMap(String json, Class<T> clazz, Map<String, Class<?>> classMap) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("in json:{}", json);
        }

        JSONObject jsonObject = JSONObject.fromObject(json);

        Map<String, T> map = new HashMap<String, T>();
        @SuppressWarnings("unchecked")
        Iterator<String> keys = jsonObject.keys();

        while (keys.hasNext()) {
            String key = keys.next();
            Object value = jsonObject.get(key);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("key:{} value:{}", key, value);
            }
            map.put(key, toBean(value, clazz, classMap));
        }
        return map;
    }

    // [end]

    // [start]toJSON

    /**
     * Bean?Map?????Json.
     *
     * @param obj
     *            the obj
     * @return the jSON
     * @see #toJSON(Object, JsonConfig)
     */
    public static JSON toJSON(Object obj) {
        return toJSON(obj, null);
    }

    /**
     * Bean?Map?????Json.
     *
     * @param obj
     *            the obj
     * @param jsonConfig
     *            the json config
     * @return the jSON
     * @see net.sf.json.JSONArray#fromObject(Object, JsonConfig)
     * @see net.sf.json.JSONObject#fromObject(Object, JsonConfig)
     * @see net.sf.json.util.JSONUtils#isArray(Object)
     * @see java.lang.Class#isEnum()
     * @see net.sf.json.JsonConfig#registerJsonValueProcessor(Class, JsonValueProcessor)
     * @see org.apache.commons.collections.IteratorUtils#toList(Iterator)
     * @see org.apache.commons.collections.IteratorUtils#toList(Iterator, int)
     */
    public static JSON toJSON(Object obj, JsonConfig jsonConfig) {
        if (null == jsonConfig) {
            jsonConfig = DEFAULT_JSON_CONFIG;
        }

        // obj instanceof Collection || obj instanceof Object[]
        if (JSONUtils.isArray(obj) || //
                obj instanceof Enum || // obj.getClass().isEnum() null// object'isanEnum.UseJSONArrayinstead
                obj instanceof Iterator) {

            if (obj instanceof Iterator) {
                Collection<?> list = IteratorUtils.toList((Iterator<?>) obj);
                obj = list;
            }
            //Accepts JSON formatted strings, arrays, Collections and Enums.
            return JSONArray.fromObject(obj, jsonConfig);
        }
        //Accepts JSON formatted strings, Maps, DynaBeans and JavaBeans.
        return JSONObject.fromObject(obj, jsonConfig);
    }

    // [end]

    //*******************************objectToXML*************************************************

    // [start]objectToXML

    /**
     * json???(collection map)?Bean??XML<br>
     * XMLSerializer API http://json-lib.sourceforge.net/apidocs/net/sf/json/xml/XMLSerializer.html ?<br>
     * http://json-lib.sourceforge.net/xref-test/net/sf/json/xml/TestXMLSerializer_writes.html<br>
     * http://json-lib.sourceforge.net/xref-test/net/sf/json/xml/TestXMLSerializer_writes.html
     * 
     * @param object
     *            the object
     * @return xml
     * @see #objectToXML(Object, String)
     */
    public static String objectToXML(Object object) {
        return objectToXML(object, null);
    }

    /**
     * Object to xml<br>
     * :
     * <ul>
     * <li>? {@code <?xml version="1.0" encoding="UTF-8"? >}</li>
     * <li>??</li>
     * <li>,? {@code <additionalData></additionalData>} ,? {@code <additionalData/>}</li>
     * </ul>
     * 
     * @param object
     *            the object
     * @param encoding
     *            the encoding
     * @return the string
     * @see #toJSON(Object)
     * @see net.sf.json.xml.XMLSerializer#write(JSON)
     * @see net.sf.json.xml.XMLSerializer#write(JSON, String)
     */
    public static String objectToXML(Object object, String encoding) {
        JSON json = toJSON(object);
        XMLSerializer xmlSerializer = new XMLSerializer();
        // xmlSerializer.setRootName("outputPaymentPGW");
        // xmlSerializer.setTypeHintsEnabled(true);
        // xmlSerializer.setTypeHintsCompatibility(true);
        // xmlSerializer.setSkipWhitespace(false);
        if (Validator.isNotNullOrEmpty(encoding)) {
            return xmlSerializer.write(json, encoding);
        }
        return xmlSerializer.write(json);

    }

    // [end]

    // [start]xmlToJSON

    /**
     * XML?json.
     * 
     * @param xml
     *            the xml
     * @return String
     * @see net.sf.json.xml.XMLSerializer#read(String)
     */
    public static JSON xmlToJSON(String xml) {
        XMLSerializer xmlSerializer = new XMLSerializer();
        JSON json = xmlSerializer.read(xml);
        return json;
    }

    // [end]
}