如何在REST Assured中访问基础的Jackson ObjectMapper?

26

我需要在REST Assured中配置底层的Jackson ObjectMapper。我正在使用REST Assured编写REST API测试,我需要定义一些过滤器以注册到用于将我的对象序列化为JSON的ObjectMapper:

    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) {

    }
}

}

4个回答

34

你可以尝试这样做:

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;
        }
    }
));

我现在正在尝试这个解决方案,但是我有一个问题——这里不能使用类型参数来作为Class参数,对吗?我必须使用原始类类型? - Selena
这个很好用!我在Eclipse上遇到了一个问题,它抱怨我没有覆盖超类方法,但我发现我的Java编译器兼容级别设置为1.5,并且在Java 1.6之前,对于从接口实现的方法的Override注释的支持还没有添加。一旦我改变了Eclipse的偏好设置,错误就消失了。 - Selena
1
我尝试过这个,但我的过滤器从未被调用。我已经仔细查看了Jackson代码,虽然我在配置中看到我的过滤器作为FilterProvider传递,但过滤器本身从未被调用。你有类似的困难吗? - torngat
好的,我发现我必须覆盖注释内省器,因为我的类没有以任何方式引用此过滤器。然而,这对我提出了另一个问题,我已经在这里发布了[http://stackoverflow.com/questions/29833259/jackson-how-to-add-property-filter-without-overriding-annotation-filters]。 - torngat

12
这将为您提供一个对象映射器,当后端开发人员决定添加新字段时不会崩溃。
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;
      }          

    }
));

3
鉴于 Rest Assured 的使用场景,通常情况下您可能希望修改或提供用于某些请求的 ObjectMapper,而不是所有请求都需要这样做。
您可以通过使用以下方法来实现此目的: 一个经典的用例,就像@jason-henriksen提到的那样是:
  • 允许忽略未知属性
  • 在反序列化期间忽略未标记为@JsonIgnoreReturnedType类中定义的属性,而不会抛出异常(当您无法控制/无法修改该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);

您还可以通过使用Jackson MixIns来配置您的ObjectMapper来实现这一点。

这个方案对我来说完美地解决了问题!在我的情况下,反序列化失败出现在 .as(...) 这里,传入自定义的 objectMapper 是最简单的解决方案,而且不需要到处修改。 - swiftest

2

@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;
            }
    ));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接