xiejun
2024-11-01 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/MappingApiJackson2HttpMessageConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
package org.springblade.core.tool.jackson;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springblade.core.tool.utils.Charsets;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
 * é’ˆå¯¹ api æœåС坹 android å’Œ ios å¤„理的 åˆ†è¯»å†™çš„ jackson å¤„理
 *
 * <p>
 * 1. app ç«¯ä¸ŠæŠ¥æ•°æ®æ˜¯ ä½¿ç”¨ readObjectMapper
 * 2. è¿”回给 app ç«¯çš„æ•°æ®ä½¿ç”¨ writeObjectMapper
 * 3. å¦‚果是返回字符串,直接相应,不做 json å¤„理
 * </p>
 *
 * @author L.cm
 */
public class MappingApiJackson2HttpMessageConverter extends AbstractReadWriteJackson2HttpMessageConverter {
   @Nullable
   private String jsonPrefix;
   public MappingApiJackson2HttpMessageConverter(ObjectMapper objectMapper, BladeJacksonProperties properties) {
      super(objectMapper, initWriteObjectMapper(objectMapper, properties), initMediaType(properties));
   }
   private static List<MediaType> initMediaType(BladeJacksonProperties properties) {
      List<MediaType> supportedMediaTypes = new ArrayList<>();
      supportedMediaTypes.add(MediaType.APPLICATION_JSON);
      supportedMediaTypes.add(new MediaType("application", "*+json"));
      // æ”¯æŒ text æ–‡æœ¬ï¼Œç”¨äºŽæŠ¥æ–‡ç­¾å
      if (Boolean.TRUE.equals(properties.getSupportTextPlain())) {
         supportedMediaTypes.add(MediaType.TEXT_PLAIN);
      }
      return supportedMediaTypes;
   }
   private static ObjectMapper initWriteObjectMapper(ObjectMapper readObjectMapper, BladeJacksonProperties properties) {
      // æ‹·è´ readObjectMapper
      ObjectMapper writeObjectMapper = readObjectMapper.copy();
      // å¤§æ•°å­— è½¬ å­—符串
      if (Boolean.TRUE.equals(properties.getBigNumToString())) {
         writeObjectMapper.registerModules(BladeNumberModule.INSTANCE);
      }
      // null å¤„理
      if (Boolean.TRUE.equals(properties.getNullToEmpty())) {
         writeObjectMapper.setSerializerFactory(writeObjectMapper.getSerializerFactory().withSerializerModifier(new BladeBeanSerializerModifier()));
         writeObjectMapper.getSerializerProvider().setNullValueSerializer(BladeBeanSerializerModifier.NullJsonSerializers.STRING_JSON_SERIALIZER);
      }
      return writeObjectMapper;
   }
   @Override
   protected void writeInternal(@NonNull Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
      // å¦‚果是字符串,直接写出
      if (object instanceof String) {
         Charset defaultCharset = this.getDefaultCharset();
         Charset charset = defaultCharset == null ? Charsets.UTF_8 : defaultCharset;
         StreamUtils.copy((String) object, charset, outputMessage.getBody());
      } else {
         super.writeInternal(object, type, outputMessage);
      }
   }
   /**
    * Specify a custom prefix to use for this view's JSON output.
    * Default is none.
    *
    * @param jsonPrefix jsonPrefix
    * @see #setPrefixJson
    */
   public void setJsonPrefix(@Nullable String jsonPrefix) {
      this.jsonPrefix = jsonPrefix;
   }
   /**
    * Indicate whether the JSON output by this view should be prefixed with ")]}', ". Default is false.
    * <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
    * The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
    * This prefix should be stripped before parsing the string as JSON.
    *
    * @param prefixJson prefixJson
    * @see #setJsonPrefix
    */
   public void setPrefixJson(boolean prefixJson) {
      this.jsonPrefix = (prefixJson ? ")]}', " : null);
   }
   @Override
   protected void writePrefix(@NonNull JsonGenerator generator, @NonNull Object object) throws IOException {
      if (this.jsonPrefix != null) {
         generator.writeRaw(this.jsonPrefix);
      }
   }
}