Как получить доступ к базовому объектному картографу Jackson ObjectMapper в REST Assured?

Мне нужно настроить лежащий в основе Jackson ObjectMapper в REST Assured. Я пишу тесты REST API, используя REST Assured, и мне нужно определить некоторые фильтры для регистрации в ObjectMapper, который используется для сериализации моих объектов в JSON:

    String newTestSuite = "{\"name\":\"Added through Rest API\",\"description\":\"Test Description\",\"steps\":[]}";

    FilterProvider filters = new SimpleFilterProvider().addFilter("createNewTestSuite", new NewTestSuiteFilter());
    ObjectMapper om = new ObjectMapper();
    om.setFilters(filters);

    try {
        TestSuite ts = om.readValue(newCaspianTest, TestSuite.class);

        RequestSpecification requestSpec = new RequestSpecBuilder()
            .setBaseUri("https://somesite.com")
            .setBody(ts)
            .setUrlEncodingEnabled(false)
            .build();

        ResponseSpecification responseSpec = new ResponseSpecBuilder()
            .expectStatusCode(200)
            .expectStatusLine(Matchers.containsString("200 OK"))
            .build();

        RestAssured.given()
            .auth().basic("testUser","testPassword")
            .spec(requestSpec)
            .log().all()
            .post("/restendpoint")
                .then()
                .log().all()
                .spec(responseSpec);

    } catch(JsonParseException jpe) {

    } catch(JsonMappingException jme) {

    } catch(IOException ioe) {

    }
}

}


person Selena    schedule 31.07.2014    source источник


Ответы (4)


Вы можете попробовать это:

RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
new Jackson2ObjectMapperFactory() {
        @Override
        public ObjectMapper create(Class aClass, String s) {
            FilterProvider filter = new SimpleFilterProvider().addFilter(...);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setFilters(filter);
            return objectMapper;
        }
    }
));
person sanj    schedule 31.07.2014
comment
Я пробую это решение прямо сейчас, но у меня есть один вопрос: здесь невозможно использовать параметр типа с аргументом класса, не так ли? Я должен использовать необработанный тип класса? - person Selena; 01.08.2014
comment
Это сработало отлично! У меня действительно была проблема с Eclipse, жалующимся на то, что я не переопределил метод суперкласса, но я обнаружил, что мой уровень соответствия java-компилятору был установлен на 1.5, а поддержка аннотации Override для реализованных методов из интерфейса не была добавлена ​​до java 1.6. Как только я изменил настройки Eclipse, ошибка исчезла. - person Selena; 01.08.2014
comment
Я пробовал это, но мой фильтр никогда не вызывается. Я просмотрел код Джексона, и хотя я вижу, что мой фильтр передается как часть FilterProvider в конфигурации, сам фильтр никогда не вызывается. Были ли у вас подобные трудности? - person torngat; 23.04.2015
comment
Хорошо, я обнаружил, что мне нужно переопределить интроспектор аннотаций, поскольку мои классы никак не относятся к этому фильтру. Однако у меня возникает другой вопрос, который я разместил здесь [stackoverflow.com/questions/29833259/ - person torngat; 23.04.2015

Это даст вам средство сопоставления объектов, которое не взрывается, когда разработчик серверной части решает добавить новое поле.

RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
    new Jackson2ObjectMapperFactory() {
      @Override
      public ObjectMapper create(Type cls, String charset) {
        ObjectMapper om = new ObjectMapper().findAndRegisterModules();
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return om;
      }          

    }
));
person Jason Henriksen    schedule 07.03.2019

Ответ @sanj был очень полезным. Мне пришлось немного изменить его, потому что я использую RestAssuredMockMvc.

Вот как я настраиваю RestAssuredMockMvc для использования snake_case вместо CamelCase:

RestAssuredMockMvc.config = RestAssuredMockMvcConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
            (type, s) -> {
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
                return objectMapper;
            }
    ));
person Bram    schedule 16.01.2019

Учитывая контекст, в котором используется Rest Assured, часто бывает необходимо изменить или указать ObjectMapper, используемый для некоторых запросов, но не для всех.

Вы можете добиться этого, используя методы:

Классический вариант использования, как упоминалось @jason-henriksen, заключается в

  • Разрешить игнорировать неизвестные свойства
  • Игнорировать свойства, определенные в вашем классе ReturnedType, которые не отмечены @JsonIgnore без создания исключения во время десериализации (полезно, когда у вас нет контроля/невозможно изменить этот ReturnedType класс 1)

Это можно сделать с помощью:

RequestSpecification request = ...;
io.restassured.mapper.ObjectMapper objectMapper = new Jackson2Mapper(((type, charset) -> {
    com.fasterxml.jackson.databind.ObjectMapper om = new ObjectMapper().findAndRegisterModules();
    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    return om;
}));
ReturnType response = request.get().as(ReturnType.class, objectMapper);

1 Этого также можно добиться, настроив ObjectMapper с помощью Jackson MixIns .

person surpriz3    schedule 21.08.2020
comment
Это решение отлично сработало для меня! В моем случае десериализация не удалась в .as(...) и передача пользовательского objectMapper была самым простым решением, которое не требовало его изменения везде. - person swiftest; 20.05.2021