使用RestTemplate进行Spring MVC测试:通用集合失败(即使使用ParameterizedTypeReference)

时间:2016-09-07 17:17:29

标签: spring spring-mvc spring-test-mvc

我正在使用Spring Framework 4.3.1

我有以下域类

@XmlRootElement(name="persona")
@XmlType(propOrder = {"id","nombre","apellido","fecha"})
public class Persona implements Serializable {

    @XmlElement(name="id")
    @JsonProperty("id")
    public String getId() {
        return id;
    }

    ....

每个getter都有@XmlElement@JsonProperty注释。 我正在使用JAXB2Jackson2

我也有以下内容:

@XmlRootElement(name="collection")
public class GenericCollection<T> {

    private Collection<T> collection;

    public GenericCollection(){

    }

    public GenericCollection(Collection<T> collection){
        this.collection = collection;
    }

    @XmlElement(name="item")
    @JsonProperty("collection")
    public Collection<T> getCollection() {
        return collection;
    }

    public void setCollection(Collection<T> collection) {
        this.collection = collection;
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      for(Object object : collection){
        builder.append("[");
        builder.append(object.toString());
        builder.append("]");
      }
      return builder.toString();
    }

}

关于测试,通过@Test工作的许多Spring MVC Test方法都可以正常工作。 @Controller@RestController的工作方式如何。

注意:我可以测试CRUD方案,它可以测试HTTP methods,例如POSTPUTGET和{{1 }}。因此,我能够获得一个实体和一组实体。

注意:从上一条记录开始,所有工作均采用DELETEXML格式。

现在尝试通过JSON测试一种程序化客户端, 无法进行集合测试。有以下内容:

RestTemplate

我可以确认@Before public void setUp(){ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc)); List<HttpMessageConverter<?>> converters = new ArrayList<>(); converters.add(httpMessageConverterConfig.marshallingMessageConverter()); converters.add(httpMessageConverterConfig.mappingJackson2HttpMessageConverter()); restTemplate.setMessageConverters(converters); System.out.println("converters.size():" + converters.size()); } 始终打印converters.size()

以下是XML和JSON

2

注意:观察我在两种情况下使用@Test public void findAllXmlTest(){ RequestEntity<Void> requestEntity = RestControllerSupport_.createRequestEntityForGet(uri, retrieveURI); ParameterizedTypeReference<GenericCollection<Persona>> parameterizedTypeReference = new ParameterizedTypeReference<GenericCollection<Persona>>(){}; ResponseEntity<GenericCollection<Persona>> responseEntity = restTemplate.exchange(requestEntity, parameterizedTypeReference); assertThat(responseEntity, notNullValue()); assertThat(responseEntity.getStatusCode(), is(HttpStatus.OK)); assertThat(responseEntity.getHeaders().getContentType(), is(MediaType.APPLICATION_XML) ); assertThat(responseEntity.getBody(), notNullValue()); assertThat(responseEntity.getBody().getClass(), is(GenericCollection.class)); assertThat(responseEntity.getBody().getCollection(), is(personas)); } @Test public void findAllJsonTest(){ RequestEntity<Void> requestEntity = RestControllerSupport_.createRequestEntityForGet(uri, retrieveURI); ParameterizedTypeReference<GenericCollection<Persona>> parameterizedTypeReference = new ParameterizedTypeReference<GenericCollection<Persona>>(){}; ResponseEntity<GenericCollection<Persona>> responseEntity = restTemplate.exchange(requestEntity, parameterizedTypeReference); assertThat(responseEntity, notNullValue()); assertThat(responseEntity.getStatusCode(), is(HttpStatus.OK)); assertThat(responseEntity.getHeaders().getContentType(), is(MediaType.APPLICATION_JSON_UTF8) ); assertThat(responseEntity.getBody(), notNullValue()); assertThat(responseEntity.getBody().getClass(), is(GenericCollection.class)); assertThat(responseEntity.getBody().getCollection(), is(personas)); }

对于JSON,它可以工作。

但对于XML,我得到:

ParameterizedTypeReference

有什么问题或缺失?

1 个答案:

答案 0 :(得分:1)

您使用的问题MarshallingHttpMessageConverter不是GenericHttpMessageConverter,就像ParameterizedTypeReference中的HttpMessageConverterExtractor所期望的那样:

if (messageConverter instanceof GenericHttpMessageConverter) {
                GenericHttpMessageConverter<?> genericMessageConverter =
                        (GenericHttpMessageConverter<?>) messageConverter;
                if (genericMessageConverter.canRead(this.responseType, null, contentType)) {

MappingJackson2HttpMessageConverter就是那个。

所以,我建议你试试Jaxb2CollectionHttpMessageConverter