All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xiaoleilu.hutool.json.InternalJSONUtil Maven / Gradle / Ivy

package com.xiaoleilu.hutool.json;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;

import com.xiaoleilu.hutool.bean.BeanUtil;
import com.xiaoleilu.hutool.bean.copier.CopyOptions;
import com.xiaoleilu.hutool.bean.copier.ValueProvider;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.convert.ConvertException;
import com.xiaoleilu.hutool.convert.ConverterRegistry;
import com.xiaoleilu.hutool.convert.impl.CollectionConverter;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.hutool.util.TypeUtil;

/**
 * 内部JSON工具类,仅用于JSON内部使用
 * @author Looly
 *
 */
final class InternalJSONUtil {
	
	private InternalJSONUtil() {}
	
	/**
	 * 写入值到Writer
	 * @param writer Writer
	 * @param value 值
	 * @param indentFactor
	 * @param indent 缩进空格数
	 * @return Writer
	 * @throws JSONException
	 * @throws IOException
	 */
	protected static final Writer writeValue(Writer writer, Object value, int indentFactor, int indent) throws JSONException, IOException {
		if (value == null || value instanceof JSONNull) {
			writer.write("null");
		} else if (value instanceof JSON) {
			((JSON) value).write(writer, indentFactor, indent);
		}else if (value instanceof Map) {
			new JSONObject((Map) value).write(writer, indentFactor, indent);
		} else if (value instanceof Collection) {
			new JSONArray((Collection) value).write(writer, indentFactor, indent);
		} else if (value.getClass().isArray()) {
			new JSONArray(value).write(writer, indentFactor, indent);
		} else if (value instanceof Number) {
			writer.write(NumberUtil.toStr((Number) value));
		} else if (value instanceof Boolean) {
			writer.write(value.toString());
		} else if (value instanceof JSONString) {
			Object o;
			try {
				o = ((JSONString) value).toJSONString();
			} catch (Exception e) {
				throw new JSONException(e);
			}
			writer.write(o != null ? o.toString() : JSONUtil.quote(value.toString()));
		} else {
			JSONUtil.quote(value.toString(), writer);
		}
		return writer;
	}

	/**
	 * 缩进,使用空格符
	 * @param writer
	 * @param indent
	 * @throws IOException
	 */
	protected static final void indent(Writer writer, int indent) throws IOException {
		for (int i = 0; i < indent; i += 1) {
			writer.write(' ');
		}
	}
	
	/**
	 * 如果对象是Number 且是 NaN or infinite,将抛出异常
	 * @param obj 被检查的对象
	 * @throws JSONException If o is a non-finite number.
	 */
	protected static void testValidity(Object obj) throws JSONException {
		if(false == ObjectUtil.isValidIfNumber(obj)){
			throw new JSONException("JSON does not allow non-finite numbers.");
		}
	}
	
	/**
	 * 值转为String,用于JSON中。
	 * If the object has an value.toJSONString() method, then that method will be used to produce the JSON text. 
* The method is required to produce a strictly conforming text.
* If the object does not contain a toJSONString method (which is the most common case), then a text will be produced by other means.
* If the value is an array or Collection, then a JSONArray will be made from it and its toJSONString method will be called.
* If the value is a MAP, then a JSONObject will be made from it and its toJSONString method will be called.
* Otherwise, the value's toString method will be called, and the result will be quoted.
* * @param value 需要转为字符串的对象 * @return 字符串 * @throws JSONException If the value is or contains an invalid number. */ protected static String valueToString(Object value) throws JSONException { if (value == null || value instanceof JSONNull) { return "null"; } if (value instanceof JSONString) { try { return ((JSONString) value).toJSONString(); } catch (Exception e) { throw new JSONException(e); } }else if (value instanceof Number) { return NumberUtil.toStr((Number) value); }else if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) { return value.toString(); }else if (value instanceof Map) { Map map = (Map) value; return new JSONObject(map).toString(); }else if (value instanceof Collection) { Collection coll = (Collection) value; return new JSONArray(coll).toString(); }else if (value.getClass().isArray()) { return new JSONArray(value).toString(); }else{ return JSONUtil.quote(value.toString()); } } /** * 尝试转换字符串为number, boolean, or null,无法转换返回String * * @param string A String. * @return A simple JSON value. */ protected static Object stringToValue(String string) { Double d; if(null == string || "null".equalsIgnoreCase(string)){ return JSONNull.NULL; } if (StrUtil.EMPTY.equals(string)) { return string; } if ("true".equalsIgnoreCase(string)) { return Boolean.TRUE; } if ("false".equalsIgnoreCase(string)) { return Boolean.FALSE; } /* If it might be a number, try converting it. If a number cannot be produced, then the value will just be a string. */ char b = string.charAt(0); if ((b >= '0' && b <= '9') || b == '-') { try { if (string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1) { d = Double.valueOf(string); if (!d.isInfinite() && !d.isNaN()) { return d; } } else { Long myLong = new Long(string); if (string.equals(myLong.toString())) { if (myLong == myLong.intValue()) { return myLong.intValue(); } else { return myLong; } } } } catch (Exception ignore) { } } return string; } /** * 将Property的键转化为JSON形式
* 用于识别类似于:com.luxiaolei.package.hutool这类用点隔开的键 * * @param jsonObject JSONObject * @param key 键 * @param value 值 * @return JSONObject */ protected static JSONObject propertyPut(JSONObject jsonObject, Object key, Object value){ String keyStr = Convert.toStr(key); String[] path = StrUtil.split(keyStr, StrUtil.DOT); int last = path.length - 1; JSONObject target = jsonObject; for (int i = 0; i < last; i += 1) { String segment = path[i]; JSONObject nextTarget = target.getJSONObject(segment); if (nextTarget == null) { nextTarget = new JSONObject(); target.put(segment, nextTarget); } target = nextTarget; } target.put(path[last], value); return jsonObject; } /** * JSON转Bean,忽略字段的大小写 * * @param jsonObject JSON对象 * @param bean 目标Bean * @param ignoreError 是否忽略转换错误 * @return 目标Bean */ protected static T toBean(final JSONObject jsonObject, T bean, final boolean ignoreError){ return BeanUtil.fillBean(bean, new ValueProvider(){ @Override public Object value(String key, Type valueType) { return jsonConvert(valueType, jsonObject.get(key), ignoreError); } @Override public boolean containsKey(String key) { return jsonObject.containsKey(key); } }, CopyOptions.create().setIgnoreCase(true).setIgnoreError(ignoreError)); } /** * JSONArray转数组 * @param jsonArray JSONArray * @param arrayClass 数组元素类型 * @param ignoreError 是否忽略转换异常 * @return 数组对象 */ protected static Object[] toArray(final JSONArray jsonArray, Class arrayClass, boolean ignoreError){ final Class componentType = arrayClass.isArray() ? arrayClass.getComponentType() : arrayClass; final Object[] objArray = ArrayUtil.newArray(componentType, jsonArray.size()); for(int i = 0; i < objArray.length; i++){ objArray[i] = jsonConvert(componentType, jsonArray.get(i), ignoreError); } return objArray; } /** * JSON递归转换
* 首先尝试JDK类型转换,如果失败尝试JSON转Bean * @param type 目标类型 * @param value 值 * @param ignoreError 是否忽略转换错误 * @return 目标类型的值 * @throws ConvertException 转换失败 */ protected static Object jsonConvert(Type type, Object value, boolean ignoreError) throws ConvertException{ if(null == value){ return null; } if(value instanceof JSONNull){ return null; } final Class rowType = TypeUtil.getClass(type); if(null == rowType) { throw new IllegalArgumentException(StrUtil.format("Can not know Class of Type {} !", type)); } if(JSON.class.isAssignableFrom(rowType)) { //目标为JSON格式 return JSONUtil.parse(value); } Object targetValue = null; //非标准转换格式 if(value instanceof JSONObject){ targetValue = ((JSONObject)value).toBean(rowType, ignoreError); }else if(value instanceof JSONArray){ if(rowType.isArray()){ //目标为数组 targetValue = ((JSONArray)value).toArray(rowType, ignoreError); }else{ targetValue = (new CollectionConverter(rowType, TypeUtil.getTypeArgument(type))).convert(value, null); } } //标准格式转换 if(null == targetValue){ try { targetValue = ConverterRegistry.getInstance().convert(rowType, value); } catch (ConvertException e) { if(ignoreError) { return null; } throw e; } } if(null == targetValue && false == ignoreError){ if(value instanceof CharSequence && StrUtil.isBlank((CharSequence)value)) { //对于传入空字符串的情况,如果转换的目标对象是非字符串或非原书类型,转换器会返回false。 //此处特殊处理,认为返回null属于正常情况 return null; } throw new ConvertException("Can not convert [{}] to type [{}]", value, rowType.getName()); } return targetValue; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy