This commit is contained in:
Looly 2020-04-17 15:54:43 +08:00
parent 94c824e03d
commit 7e8096a75c
6 changed files with 242 additions and 144 deletions

View File

@ -13,6 +13,7 @@
* 【core 】 增加XmlUtil.setNamespaceAwaregetByPath支持UniversalNamespaceCache
* 【core 】 增加XmlUtil.setNamespaceAwaregetByPath支持UniversalNamespaceCache
* 【aop 】 增加Spring-cglib支持改为SPI实现
* 【json 】 增加JSONUtil.parseXXX增加JSONConfig参数
### Bug修复
* 【json 】 修复解析JSON字符串时配置无法传递问题

View File

@ -188,8 +188,7 @@ final class InternalJSONUtil {
* @return JSONObject
*/
protected static JSONObject propertyPut(JSONObject jsonObject, Object key, Object value) {
String keyStr = Convert.toStr(key);
String[] path = StrUtil.split(keyStr, StrUtil.DOT);
final String[] path = StrUtil.split(Convert.toStr(key), StrUtil.DOT);
int last = path.length - 1;
JSONObject target = jsonObject;
for (int i = 0; i < last; i += 1) {

View File

@ -1,13 +1,13 @@
package cn.hutool.json;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.lang.TypeReference;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.lang.TypeReference;
/**
* JSON接口
*

View File

@ -23,32 +23,41 @@ import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
/**
* JSON对象<br>
* <br>
*
*
* <pre>
* json = new JSONObject().put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
* </pre>
*
*
* @author looly
*/
public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object> {
private static final long serialVersionUID = -330220388580734346L;
/** 默认初始大小 */
public static final int DEFAULT_CAPACITY = 16;
/**
* 默认初始大小
*/
public static final int DEFAULT_CAPACITY = MapUtil.DEFAULT_INITIAL_CAPACITY;
/** JSON的KV持有Map */
/**
* JSON的KV持有Map
*/
private final Map<String, Object> rawHashMap;
/** 配置项 */
/**
* 配置项
*/
private final JSONConfig config;
// -------------------------------------------------------------------------------------------------------------------- Constructor start
/**
* 构造初始容量为 {@link #DEFAULT_CAPACITY}KEY无序
*/
@ -58,7 +67,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 构造初始容量为 {@link #DEFAULT_CAPACITY}
*
*
* @param isOrder 是否有序
* @since 3.0.9
*/
@ -68,9 +77,9 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 构造
*
*
* @param capacity 初始大小
* @param isOrder 是否有序
* @param isOrder 是否有序
* @since 3.0.9
*/
public JSONObject(int capacity, boolean isOrder) {
@ -79,19 +88,19 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 构造
*
* @param capacity 初始大小
*
* @param capacity 初始大小
* @param isIgnoreCase 是否忽略KEY大小写
* @param isOrder 是否有序
* @param isOrder 是否有序
* @since 3.3.1
*/
public JSONObject(int capacity, boolean isIgnoreCase, boolean isOrder) {
this(capacity, JSONConfig.create().setIgnoreCase(isIgnoreCase).setOrder(isOrder));
}
/**
* 构造
*
*
* @param config JSON配置项
* @since 4.6.5
*/
@ -101,13 +110,13 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 构造
*
*
* @param capacity 初始大小
* @param config JSON配置项null表示默认配置
* @param config JSON配置项null表示默认配置
* @since 4.1.19
*/
public JSONObject(int capacity, JSONConfig config) {
if(null == config){
if (null == config) {
config = JSONConfig.create();
}
if (config.isIgnoreCase()) {
@ -127,7 +136,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* <li>value为普通JavaBean如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象
* 例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"</li>
* </ol>
*
*
* @param source JavaBean或者Map对象或者String
*/
public JSONObject(Object source) {
@ -142,8 +151,8 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* <li>value为JSONTokener直接解析</li>
* <li>value为普通JavaBean如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"</li>
* </ol>
*
* @param source JavaBean或者Map对象或者String
*
* @param source JavaBean或者Map对象或者String
* @param ignoreNullValue 是否忽略空值
* @since 3.0.9
*/
@ -159,10 +168,10 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* <li>value为JSONTokener直接解析</li>
* <li>value为普通JavaBean如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"</li>
* </ol>
*
* @param source JavaBean或者Map对象或者String
*
* @param source JavaBean或者Map对象或者String
* @param ignoreNullValue 是否忽略空值如果source为JSON字符串不忽略空值
* @param isOrder 是否有序
* @param isOrder 是否有序
* @since 4.2.2
*/
public JSONObject(Object source, boolean ignoreNullValue, boolean isOrder) {
@ -179,11 +188,11 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* <li>value为JSONTokener直接解析</li>
* <li>value为普通JavaBean如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"</li>
* </ol>
*
* <p>
* 如果给定值为Map将键值对加入JSON对象;<br>
* 如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象<br>
* 例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"
*
*
* @param source JavaBean或者Map对象或者String
* @param config JSON配置文件
* @since 4.2.2
@ -195,16 +204,16 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 构建指定name列表对应的键值对为新的JSONObject情况如下
*
*
* <pre>
* 1. 若obj为Map则获取name列表对应键值对
* 2. 若obj为普通Bean使用反射方式获取字段名和字段值
* </pre>
*
* <p>
* KEY或VALUE任意一个为null则不加入字段不存在也不加入<br>
* 若names列表为空则字段全部加入
*
* @param obj 包含需要字段的Bean对象或者Map对象
* @param obj 包含需要字段的Bean对象或者Map对象
* @param names 需要构建JSONObject的字段名列表
*/
public JSONObject(Object obj, String... names) {
@ -234,9 +243,9 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 从JSON字符串解析为JSON对象对于排序单独配置参数
*
* @param source 以大括号 {} 包围的字符串其中KEY和VALUE使用 : 分隔每个键值对使用逗号分隔
* @param source 以大括号 {} 包围的字符串其中KEY和VALUE使用 : 分隔每个键值对使用逗号分隔
* @param isOrder 是否有序
* @exception JSONException JSON字符串语法错误
* @throws JSONException JSON字符串语法错误
* @since 4.2.2
*/
public JSONObject(CharSequence source, boolean isOrder) throws JSONException {
@ -252,7 +261,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 设置转为字符串时的日期格式默认为时间戳null值
*
*
* @param format 格式null表示使用时间戳
* @return this
* @since 4.1.19
@ -333,7 +342,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* PUT 键值对到JSONObject中在忽略null模式下如果值为<code>null</code>将此键移除
*
* @param key
* @param key
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this.
* @throws JSONException 值是无穷数字抛出此异常
@ -360,7 +369,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 设置键值对到JSONObject中在忽略null模式下如果值为<code>null</code>将此键移除
*
* @param key
* @param key
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this.
* @throws JSONException 值是无穷数字抛出此异常
@ -373,7 +382,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 一次性Put 键值对如果key已经存在抛出异常如果键值中有null值忽略
*
* @param key
* @param key
* @param value 值对象可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this.
* @throws JSONException 值是无穷数字键重复抛出异常
@ -391,7 +400,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 在键和值都为非空的情况下put到JSONObject中
*
* @param key
* @param key
* @param value 值对象可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this.
* @throws JSONException 值是无穷数字
@ -414,7 +423,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* 积累值类似于put当key对应value已经存在时与value组成新的JSONArray. <br>
* 如果只有一个值此值就是value如果多个值则是添加到新的JSONArray中
*
* @param key
* @param key
* @param value 被积累的值
* @return this.
* @throws JSONException 如果给定键为<code>null</code>或者键对应的值存在且为非JSONArray
@ -435,7 +444,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 追加值如果key无对应值就添加一个JSONArray其元素只有value如果值已经是一个JSONArray则添加到值JSONArray中
*
* @param key
* @param key
* @param value
* @return this.
* @throws JSONException 如果给定键为<code>null</code>或者键对应的值存在且为非JSONArray
@ -559,12 +568,13 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
}
// ------------------------------------------------------------------------------------------------- Private method start
/**
* 将JSON内容写入Writer
*
* @param writer writer
*
* @param writer writer
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param indent 本级别缩进量
* @return Writer
* @throws JSONException JSON相关异常
*/
@ -610,7 +620,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* Bean对象转Map
*
*
* @param bean Bean对象
*/
private void populateMap(Object bean) {
@ -654,7 +664,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* <li>value为JSONTokener直接解析</li>
* <li>value为普通JavaBean如果为普通的JavaBean调用其getters方法getXXX或者isXXX获得值加入到JSON对象例如如果JavaBean对象中有个方法getName()值为"张三"获得的键值对为name: "张三"</li>
* </ol>
*
*
* @param source JavaBean或者Map对象或者String
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@ -662,9 +672,9 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
if (null == source) {
return;
}
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass());
if(serializer instanceof JSONObjectSerializer) {
if (serializer instanceof JSONObjectSerializer) {
// 自定义序列化
serializer.serialize(this, source);
} else if (source instanceof Map) {
@ -678,7 +688,10 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
} else if (source instanceof JSONTokener) {
// JSONTokener
init((JSONTokener) source);
} else if(BeanUtil.isReadableBean(source.getClass())){
} else if (source instanceof ResourceBundle) {
// JSONTokener
init((ResourceBundle) source);
} else if (BeanUtil.isReadableBean(source.getClass())) {
// 普通Bean
this.populateMap(source);
}
@ -686,16 +699,37 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
/**
* 初始化
*
*
* @param bundle ResourceBundle
* @since 5.3.1
*/
private void init(ResourceBundle bundle) {
Enumeration<String> keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
if (key != null) {
InternalJSONUtil.propertyPut(this, key, bundle.getString(key));
}
}
}
/**
* 初始化可以判断字符串为JSON或者XML
*
* @param source JSON字符串
*/
private void init(CharSequence source) {
final String jsonStr = StrUtil.trim(source);
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
XML.toJSONObject(this, jsonStr, false);
}
init(new JSONTokener(StrUtil.trim(source), this.config));
}
/**
* 初始化
*
*
* @param x JSONTokener
*/
private void init(JSONTokener x) {
@ -708,13 +742,13 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
while (true) {
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
// The key is followed by ':'.
@ -728,17 +762,17 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
// Pairs are separated by ','.
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == '}') {
case ';':
case ',':
if (x.nextClean() == '}') {
return;
}
x.back();
break;
case '}':
return;
}
x.back();
break;
case '}':
return;
default:
throw x.syntaxError("Expected a ',' or '}'");
default:
throw x.syntaxError("Expected a ',' or '}'");
}
}
}

View File

@ -23,9 +23,8 @@ import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
@ -100,6 +99,19 @@ public final class JSONUtil {
return new JSONObject(obj);
}
/**
* JSON字符串转JSONObject对象<br>
* 此方法会忽略空值但是对JSON字符串不影响
*
* @param obj Bean对象或者Map
* @param config JSON配置
* @return JSONObject
* @since 5.3.1
*/
public static JSONObject parseObj(Object obj, JSONConfig config) {
return new JSONObject(obj, config);
}
/**
* JSON字符串转JSONObject对象
*
@ -146,6 +158,18 @@ public final class JSONUtil {
return new JSONArray(arrayOrCollection);
}
/**
* JSON字符串转JSONArray
*
* @param arrayOrCollection 数组或集合对象
* @param config JSON配置
* @return JSONArray
* @since 5.3.1
*/
public static JSONArray parseArray(Object arrayOrCollection, JSONConfig config) {
return new JSONArray(arrayOrCollection, config);
}
/**
* JSON字符串转JSONArray
*
@ -169,6 +193,22 @@ public final class JSONUtil {
* @return JSON
*/
public static JSON parse(Object obj) {
return parse(obj, JSONConfig.create());
}
/**
* 转换对象为JSON<br>
* 支持的对象<br>
* String: 转换为相应的对象<br>
* ArrayIterableIterator转换为JSONArray<br>
* Bean对象转为JSONObject
*
* @param obj 对象
* @param config JSON配置
* @return JSON
* @since 5.3.1
*/
public static JSON parse(Object obj, JSONConfig config) {
if (null == obj) {
return null;
}
@ -176,17 +216,13 @@ public final class JSONUtil {
JSON json;
if (obj instanceof JSON) {
json = (JSON) obj;
} else if (obj instanceof String) {
String jsonStr = ((String) obj).trim();
if (jsonStr.startsWith("[")) {
json = parseArray(jsonStr);
} else {
json = parseObj(jsonStr);
}
} else if (obj instanceof Collection || obj.getClass().isArray()) {// 列表
json = new JSONArray(obj);
} else if (obj instanceof CharSequence) {
final String jsonStr = StrUtil.trim((CharSequence) obj);
json = StrUtil.startWith(jsonStr, '[') ? parseArray(jsonStr) : parseObj(jsonStr);
} else if (obj instanceof Iterable || obj instanceof Iterator || ArrayUtil.isArray(obj)) {// 列表
json = new JSONArray(obj, config);
} else {// 对象
json = new JSONObject(obj);
json = new JSONObject(obj, config);
}
return json;
@ -206,8 +242,10 @@ public final class JSONUtil {
* Map转化为JSONObject
*
* @param map {@link Map}
* @return JSONObject
* @return JSONObjec
* @deprecated 请直接使用 {@link #parseObj(Object)}
*/
@Deprecated
public static JSONObject parseFromMap(Map<?, ?> map) {
return new JSONObject(map);
}
@ -217,17 +255,11 @@ public final class JSONUtil {
*
* @param bundle ResourceBundle文件
* @return JSONObject
* @deprecated 请直接使用 {@link #parseObj(Object)}
*/
@Deprecated
public static JSONObject parseFromResourceBundle(ResourceBundle bundle) {
JSONObject jsonObject = new JSONObject();
Enumeration<String> keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
if (key != null) {
InternalJSONUtil.propertyPut(jsonObject, key, bundle.getString(key));
}
}
return jsonObject;
return new JSONObject(bundle);
}
// -------------------------------------------------------------------- Pause end

View File

@ -9,44 +9,109 @@ import java.util.Iterator;
/**
* 提供静态方法在XML和JSONObject之间转换
*
*
* @author JSON.org
*/
public class XML {
/** The Character '&amp;'. */
/**
* The Character '&amp;'.
*/
public static final Character AMP = CharUtil.AMP;
/** The Character '''. */
/**
* The Character '''.
*/
public static final Character APOS = CharUtil.SINGLE_QUOTE;
/** The Character '!'. */
/**
* The Character '!'.
*/
public static final Character BANG = '!';
/** The Character '='. */
/**
* The Character '='.
*/
public static final Character EQ = '=';
/** The Character '&gt;'. */
/**
* The Character '&gt;'.
*/
public static final Character GT = '>';
/** The Character '&lt;'. */
/**
* The Character '&lt;'.
*/
public static final Character LT = '<';
/** The Character '?'. */
/**
* The Character '?'.
*/
public static final Character QUEST = '?';
/** The Character '"'. */
/**
* The Character '"'.
*/
public static final Character QUOT = CharUtil.DOUBLE_QUOTES;
/** The Character '/'. */
/**
* The Character '/'.
*/
public static final Character SLASH = CharUtil.SLASH;
/**
* 转换XML为JSONObject
* 转换过程中一些信息可能会丢失JSON中无法区分节点和属性相同的节点将被处理为JSONArray
* Content text may be placed in a "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]&gt;</code> are ignored.
*
* @param string The source string.
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string) throws JSONException {
return toJSONObject(string, false);
}
/**
* 转换XML为JSONObject
* 转换过程中一些信息可能会丢失JSON中无法区分节点和属性相同的节点将被处理为JSONArray
* Content text may be placed in a "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]&gt;</code> are ignored.
* All values are converted as strings, for 1, 01, 29.0 will not be coerced to numbers but will instead be the exact value as seen in the XML document.
*
* @param string The source string.
* @param keepStrings If true, then values will not be coerced into boolean or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
return toJSONObject(new JSONObject(), string, keepStrings);
}
/**
* 转换XML为JSONObject
* 转换过程中一些信息可能会丢失JSON中无法区分节点和属性相同的节点将被处理为JSONArray
*
* @param jo JSONObject
* @param string XML字符串
* @param keepStrings If true, then values will not be coerced into boolean or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
* @since 5.3.1
*/
public static JSONObject toJSONObject(JSONObject jo, String string, boolean keepStrings) throws JSONException {
XMLTokener x = new XMLTokener(string, jo.getConfig());
while (x.more() && x.skipPast("<")) {
parse(x, jo, null, keepStrings);
}
return jo;
}
/**
* Scan the content following the named tag, attaching it to the context.
*
* @param x The XMLTokener containing the source string.
*
* @param x The XMLTokener containing the source string.
* @param context The JSONObject that will include the new material.
* @param name The tag name.
* @param name The tag name.
* @return true if the close tag is processed.
* @throws JSONException JSON异常
*/
@ -135,7 +200,7 @@ public class XML {
tagName = (String) token;
token = null;
jsonobject = new JSONObject();
for (;;) {
for (; ; ) {
if (token == null) {
token = x.nextToken();
}
@ -169,7 +234,7 @@ public class XML {
} else if (token == GT) {
// Content, between <...> and </...>
for (;;) {
for (; ; ) {
token = x.nextContent();
if (token == null) {
if (tagName != null) {
@ -203,43 +268,10 @@ public class XML {
}
}
/**
* 转换XML为JSONObject
* 转换过程中一些信息可能会丢失JSON中无法区分节点和属性相同的节点将被处理为JSONArray
* Content text may be placed in a "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]&gt;</code> are ignored.
*
* @param string The source string.
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string) throws JSONException {
return toJSONObject(string, false);
}
/**
* 转换XML为JSONObject
* 转换过程中一些信息可能会丢失JSON中无法区分节点和属性相同的节点将被处理为JSONArray
* Content text may be placed in a "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]&gt;</code> are ignored.
* All values are converted as strings, for 1, 01, 29.0 will not be coerced to numbers but will instead be the exact value as seen in the XML document.
*
* @param string The source string.
* @param keepStrings If true, then values will not be coerced into boolean or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
JSONObject jo = new JSONObject();
XMLTokener x = new XMLTokener(string, jo.getConfig());
while (x.more() && x.skipPast("<")) {
parse(x, jo, null, keepStrings);
}
return jo;
}
/**
* 转换JSONObject为XML
* Convert a JSONObject into a well-formed, element-normal XML string.
*
*
* @param object A JSONObject.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
@ -251,17 +283,17 @@ public class XML {
/**
* 转换JSONObject为XML
* Convert a JSONObject into a well-formed, element-normal XML string.
*
* @param object A JSONObject.
*
* @param object A JSONObject.
* @param tagName The optional name of the enclosing tag.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toXml(Object object, String tagName) throws JSONException {
if(null == object) {
if (null == object) {
return null;
}
StringBuilder sb = new StringBuilder();
JSONArray ja;
JSONObject jo;