上下文序列化器 ContextSerializer
前置参考:
1、接口声明
package org.noear.solon.serialization;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.serialize.Serializer;
import org.noear.solon.lang.Nullable;
public interface ContextSerializer<T> extends Serializer<T> {
/**
* 匹配
*
* @param ctx 上下文
* @param mime
*/
boolean matched(Context ctx, String mime);
/**
* 媒体类型
*/
String mimeType();
/**
* 必须要 body
*/
default boolean bodyRequired() {
return false;
}
/**
* 序列化到
*
* @param ctx 请求上下文
* @param data 数据
*/
void serializeToBody(Context ctx, Object data) throws IOException;
/**
* 反序列化从
*
* @param ctx 请求上下文
* @param toType 目标类型
* @since 3.0
*/
Object deserializeFromBody(Context ctx, @Nullable Type toType) throws IOException;
/**
* 反序列化从
*
* @param ctx 请求上下文
*/
default Object deserializeFromBody(Context ctx) throws IOException {
return deserializeFromBody(ctx, null);
}
}
2、定制参考1
public class AbcBytesSerializer implements ContextSerializer<byte[]> {
private static final String label = "application/abc";
private static final AbcBytesSerializer instance = new AbcBytesSerializer();
public static AbcBytesSerializer getInstance() {
return instance;
}
@Override
public String mimeType() {
return label;
}
@Override
public Class<byte[]> dataType() {
return byte[].class;
}
@Override
public boolean bodyRequired() {
return true;
}
/**
* 序列化器名字
*/
@Override
public String name() {
return "abc-bytes";
}
@Override
public byte[] serialize(Object fromObj) throws IOException {
if (fromObj instanceof AbcSerializable) {
AbcSerializable bs = ((AbcSerializable) fromObj);
Object out = bs.serializeFactory().createOutput();
bs.serializeWrite(out);
return bs.serializeFactory().extractBytes(out);
} else {
throw new IllegalStateException("The parameter 'fromObj' is not of AbcSerializable");
}
}
@Override
public Object deserialize(byte[] data, Type toType) throws IOException {
if (toType instanceof Class<?>) {
if (AbcSerializable.class.isAssignableFrom((Class<?>) toType)) {
AbcSerializable tmp = ClassUtil.newInstance((Class<?>) toType);
Object in = tmp.serializeFactory().createInput(data);
tmp.serializeRead(in);
return tmp;
} else {
throw new IllegalStateException("The parameter 'toType' is not of AbcSerializable");
}
} else {
throw new IllegalStateException("The parameter 'toType' is not Class");
}
}
///////////////
@Override
public boolean matched(Context ctx, String mime) {
if (mime == null) {
return false;
} else {
return mime.startsWith(label);
}
}
@Override
public void serializeToBody(Context ctx, Object data) throws IOException {
//如果没有设置过,用默认的 //如 ndjson,sse 或故意改变 mime(可由外部控制)
if (ctx.contentTypeNew() == null) {
ctx.contentType(this.mimeType());
}
if (data instanceof ModelAndView) {
ctx.output(serialize(((ModelAndView) data).model()));
} else {
ctx.output(serialize(data));
}
}
@Override
public Object deserializeFromBody(Context ctx, @Nullable Type bodyType) throws IOException {
return deserialize(ctx.bodyAsBytes(), bodyType);
}
}
3、定制参考2
public class Fastjson2StringSerializer implements ContextSerializer<String> {
private static final String label = "/json";
private JSONWriter.Context serializeConfig;
private JSONReader.Context deserializeConfig;
/**
* 获取序列化配置
*/
public JSONWriter.Context getSerializeConfig() {
if (serializeConfig == null) {
serializeConfig = new JSONWriter.Context(new ObjectWriterProvider());
}
return serializeConfig;
}
/**
* 配置序列化特性
*
* @param isReset 是否重置
* @param isAdd 是否添加
* @param features 特性
*/
public void cfgSerializeFeatures(boolean isReset, boolean isAdd, JSONWriter.Feature... features) {
if (isReset) {
getSerializeConfig().setFeatures(JSONFactory.getDefaultWriterFeatures());
}
for (JSONWriter.Feature feature : features) {
getSerializeConfig().config(feature, isAdd);
}
}
/**
* 获取反序列化配置
*/
public JSONReader.Context getDeserializeConfig() {
if (deserializeConfig == null) {
deserializeConfig = new JSONReader.Context(new ObjectReaderProvider());
}
return deserializeConfig;
}
/**
* 配置反序列化特性
*
* @param isReset 是否重置
* @param isAdd 是否添加
* @param features 特性
*/
public void cfgDeserializeFeatures(boolean isReset, boolean isAdd, JSONReader.Feature... features) {
if (isReset) {
getDeserializeConfig().setFeatures(JSONFactory.getDefaultReaderFeatures());
}
for (JSONReader.Feature feature : features) {
getDeserializeConfig().config(feature, isAdd);
}
}
/**
* 内容类型
*/
@Override
public String mimeType() {
return "application/json";
}
/**
* 数据类型
* */
@Override
public Class<String> dataType() {
return String.class;
}
/**
* 是否匹配
*
* @param ctx 请求上下文
* @param mime 内容类型
*/
@Override
public boolean matched(Context ctx, String mime) {
if (mime == null) {
return false;
} else {
return mime.contains(label) || mime.startsWith(MimeType.APPLICATION_X_NDJSON_VALUE);
}
}
/**
* 序列化器名字
*/
@Override
public String name() {
return "fastjson2-json";
}
/**
* 序列化
*
* @param obj 对象
*/
@Override
public String serialize(Object obj) throws IOException {
return JSON.toJSONString(obj, getSerializeConfig());
}
/**
* 反序列化
*
* @param data 数据
* @param toType 目标类型
*/
@Override
public Object deserialize(String data, Type toType) throws IOException {
if (toType == null) {
return JSON.parse(data, getDeserializeConfig());
} else {
return JSON.parseObject(data, toType, getDeserializeConfig());
}
}
/**
* 序列化主体
*
* @param ctx 请求上下文
* @param data 数据
*/
@Override
public void serializeToBody(Context ctx, Object data) throws IOException {
//如果没有设置过,用默认的 //如 ndjson,sse 或故意改变 mime(可由外部控制)
if (ctx.contentTypeNew() == null) {
ctx.contentType(this.mimeType());
}
if (data instanceof ModelAndView) {
ctx.output(serialize(((ModelAndView) data).model()));
} else {
ctx.output(serialize(data));
}
}
/**
* 反序列化主体
*
* @param ctx 请求上下文
*/
@Override
public Object deserializeFromBody(Context ctx, @Nullable Type bodyType) throws IOException {
String data = ctx.bodyNew();
if (Utils.isNotEmpty(data)) {
return JSON.parse(data, getDeserializeConfig());
} else {
return null;
}
}
}