xiejun
2024-11-01 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/AbstractReadWriteJackson2HttpMessageConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package org.springblade.core.tool.jackson;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import org.springblade.core.tool.utils.Charsets;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.TypeUtils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
 * åˆ†è¯»å†™çš„ json æ¶ˆæ¯ å¤„理器
 *
 * @author L.cm
 */
public abstract class AbstractReadWriteJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
   private static final java.nio.charset.Charset DEFAULT_CHARSET = Charsets.UTF_8;
   private final ObjectMapper writeObjectMapper;
   @Nullable
   private PrettyPrinter ssePrettyPrinter;
   public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper) {
      super(readObjectMapper);
      this.writeObjectMapper = writeObjectMapper;
      initSsePrettyPrinter();
   }
   public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, MediaType supportedMediaType) {
      this(readObjectMapper, writeObjectMapper);
      setSupportedMediaTypes(Collections.singletonList(supportedMediaType));
      initSsePrettyPrinter();
   }
   public AbstractReadWriteJackson2HttpMessageConverter(ObjectMapper readObjectMapper, ObjectMapper writeObjectMapper, List<MediaType> supportedMediaTypes) {
      this(readObjectMapper, writeObjectMapper);
      setSupportedMediaTypes(supportedMediaTypes);
   }
   private void initSsePrettyPrinter() {
      setDefaultCharset(DEFAULT_CHARSET);
      DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
      prettyPrinter.indentObjectsWith(new DefaultIndenter("  ", "\ndata:"));
      this.ssePrettyPrinter = prettyPrinter;
   }
   @Override
   public boolean canWrite(@NonNull Class<?> clazz, @Nullable MediaType mediaType) {
      if (!canWrite(mediaType)) {
         return false;
      }
      AtomicReference<Throwable> causeRef = new AtomicReference<>();
      if (this.defaultObjectMapper.canSerialize(clazz, causeRef)) {
         return true;
      }
      logWarningIfNecessary(clazz, causeRef.get());
      return false;
   }
   @Override
   protected void writeInternal(@NonNull Object object, @Nullable Type type, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {
      MediaType contentType = outputMessage.getHeaders().getContentType();
      JsonEncoding encoding = getJsonEncoding(contentType);
      JsonGenerator generator = this.writeObjectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
      try {
         writePrefix(generator, object);
         Object value = object;
         Class<?> serializationView = null;
         FilterProvider filters = null;
         JavaType javaType = null;
         if (object instanceof MappingJacksonValue) {
            MappingJacksonValue container = (MappingJacksonValue) object;
            value = container.getValue();
            serializationView = container.getSerializationView();
            filters = container.getFilters();
         }
         if (type != null && TypeUtils.isAssignable(type, value.getClass())) {
            javaType = getJavaType(type, null);
         }
         ObjectWriter objectWriter = (serializationView != null ?
            this.writeObjectMapper.writerWithView(serializationView) : this.writeObjectMapper.writer());
         if (filters != null) {
            objectWriter = objectWriter.with(filters);
         }
         if (javaType != null && javaType.isContainerType()) {
            objectWriter = objectWriter.forType(javaType);
         }
         SerializationConfig config = objectWriter.getConfig();
         if (contentType != null && contentType.isCompatibleWith(MediaType.TEXT_EVENT_STREAM) &&
            config.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
            objectWriter = objectWriter.with(this.ssePrettyPrinter);
         }
         objectWriter.writeValue(generator, value);
         writeSuffix(generator, object);
         generator.flush();
      } catch (InvalidDefinitionException ex) {
         throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex);
      } catch (JsonProcessingException ex) {
         throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getOriginalMessage(), ex);
      }
   }
}