All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.netty.protocol.nrpc.codec.FastJsonDataCodec Maven / Gradle / Ivy
package com.github.netty.protocol.nrpc.codec;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.github.netty.protocol.nrpc.RpcClient;
import com.github.netty.protocol.nrpc.RpcMethod;
import com.github.netty.protocol.nrpc.RpcServerInstance;
import com.github.netty.protocol.nrpc.exception.RpcDecodeException;
import com.github.netty.protocol.nrpc.exception.RpcEncodeException;
import io.netty.util.concurrent.FastThreadLocal;
import java.lang.reflect.Type;
import java.nio.charset.CharsetDecoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
/**
* com.alibaba.fastjson
*
* @author wangzihao
*/
public class FastJsonDataCodec implements DataCodec {
private static final byte[] EMPTY = {};
private static final FastThreadLocal> PARAMETER_MAP_LOCAL = new FastThreadLocal>() {
@Override
protected Map initialValue() throws Exception {
return new LinkedHashMap<>(32);
}
};
private static final FastThreadLocal CHARSET_DECODER_LOCAL = new FastThreadLocal() {
@Override
protected CharsetDecoder initialValue() throws Exception {
return CHARSET_UTF8.newDecoder();
}
};
private static SerializerFeature[] SERIALIZER_FEATURES = {
// SerializerFeature.WriteClassName
};
private static Feature[] FEATURES = {
Feature.AutoCloseSource,
Feature.InternFieldNames,
Feature.UseBigDecimal,
Feature.AllowUnQuotedFieldNames,
Feature.AllowSingleQuotes,
Feature.AllowArbitraryCommas,
Feature.SortFeidFastMatch,
Feature.IgnoreNotMatch
};
private static int FEATURE_MASK = Feature.of(FEATURES);
private static ParserConfig globalParserConfig = new ParserConfig();
private static SerializeConfig globalSerializeConfig = new SerializeConfig();
static {
// Preheat code
try {
Class.forName("com.alibaba.fastjson.util.TypeUtils");
Class.forName("com.alibaba.fastjson.JSON");
Class.forName("com.alibaba.fastjson.util.ASMClassLoader");
Class.forName("com.alibaba.fastjson.util.IOUtils");
} catch (ClassNotFoundException e) {
//
}
}
private ParserConfig parserConfig;
private SerializeConfig serializeConfig;
private List>> encodeRequestConsumerList = new CopyOnWriteArrayList<>();
private List>> decodeRequestConsumerList = new CopyOnWriteArrayList<>();
public FastJsonDataCodec() {
this(globalParserConfig, globalSerializeConfig);
}
public FastJsonDataCodec(ParserConfig parserConfig, SerializeConfig serializeConfig) {
this.parserConfig = parserConfig;
this.serializeConfig = serializeConfig;
}
public static SerializeConfig getGlobalSerializeConfig() {
return globalSerializeConfig;
}
public static void setGlobalSerializeConfig(SerializeConfig globalSerializeConfig) {
FastJsonDataCodec.globalSerializeConfig = globalSerializeConfig;
}
public static SerializerFeature[] getSerializerFeatures() {
return SERIALIZER_FEATURES;
}
public static void setSerializerFeatures(SerializerFeature[] serializerFeatures) {
SERIALIZER_FEATURES = serializerFeatures;
}
public static ParserConfig getGlobalParserConfig() {
return globalParserConfig;
}
public static void setGlobalParserConfig(ParserConfig globalParserConfig) {
FastJsonDataCodec.globalParserConfig = globalParserConfig;
}
@Override
public List>> getEncodeRequestConsumerList() {
return encodeRequestConsumerList;
}
@Override
public List>> getDecodeRequestConsumerList() {
return decodeRequestConsumerList;
}
@Override
public byte[] encodeRequestData(Object[] data, RpcMethod rpcMethod) {
String[] parameterNames = rpcMethod.getParameterNames();
Map parameterMap = PARAMETER_MAP_LOCAL.get();
if (data != null && data.length != 0) {
for (int i = 0; i < parameterNames.length; i++) {
String name = parameterNames[i];
if (name == null) {
continue;
}
Object value = data[i];
parameterMap.put(name, value);
}
}
try {
for (Consumer> consumer : encodeRequestConsumerList) {
consumer.accept(parameterMap);
}
if (parameterMap.isEmpty()) {
return EMPTY;
} else {
try {
return JSON.toJSONBytes(parameterMap, SERIALIZER_FEATURES);
} catch (Exception e) {
throw new RpcEncodeException("encodeRequestData " + rpcMethod + " fastjson error " + e, e);
}
}
} finally {
parameterMap.clear();
}
}
@Override
public Object[] decodeRequestData(byte[] data, RpcMethod rpcMethod) {
Map parameterMap;
if (data != null && data.length != 0) {
try {
parameterMap = (Map) JSON.parse(data, 0, data.length, CHARSET_DECODER_LOCAL.get(), FEATURE_MASK);
} catch (Exception e) {
throw new RpcDecodeException("decodeRequestData " + rpcMethod + " fastjson error " + e, e);
}
} else {
parameterMap = PARAMETER_MAP_LOCAL.get();
}
try {
for (Consumer> consumer : decodeRequestConsumerList) {
consumer.accept(parameterMap);
}
String[] parameterNames = rpcMethod.getParameterNames();
Object[] parameterValues = new Object[parameterNames.length];
Class>[] parameterTypes = rpcMethod.getParameterTypes();
for (int i = 0; i < parameterNames.length; i++) {
Class> type = parameterTypes[i];
String name = parameterNames[i];
Object value = parameterMap.get(name);
if (value == null && !parameterMap.containsKey(name)) {
value = parameterMap.get("arg" + i);
}
if (value == null && name.length() > 1) {
String upperCaseName = Character.toUpperCase(name.charAt(0)) + name.substring(1);
value = parameterMap.get(upperCaseName);
}
if (isNeedCast(value, type)) {
value = cast(value, type);
}
parameterValues[i] = value;
}
return parameterValues;
} finally {
parameterMap.clear();
}
}
@Override
public byte[] encodeResponseData(Object data, RpcMethod rpcMethod) {
if (data == null) {
return EMPTY;
}
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out, serializeConfig);
serializer.write(data);
return out.toBytes(CHARSET_UTF8.name());
} catch (Exception e) {
throw new RpcEncodeException("encodeResponseData " + rpcMethod + " fastjson error " + e, e);
} finally {
close(out);
}
}
@Override
public Object decodeResponseData(byte[] data, RpcMethod rpcMethod) {
if (data == null || data.length == 0) {
return null;
}
Type returnType = rpcMethod.getGenericReturnType();
try {
return JSON.parseObject(data, returnType, FEATURES);
} catch (Exception e) {
throw new RpcDecodeException("decodeResponseData " + rpcMethod + " fastjson error " + e, e);
}
}
@Override
public Object decodeChunkResponseData(byte[] data, Type type) {
if (data == null || data.length == 0) {
return null;
}
try {
return JSON.parseObject(data, type, FEATURES);
} catch (Exception e) {
throw new RpcDecodeException("decodeChunkResponseData " + type + " fastjson error " + e, e);
}
}
@Override
public byte[] encodeChunkResponseData(Object data) {
if (data == null) {
return EMPTY;
}
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out, serializeConfig);
serializer.write(data);
return out.toBytes(CHARSET_UTF8.name());
} catch (Exception e) {
throw new RpcEncodeException("encodeChunkResponseData " + data.getClass() + " fastjson error " + e, e);
} finally {
close(out);
}
}
protected boolean isNeedCast(Object value, Class> type) {
if (value == null) {
return false;
}
//The class information corresponding to type is the superclass or superinterface of the class information corresponding to arg object. Simply understood, type is the superclass or interface of arg
return !type.isAssignableFrom(value.getClass());
}
protected Object cast(Object value, Class> type) {
try {
return TypeUtils.cast(value, type, parserConfig);
} catch (Exception e) {
return value;
}
}
private static void close(Object out){
if (out instanceof AutoCloseable) {
try {
((AutoCloseable) out).close();
} catch (Exception ignored) {
}
}
}
}