Spring的MockMVC响应不匹配浏览器响应

时间:2015-10-14 13:42:29

标签: java spring spring-mvc spring-hateoas

出于某种原因,如果我通过浏览器或通过我的MockMVC测试类访问它,我的Spring控制器会返回不同的响应。 有人可以帮助我找出原因吗?

首先是控制器方法:

@RequestMapping(value = APPLICATIONS_ROOT, method = GET)
  public HttpEntity<ApplicationsListResource> listApplications(@PageableDefault(page = DEFAULT_START,
      size = DEFAULT_HITS_PER_PAGE) Pageable pageable) {
    Page<Application> applications = applicationRepository.findAll(pageable);
    ApplicationsListResource applicationListResource = new ApplicationsListResource(applications, pageable);
    return new ResponseEntity<ApplicationsListResource>(applicationListResource, HttpStatus.OK);
  }

显然那里有一些未知的类。 ApplicationListResource扩展了ResourceSupport,其中包含ApplicationResource名为applications的列表。此ApplicationResource也扩展了ResourceSupport

当我通过浏览器访问代码时,我会得到以下内容:

{
  "_links": {
    "self": {
      "href": "http://localhost:10000/applications{?page,size,sort}",
      "templated": true
    }
  },
  "_embedded": {
    "applications": [{
      "displayname": "One",
      "description": "My Test Application!",
      "locations": ["http://foo.com"],
      "_links": {
        "self": { "href": "http://localhost:10000/applications/one" }
      }
    }, {
      ...
    }]
  },
  "page": {
    "size": 20,
    "totalElements": 7,
    "totalPages": 1,
    "number": 0
  }
}

看起来HATEOAS符合我的要求。但是当我通过MockMVC请求时......

getMockMvc().perform(get(APPLICATIONS_ROOT)).andExpect(status().isOk()).andExpect(content().contentType(MediaTypes.HAL_JSON)).andExpect(jsonPath("$._embedded.applcations", hasSize(5))).andReturn();

响应中没有符合HATEOAS标准的元素,因此我的测试在jsonPath检查上失败:

{
  "page" : 0,
  "size" : 10,
  "sort" : null,
  "total" : 5,
  "applications" : [ {
    "name" : "one",
    "version" : "1.0",
    ...

我尝试在MockMVC方法的GET请求中更改ContentType,但它没有任何区别。在浏览器中,我没有设置任何特定的内容类型,标题等。

我知道MockMVC类使得HTTP请求与通常的RestTemplate存在某些差异,所以可能是这样的吗?任何人都可以看到我遗失的任何明显事物吗?

如果需要,我会添加额外的代码,但这会让问题比现在更加冗长。

1 个答案:

答案 0 :(得分:1)

Spring HATEOAS添加了正确渲染hal的其他配置,请查看详细信息:http://docs.spring.io/spring-hateoas/docs/0.19.0.RELEASE/reference/html/#configuration

简而言之,它将MixInJackson2HalModule添加的HalHandlerInstantiator添加到ObjectMapper。它全部都在HypermediaSupportBeanDefinitionRegistrar.javahttps://github.com/spring-projects/spring-hateoas/blob/master/src/main/java/org/springframework/hateoas/config/HypermediaSupportBeanDefinitionRegistrar.java

中配置

如果您使用的是独立的mockMvc配置,则必须手动配置ObjectMapper以模仿spring的行为。我遇到了同样的问题,最后在我的测试中添加了以下配置:

mockMvc = MockMvcBuilders.standaloneSetup(controller)
        .setMessageConverters(
                new MappingJackson2HttpMessageConverter(configureObjectMapper()))
        .build();

private ObjectMapper configureObjectMapper() {
    return Jackson2ObjectMapperBuilder.json()
        .modules(new Jackson2HalModule())
        .handlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(
            new DelegatingRelProvider(
                OrderAwarePluginRegistry.create(Arrays.asList(
                    new EvoInflectorRelProvider(),
                    new AnnotationRelProvider()))),
            null))
        .build();
}