MappingJackson 2HttpMessageConverter 분류 별 처리 null

6245 단어 JavaSrping
jackson 은 분류 별 처리 null 을 제공 하지 않 았 습 니 다. jackson 의 핵심 클래스 ObjectMapper 가 노출 된 NullSerializer 유형 에 따라 기본 값 을 설정 할 수 없 었 습 니 다. 다행히 jackson 은 완벽 한 확장 체 제 를 가지 고 있 습 니 다.BeanSerializerModifierchangeProperties() 방법 은 모든 Field 의 직렬 화 행 위 를 세밀 하 게 제어 할 수 있 는 가능성 을 제공 합 니 다. 코드 는 다음 과 같 습 니 다.
public enum SerializerFeature {
   WriteNullListAsEmpty,
   WriteNullStringAsEmpty,
   WriteNullNumberAsZero,
   WriteNullBooleanAsFalse;
   
   public final int mask;
   
   SerializerFeature() {
       mask = (1 << ordinal());
   }
}

final public static class FastJsonSerializerFeatureCompatibleForJackson extends BeanSerializerModifier {
   final private JsonSerializer nullBooleanJsonSerializer;
   final private JsonSerializer nullNumberJsonSerializer;
   final private JsonSerializer nullListJsonSerializer;
   final private JsonSerializer nullStringJsonSerializer;
   
   FastJsonSerializerFeatureCompatibleForJackson(SerializerFeature... features) {
       int config = 0;
       for (SerializerFeature feature : features) {
           config |= feature.mask;
       }
       nullBooleanJsonSerializer = (config & WriteNullBooleanAsFalse.mask) != 0 ? new NullBooleanSerializer() : null;
       nullNumberJsonSerializer = (config & WriteNullNumberAsZero.mask) != 0 ? new NullNumberSerializer() : null;
       nullListJsonSerializer = (config & WriteNullListAsEmpty.mask) != 0 ? new NullListJsonSerializer() : null;
       nullStringJsonSerializer = (config & WriteNullStringAsEmpty.mask) != 0 ? new NullStringSerializer() : null;
   }
   
   @Override
   public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) {
       for (BeanPropertyWriter writer : beanProperties) {
           final JavaType javaType = writer.getType();
           final Class> rawClass = javaType.getRawClass();
           if (javaType.isArrayType() || javaType.isCollectionLikeType()) {
               writer.assignNullSerializer(nullListJsonSerializer);
           } else if (Number.class.isAssignableFrom(rawClass) && rawClass.getName().startsWith("java.lang")) {
               writer.assignNullSerializer(nullNumberJsonSerializer);
           } else if (Boolean.class.equals(rawClass)) {
               writer.assignNullSerializer(nullBooleanJsonSerializer);
           } else if (String.class.equals(rawClass)) {
               writer.assignNullSerializer(nullStringJsonSerializer);
           }
       }
       return beanProperties;
   }
   
   private static class NullListJsonSerializer extends JsonSerializer {
       @Override
       public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
           jgen.writeStartArray();
           jgen.writeEndArray();
       }
   }
   
   private static class NullNumberSerializer extends JsonSerializer {
       @Override
       public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
           jgen.writeNumber(0);
       }
   }
   
   private static class NullBooleanSerializer extends JsonSerializer {
       @Override
       public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
           jgen.writeBoolean(false);
       }
   }
   
   private static class NullStringSerializer extends JsonSerializer {
       @Override
       public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
           jgen.writeString("");
       }
   }
}

마지막Modifier
주입ObjectMapper
맞다
objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new FastJsonSerializerFeatureCompatibleForJackson(features)));

역 직렬 화 시 존재 하지 않 는 필드 무시
표준 JSon 규범 에서 JSon 문자열 을 지정 한 POJO 로 역 직렬 화 하려 면 문자열 에 Field 가 POJO 에 존재 하지 않 으 므 로 오 류 를 던 져 야 합 니 다.이 경우 fastjson 은 기본적으로 건 너 뛰 고 잭 슨 은 기본적으로 중단 합 니 다.
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

SpringMVC 의 HttpMessage Convertor 를 다시 설정 합 니 다.

      
          
              
                  
                      WriteNullListAsEmpty
                      WriteNullStringAsEmpty
                      WriteNullNumberAsZero
                      WriteNullBooleanAsFalse
                  
              
          
      
  

전역 설정 을 프로 그래 밍 식 으로 설정 해 야 하기 때문에 확장FactoryBean
( CustomObjectMapperFactoryBean
) 사용자 정의 생 성ObjectMapper
대체 하 다MappingJackson2HttpMessageConverter
묵인ObjectMapper
.
final public static class CustomObjectMapperFactoryBean implements FactoryBean {
 SerializerFeature[] features;
 public CustomObjectMapperFactoryBean(SerializerFeature[] features) {
     this.features = features;
 }

 @Override
 public ObjectMapper getObject() throws Exception {
     ObjectMapper objectMapper = new ObjectMapper();
     objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new FastJsonSerializerFeatureCompatibleForJackson(features))).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
     return objectMapper;
 }

 @Override
 public Class> getObjectType() {
     return ObjectMapper.class;
 }

 @Override
 public boolean isSingleton() {
     return false;
 }
}

좋은 웹페이지 즐겨찾기