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

cn.hutool.json.ObjectMapper Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.json;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ArrayIter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutablePair;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONObjectSerializer;
import cn.hutool.json.serialize.JSONSerializer;

import java.io.InputStream;
import java.io.Reader;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * 对象和JSON映射器,用于转换对象为JSON,支持:
 * 
    *
  • Map 转 JSONObject,将键值对加入JSON对象
  • *
  • Map.Entry 转 JSONObject
  • *
  • CharSequence 转 JSONObject,使用JSONTokener解析
  • *
  • {@link Reader} 转 JSONObject,使用JSONTokener解析
  • *
  • {@link InputStream} 转 JSONObject,使用JSONTokener解析
  • *
  • JSONTokener 转 JSONObject,直接解析
  • *
  • ResourceBundle 转 JSONObject
  • *
  • Bean 转 JSONObject,调用其getters方法(getXXX或者isXXX)获得值,加入到JSON对象。例如:如果JavaBean对象中有个方法getName(),值为"张三",获得的键值对为:name: "张三"
  • *
* * @author looly * @since 5.8.0 */ public class ObjectMapper { /** * 创建ObjectMapper * * @param source 来源对象 * @return ObjectMapper */ public static ObjectMapper of(Object source) { return new ObjectMapper(source); } private final Object source; /** * 构造 * * @param source 来源对象 */ public ObjectMapper(Object source) { this.source = source; } /** * 将给定对象转换为{@link JSONObject} * * @param jsonObject 目标{@link JSONObject} * @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作 */ @SuppressWarnings({"rawtypes", "unchecked"}) public void map(JSONObject jsonObject, Filter> filter) { final Object source = this.source; if (null == source) { return; } // 自定义序列化 final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass()); if (serializer instanceof JSONObjectSerializer) { serializer.serialize(jsonObject, source); return; } if (source instanceof JSONArray) { // 不支持集合类型转换为JSONObject throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass()); } if (source instanceof Map) { // Map for (final Map.Entry e : ((Map) source).entrySet()) { jsonObject.set(Convert.toStr(e.getKey()), e.getValue(), filter, jsonObject.getConfig().isCheckDuplicate()); } } else if (source instanceof Map.Entry) { final Map.Entry entry = (Map.Entry) source; jsonObject.set(Convert.toStr(entry.getKey()), entry.getValue(), filter, jsonObject.getConfig().isCheckDuplicate()); } else if (source instanceof CharSequence) { // 可能为JSON字符串 mapFromStr((CharSequence) source, jsonObject, filter); } else if (source instanceof Reader) { mapFromTokener(new JSONTokener((Reader) source, jsonObject.getConfig()), jsonObject, filter); } else if (source instanceof InputStream) { mapFromTokener(new JSONTokener((InputStream) source, jsonObject.getConfig()), jsonObject, filter); } else if (source instanceof byte[]) { mapFromTokener(new JSONTokener(IoUtil.toStream((byte[]) source), jsonObject.getConfig()), jsonObject, filter); } else if (source instanceof JSONTokener) { // JSONTokener mapFromTokener((JSONTokener) source, jsonObject, filter); } else if (source instanceof ResourceBundle) { // JSONTokener mapFromResourceBundle((ResourceBundle) source, jsonObject, filter); } else if (BeanUtil.isReadableBean(source.getClass())) { // 普通Bean // TODO 过滤器对Bean无效,需补充。 mapFromBean(source, jsonObject); } // 跳过空对象 } /** * 初始化 * * @param jsonArray 目标{@link JSONArray} * @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤 * @throws JSONException 非数组或集合 */ @SuppressWarnings({"rawtypes", "unchecked"}) public void map(JSONArray jsonArray, Filter> filter) throws JSONException { final Object source = this.source; if (null == source) { return; } final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass()); if (null != serializer && JSONArray.class.equals(TypeUtil.getTypeArgument(serializer.getClass()))) { // 自定义序列化 serializer.serialize(jsonArray, source); } else if (source instanceof CharSequence) { // JSON字符串 mapFromStr((CharSequence) source, jsonArray, filter); }else if (source instanceof Reader) { mapFromTokener(new JSONTokener((Reader) source, jsonArray.getConfig()), jsonArray, filter); } else if (source instanceof InputStream) { mapFromTokener(new JSONTokener((InputStream) source, jsonArray.getConfig()), jsonArray, filter); } else if (source instanceof byte[]) { final byte[] bytesSource = (byte[]) source; // 如果是普通的的byte[], 要避免下标越界 if (bytesSource.length > 1 && '[' == bytesSource[0] && ']' == bytesSource[bytesSource.length - 1]) { mapFromTokener(new JSONTokener(IoUtil.toStream(bytesSource), jsonArray.getConfig()), jsonArray, filter); }else{ // https://github.com/dromara/hutool/issues/2369 // 非标准的二进制流,则按照普通数组对待 for(final byte b : bytesSource){ jsonArray.add(b); } } } else if (source instanceof JSONTokener) { mapFromTokener((JSONTokener) source, jsonArray, filter); } else { final Iterator iter; if (ArrayUtil.isArray(source)) {// 数组 iter = new ArrayIter<>(source); } else if (source instanceof Iterator) {// Iterator iter = ((Iterator) source); } else if (source instanceof Iterable) {// Iterable iter = ((Iterable) source).iterator(); } else { if(false == jsonArray.getConfig().isIgnoreError()){ throw new JSONException("JSONArray initial value should be a string or collection or array."); } // 如果用户选择跳过异常,则跳过此值转换 return; } final JSONConfig config = jsonArray.getConfig(); Object next; while (iter.hasNext()) { next = iter.next(); // 检查循环引用 if (next != source) { jsonArray.addRaw(JSONUtil.wrap(next, config), filter); } } } } /** * 从{@link ResourceBundle}转换 * * @param bundle ResourceBundle * @param jsonObject {@link JSONObject} * @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤 * @since 5.3.1 */ private static void mapFromResourceBundle(ResourceBundle bundle, JSONObject jsonObject, Filter> filter) { Enumeration keys = bundle.getKeys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); if (key != null) { InternalJSONUtil.propertyPut(jsonObject, key, bundle.getString(key), filter); } } } /** * 从字符串转换 * * @param source JSON字符串 * @param jsonObject {@link JSONObject} * @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤 */ private static void mapFromStr(CharSequence source, JSONObject jsonObject, Filter> filter) { final String jsonStr = StrUtil.trim(source); if (StrUtil.startWith(jsonStr, '<')) { // 可能为XML XML.toJSONObject(jsonObject, jsonStr, false); return; } mapFromTokener(new JSONTokener(StrUtil.trim(source), jsonObject.getConfig()), jsonObject, filter); } /** * 初始化 * * @param source JSON字符串 * @param jsonArray {@link JSONArray} * @param filter 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤 */ private void mapFromStr(CharSequence source, JSONArray jsonArray, Filter> filter) { if (null != source) { mapFromTokener(new JSONTokener(StrUtil.trim(source), jsonArray.getConfig()), jsonArray, filter); } } /** * 从{@link JSONTokener}转换 * * @param x JSONTokener * @param jsonObject {@link JSONObject} * @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作 */ private static void mapFromTokener(JSONTokener x, JSONObject jsonObject, Filter> filter) { JSONParser.of(x).parseTo(jsonObject, filter); } /** * 初始化 * * @param x {@link JSONTokener} * @param jsonArray {@link JSONArray} * @param filter 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤 */ private static void mapFromTokener(JSONTokener x, JSONArray jsonArray, Filter> filter) { JSONParser.of(x).parseTo(jsonArray, filter); } /** * 从Bean转换 * * @param bean Bean对象 * @param jsonObject {@link JSONObject} */ private static void mapFromBean(Object bean, JSONObject jsonObject) { BeanUtil.beanToMap(bean, jsonObject, InternalJSONUtil.toCopyOptions(jsonObject.getConfig())); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy