Solon v3.5.1

上下文序列化器 ContextSerializer

</> markdown

前置参考:

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;
        }
    }
}