11

Вопрос по json, java – Обработка альтернативных имен свойств в десериализации Джексона

Я работаю над преобразованием службы REST / JSON из Coldfusion 9 в приложение Spring-MVC 3.1. Я использую Jackson (1.9.5) и MappingJacksonJsonConverter, которые предоставляет Spring, и настраиваю ObjectMapper для именования полей с помощью ...

4 ответа

6

Вы можете использовать PropertyNamingStrategy:

  class CaseInsensitiveNaming extends PropertyNamingStrategy {
    @Override
    public String nameForGetterMethod(MapperConfig<?> config,
         AnnotatedMethod method, String defaultName)
    {
      // case-insensitive, underscores etc. mapping to property names
      // so you need to implement the convert method in way you need.
      return convert(defaultName); 
    }
  }

  objectMapper.setPropertyNamingStrategy(new CaseInsensitiveNaming());
12

Это было исправлено с версии 2.5.0.

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
5

Поскольку вы используете Jackson 1.x, а не Jackson 2.x, вы можете использовать MixIns. Из того, что я понимаю, вы хотите, чтобы десериализация понимала UPPER_CASE, но вы хотите сериализовать в нижнем регистре. Добавьте MixIn в конфигурацию десериализации, но не в конфигурацию сериализации:

public class JsonNamingTest {   
    public static class A {
        private String testField;
        public String getTestField() {
            return testField;
        }
        public void setTestField(String field) {
            this.testField = field;
        }
    }

    public static class MixInA {
        @JsonProperty("TEST_FIELD")
        public void setTestField(String field) {}
    }

    @Test
    public void something() throws Exception {
        A test = new A();
        test.setTestField("test");
        ObjectMapper mapper = new ObjectMapper();
        mapper.getDeserializationConfig().addMixInAnnotations(A.class, MixInA.class);
        assertEquals("{\"test_field\":\"test\"}", mapper.writeValueAsString(test));
        assertEquals("test", mapper.readValue("{\"test_field\":\"test\"}", A.class).getTestField());
        assertEquals("test", mapper.readValue("{\"TEST_FIELD\":\"test\"}", A.class).getTestField());
    }
}

Однако вы не можете сделать это с помощью Jackson 2.x: mixIns совместно используются конфигурацией сериализации и десериализации. Мне еще предстоит найти способ обработки псевдонимов с помощью Jackson 2.x :(

1

При использовании Spring Boot также можно использоватьJackson2ObjectMapperBuilderCustomizer который сохраняет автоконфигурацию по умолчанию. Это можно сделать, добавив компонент:

@Bean
public Jackson2ObjectMapperBuilderCustomizer acceptCaseInsensitive() {
    return builder -> builder.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
}

Похожие вопросы