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

com.alibaba.fastjson2.support.spring6.http.codec.Fastjson2Encoder Maven / Gradle / Ivy

There is a newer version: 2.0.53
Show newest version
package com.alibaba.fastjson2.support.spring6.http.codec;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.*;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import com.alibaba.fastjson2.writer.ObjectWriter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.Hints;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.log.LogFormatUtils;
import org.springframework.http.codec.json.AbstractJackson2Decoder;
import org.springframework.http.codec.json.AbstractJackson2Encoder;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.MimeType;

import java.io.IOException;
import java.util.Map;

/**
 * Fastjson2 for Spring WebFlux.
 *
 * @author Xi.Liu
 * @see AbstractJackson2Decoder
 */
public class Fastjson2Encoder
        extends AbstractJackson2Encoder {
    private final FastJsonConfig config;

    public Fastjson2Encoder(ObjectMapper mapper, MimeType... mimeTypes) {
        super(mapper, mimeTypes);
        this.config = new FastJsonConfig();
    }

    public Fastjson2Encoder(ObjectMapper mapper, FastJsonConfig config, MimeType... mimeTypes) {
        super(mapper, mimeTypes);
        this.config = config;
    }

    @NonNull
    @Override
    public DataBuffer encodeValue(@Nullable Object value,
                                  @NonNull DataBufferFactory bufferFactory,
                                  @NonNull ResolvableType valueType,
                                  MimeType mimeType,
                                  Map hints) {
        try {
            logValue(hints, value);
            if (value instanceof String v && JSON.isValidObject(v)) {
                byte[] strBytes = v.getBytes(this.config.getCharset());
                DataBuffer buffer = bufferFactory.allocateBuffer(strBytes.length);
                buffer.write(strBytes, 0, strBytes.length);
                Hints.touchDataBuffer(buffer, hints, logger);
                return buffer;
            }
            try (JSONWriter writer = JSONWriter.ofUTF8(this.config.getWriterFeatures())) {
                if (value == null) {
                    writer.writeNull();
                } else {
                    writer.setRootObject(value);
                    configFilter(writer.context, this.config.getWriterFilters());
                    Class valueClass = value.getClass();
                    ObjectWriter objectWriter = writer.getObjectWriter(valueClass, valueClass);
                    objectWriter.write(writer, value, null, null, 0);
                }
                DataBuffer buffer = bufferFactory.allocateBuffer(writer.size());
                writer.flushTo(buffer.asOutputStream());
                Hints.touchDataBuffer(buffer, hints, logger);
                return buffer;
            } catch (IOException e) {
                throw new JSONException("JSON#writeTo cannot serialize '" + value + "' to 'OutputStream'", e);
            }
        } catch (JSONException ex) {
            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }

    private void configFilter(JSONWriter.Context context, Filter... filters) {
        if (filters == null || filters.length == 0) {
            return;
        }
        for (Filter filter : filters) {
            if (filter instanceof NameFilter f) {
                if (context.getNameFilter() == null) {
                    context.setNameFilter(f);
                } else {
                    context.setNameFilter(NameFilter.compose(context.getNameFilter(), f));
                }
            }

            if (filter instanceof ValueFilter f) {
                if (context.getValueFilter() == null) {
                    context.setValueFilter(f);
                } else {
                    context.setValueFilter(ValueFilter.compose(context.getValueFilter(), f));
                }
            }

            if (filter instanceof PropertyFilter f) {
                context.setPropertyFilter(f);
            }

            if (filter instanceof PropertyPreFilter f) {
                context.setPropertyPreFilter(f);
            }

            if (filter instanceof BeforeFilter f) {
                context.setBeforeFilter(f);
            }

            if (filter instanceof AfterFilter f) {
                context.setAfterFilter(f);
            }

            if (filter instanceof LabelFilter f) {
                context.setLabelFilter(f);
            }

            if (filter instanceof ContextValueFilter f) {
                context.setContextValueFilter(f);
            }

            if (filter instanceof ContextNameFilter f) {
                context.setContextNameFilter(f);
            }
        }
    }

    private void logValue(@Nullable Map hints, Object value) {
        if (!Hints.isLoggingSuppressed(hints)) {
            LogFormatUtils.traceDebug(logger, traceOn -> {
                String formatted = LogFormatUtils.formatValue(value, !traceOn);
                return Hints.getLogPrefix(hints) + "Encoding [" + formatted + "]";
            });
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy