Fastjson2Encoder.java
package com.alibaba.fastjson2.support.spring.codec;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import org.reactivestreams.Publisher;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.AbstractEncoder;
import org.springframework.core.codec.EncodingException;
import org.springframework.core.codec.Hints;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.MimeType;
import reactor.core.publisher.Flux;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
/**
* spring message codec encoder for Fastjson2.
*
* @author ���������
* @since 2025/8/6
*/
public final class Fastjson2Encoder
extends AbstractEncoder<Object> {
private final FastJsonConfig config;
/**
* default constructor
*/
public Fastjson2Encoder() {
this(new FastJsonConfig(), MediaType.ALL);
}
/**
* Constructor with custom configs
*
* @param config FastJsonConfig
* @param mimeTypes the mime types to support
*/
public Fastjson2Encoder(FastJsonConfig config, MimeType... mimeTypes) {
super(mimeTypes == null || mimeTypes.length == 0 ? new MimeType[]{MediaType.ALL} : mimeTypes);
this.config = config;
}
@Override
@NonNull
public Flux<DataBuffer> encode(@NonNull Publisher<?> inputStream, @NonNull DataBufferFactory bufferFactory, @NonNull ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
return Flux.from(inputStream)
.map(val -> encodeValue(val, bufferFactory, elementType, mimeType, hints));
}
@Override
@NonNull
public DataBuffer encodeValue(@Nullable Object value, @NonNull DataBufferFactory bufferFactory, @NonNull ResolvableType valueType, MimeType mimeType, Map<String, Object> hints) {
byte[] bytes = null;
// Check if the value is a valid JSON string or byte array
if (value instanceof String) {
String str = (String) value;
if (JSON.isValidObject(str)) {
bytes = str.getBytes(config.getCharset());
}
} else if (value instanceof byte[]) {
byte[] curBytes = (byte[]) value;
if (JSON.isValid(curBytes)) {
bytes = (byte[]) value;
}
}
// If bytes is not null, write it to a DataBuffer
if (bytes != null) {
int length = bytes.length;
DataBuffer buffer = bufferFactory.allocateBuffer(length)
.write(bytes, 0, length);
Hints.touchDataBuffer(buffer, hints, logger);
return buffer;
}
//@see JSON.writeTo
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
JSON.writeTo(
baos,
value,
config.getDateFormat(),
config.getWriterFilters(),
config.getWriterFeatures()
);
DataBuffer buffer = bufferFactory.allocateBuffer(baos.size());
baos.writeTo(buffer.asOutputStream());
Hints.touchDataBuffer(buffer, hints, logger);
return buffer;
} catch (IOException e) {
throw new EncodingException("JSON#writeTo cannot serialize '" + value + "' to 'OutputStream'", e);
}
}
}