196 lines
6.8 KiB
Java
196 lines
6.8 KiB
Java
package com.jsh.erp.utils;
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.parser.ParserConfig;
|
|
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
|
|
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
|
|
import com.alibaba.fastjson.serializer.*;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Type;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* @author jishenghua qq752718920 2018-10-7 15:26:27
|
|
*/
|
|
public class ExtJsonUtils {
|
|
private static class NPFloatCodec extends FloatCodec {
|
|
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType) throws IOException {
|
|
SerializeWriter out = serializer.getWriter();
|
|
|
|
if (object == null) {
|
|
if (serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) {
|
|
out.write('0');
|
|
} else {
|
|
out.writeNull();
|
|
}
|
|
return;
|
|
}
|
|
|
|
float floatValue = (Float) object;
|
|
|
|
if (Float.isNaN(floatValue)) {
|
|
out.writeNull();
|
|
} else if (Float.isInfinite(floatValue)) {
|
|
out.writeNull();
|
|
} else {
|
|
String floatText = Float.toString(floatValue);
|
|
out.write(floatText);
|
|
|
|
if (serializer.isEnabled(SerializerFeature.WriteClassName)) {
|
|
out.write('F');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class NPDoubleSerializer extends DoubleSerializer {
|
|
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType) throws IOException {
|
|
SerializeWriter out = serializer.getWriter();
|
|
|
|
if (object == null) {
|
|
if (!serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) {
|
|
out.writeNull();
|
|
} else {
|
|
out.write('0');
|
|
}
|
|
return;
|
|
}
|
|
|
|
double doubleValue = (Double) object;
|
|
|
|
if (Double.isNaN(doubleValue)) {
|
|
out.writeNull();
|
|
} else if (Double.isInfinite(doubleValue)) {
|
|
out.writeNull();
|
|
} else {
|
|
String doubleText;
|
|
doubleText = Double.toString(doubleValue);
|
|
out.append(doubleText);
|
|
|
|
if (serializer.isEnabled(SerializerFeature.WriteClassName)) {
|
|
out.write('D');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static final String EXT_NAME = "ext";
|
|
|
|
static class ExtFilter extends AfterFilter implements PropertyFilter {
|
|
static {
|
|
SerializeConfig.getGlobalInstance().put(Float.class, new NPFloatCodec());
|
|
SerializeConfig.getGlobalInstance().put(float.class, new NPFloatCodec());
|
|
SerializeConfig.getGlobalInstance().put(Double.class, new NPDoubleSerializer());
|
|
SerializeConfig.getGlobalInstance().put(double.class, new NPDoubleSerializer());
|
|
}
|
|
|
|
private Map<Object, JSONObject> map = new HashMap<>();
|
|
|
|
private Map<Object, Set<String>> ignoredKey = new HashMap<>();
|
|
|
|
@Override
|
|
public boolean apply(Object object, String name, Object value) {
|
|
if (name.equals(EXT_NAME) && value instanceof String) {
|
|
map.put(object, JSON.parseObject((String) value));
|
|
return false;
|
|
}
|
|
if (!map.containsKey(object)) {
|
|
ignoredKey.put(object, new HashSet<String>());
|
|
}
|
|
ignoredKey.get(object).add(name);
|
|
// if (value instanceof Float || value instanceof Double) {
|
|
// if (!floatMap.containsKey(object)) {
|
|
// floatMap.put(object, new HashMap<String, Object>());
|
|
// }
|
|
// floatMap.get(object).put(name, value);
|
|
// return false;
|
|
// }
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void writeAfter(Object object) {
|
|
if (map.containsKey(object)) {
|
|
Set<String> ignoredKeys;
|
|
if (ignoredKey.containsKey(object)) {
|
|
ignoredKeys = ignoredKey.get(object);
|
|
} else {
|
|
ignoredKeys = new HashSet<>();
|
|
}
|
|
for (Map.Entry<String, Object> entry : map.get(object).entrySet()) {
|
|
if (!ignoredKeys.contains(entry.getKey())) {
|
|
writeKeyValue(entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static String toJSONString(Object object) {
|
|
return JSON.toJSONString(object, new ExtFilter());
|
|
}
|
|
|
|
public interface ExtExtractor {
|
|
String getExt(Object bean);
|
|
}
|
|
|
|
private static class MetaInfo {
|
|
private final static ParserConfig INSTANCE = ParserConfig.getGlobalInstance();
|
|
|
|
private final Object object;
|
|
private final Map<String, FieldDeserializer> map;
|
|
private final JSONObject ext = new JSONObject();
|
|
|
|
private MetaInfo(Object object) {
|
|
this.object = object;
|
|
this.map = INSTANCE.getFieldDeserializers(object.getClass());
|
|
}
|
|
|
|
void gather(String key, Object value) {
|
|
if (!map.containsKey(key)) {
|
|
ext.put(key, value);
|
|
}
|
|
}
|
|
|
|
public void update(ExtExtractor extractor) {
|
|
JSONObject old = JSON.parseObject(extractor.getExt(object));
|
|
if (old == null) {
|
|
old = new JSONObject();
|
|
}
|
|
old.putAll(ext);
|
|
map.get(EXT_NAME).setValue(object, old.toJSONString());
|
|
}
|
|
|
|
static boolean hasExt(Class<?> clazz) {
|
|
return INSTANCE.getFieldDeserializers(clazz).containsKey(EXT_NAME);
|
|
}
|
|
}
|
|
|
|
public static <T> T parseObject(String text, final Class<T> clazz, ExtExtractor extractor) {
|
|
final Map<Object, MetaInfo> map = new HashMap<>();
|
|
|
|
T object = JSON.parseObject(text, clazz, new ExtraProcessor() {
|
|
@Override
|
|
public void processExtra(Object object, String key, Object value) {
|
|
if (!map.containsKey(object) && MetaInfo.hasExt(object.getClass())) {
|
|
map.put(object, new MetaInfo(object));
|
|
}
|
|
if (map.containsKey(object)) {
|
|
map.get(object).gather(key, value);
|
|
}
|
|
}
|
|
});
|
|
|
|
for (Map.Entry<Object, MetaInfo> entry : map.entrySet()) {
|
|
entry.getValue().update(extractor);
|
|
}
|
|
|
|
return object;
|
|
}
|
|
}
|