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

com.jfinal.json.JFinalJsonKit Maven / Gradle / Ivy

There is a newer version: 5.2.2
Show newest version
/**
 * Copyright (c) 2011-2023, James Zhan 詹波 ([email protected]).
 *
 * 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.jfinal.json;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import com.jfinal.kit.StrKit;
import com.jfinal.kit.SyncWriteMap;
import com.jfinal.kit.TimeKit;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;

/**
 * JFinalJsonKit
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class JFinalJsonKit {
	
	public static final JFinalJsonKit me = new JFinalJsonKit();
	
	// 缓存 ToJson 对象
	protected static SyncWriteMap, ToJson> cache = new SyncWriteMap<>(512, 0.25F);
	
	// StringBuilder 最大缓冲区大小
	protected static int maxBufferSize = 1024 * 512;
	
	// 将 Model 当成 Bean 只对 getter 方法进行转换
	protected static boolean treatModelAsBean = false;
	
	// 是否跳过 null 值的字段,不对其进行转换
	protected static boolean skipNullValueField = false;
	
	// 对 Model 和 Record 的字段名进行转换的函数。例如转成驼峰形式对 oracle 支持更友好
	protected static Function modelAndRecordFieldNameConverter = null;
	
	protected static Function> toJsonFactory = null;
	
	public interface ToJson {
		void toJson(T value, int depth, JsonResult ret);
	}
	
	public ToJson getToJson(Object object) {
		ToJson ret = cache.get(object.getClass());
		if (ret == null) {
			ret = createToJson(object);
			cache.putIfAbsent(object.getClass(), ret);
		}
		return ret;
	}
	
	/**
	 * 添加 ToJson 转换接口实现类,自由定制任意类型数据的转换规则
	 * 
	 * 例子:
	 *     ToJson toJson = (value, depth, ret) -> {
	 *       ret.addLong(value.getTime());
	 *     };
	 *     
	 *     JFinalJson.addToJson(Timestamp.class, toJson);
	 *     
	 *     以上代码为 Timestamp 类型的 json 转换定制了转换规则
	 *     将其转换成了 long 型数据
	 * 
*/ public static void addToJson(Class type, ToJson toJson) { Objects.requireNonNull(type, "type can not be null"); Objects.requireNonNull(toJson, "toJson can not be null"); cache.put(type, toJson); } protected ToJson createToJson(Object value) { // 优先使用 toJsonFactory 创建 ToJson 实例,方便用户优先接管 ToJson 转换器的创建 if (toJsonFactory != null) { ToJson tj = toJsonFactory.apply(value); if (tj != null) { return tj; } } // 基础类型 ----------------------------------------- if (value instanceof String) { return new StrToJson(); } if (value instanceof Number) { if (value instanceof Integer) { return new IntToJson(); } if (value instanceof Long) { return new LongToJson(); } if (value instanceof Double) { return new DoubleToJson(); } if (value instanceof Float) { return new FloatToJson(); } return new NumberToJson(); } if (value instanceof Boolean) { return new BooleanToJson(); } if (value instanceof Character) { return new CharacterToJson(); } if (value instanceof Enum) { return new EnumToJson(); } if (value instanceof java.util.Date) { if (value instanceof Timestamp) { return new TimestampToJson(); } if (value instanceof Time) { return new TimeToJson(); } return new DateToJson(); } if (value instanceof Temporal) { if (value instanceof LocalDateTime) { return new LocalDateTimeToJson(); } if (value instanceof LocalDate) { return new LocalDateToJson(); } if (value instanceof LocalTime) { return new LocalTimeToJson(); } } // 集合、Bean 类型,需要检测 depth --------------------------------- if (! treatModelAsBean) { if (value instanceof Model) { return new ModelToJson(); } } if (value instanceof Record) { return new RecordToJson(); } if (value instanceof Map) { return new MapToJson(); } if (value instanceof Collection) { return new CollectionToJson(); } if (value.getClass().isArray()) { return new ArrayToJson(); } if (value instanceof Enumeration) { return new EnumerationToJson(); } if (value instanceof Iterator) { return new IteratorToJson(); } if (value instanceof Iterable) { return new IterableToJson(); } BeanToJson beanToJson = buildBeanToJson(value); if (beanToJson != null) { return beanToJson; } return new UnknownToJson(); } public static boolean checkDepth(int depth, JsonResult ret) { if (depth < 0) { ret.addNull(); return true; } else { return false; } } static class StrToJson implements ToJson { public void toJson(String str, int depth, JsonResult ret) { escape(str, ret.sb); } } static class CharacterToJson implements ToJson { public void toJson(Character ch, int depth, JsonResult ret) { escape(ch.toString(), ret.sb); } } static class IntToJson implements ToJson { public void toJson(Integer value, int depth, JsonResult ret) { ret.addInt(value); } } static class LongToJson implements ToJson { public void toJson(Long value, int depth, JsonResult ret) { ret.addLong(value); } } static class DoubleToJson implements ToJson { public void toJson(Double value, int depth, JsonResult ret) { if (value.isInfinite() || value.isNaN()) { ret.addNull(); } else { ret.addDouble(value); } } } static class FloatToJson implements ToJson { public void toJson(Float value, int depth, JsonResult ret) { if (value.isInfinite() || value.isNaN()) { ret.addNull(); } else { ret.addFloat(value); } } } // 接管 int、long、double、float 之外的 Number 类型 static class NumberToJson implements ToJson { public void toJson(Number value, int depth, JsonResult ret) { ret.addNumber(value); } } static class BooleanToJson implements ToJson { public void toJson(Boolean value, int depth, JsonResult ret) { ret.addBoolean(value); } } static class EnumToJson implements ToJson { public void toJson(Enum en, int depth, JsonResult ret) { ret.addEnum(en); } } static class TimestampToJson implements ToJson { public void toJson(Timestamp ts, int depth, JsonResult ret) { ret.addTimestamp(ts); } } static class TimeToJson implements ToJson