web-dev-qa-db-ja.com

RestTemplateが応答表現をPagedResourcesにバインドしないのはなぜですか?

エンティティを(ページングされた)RESTリソースとして公開するために、spring-data-restを使用しています。すべてが正常に動作しますが、RestTemplateを介してデータを要求すると、役に立たないHATEOAS JSON(要求しなかった)が表示されます。 JSONはPagedResourcesのようです。私はそれで生活することができましたが、JSONはオブジェクトに正しく変換されません。内部にはcontentはありません。

リポジトリ:

@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long>
{
    List<Person> findByLastName(@Param("name") String name);
}

クライアント:

public List<Person> getPersons()
{
    RestTemplate rt = new RestTemplate();
    System.out.println(rt.getForObject(URL, PagedResources.class).getContent().size());
    System.out.println(rt.getForObject(URL, PagedResources.class).getLinks().size());
    System.out.println(rt.getForObject(URL, PagedResources.class).getMetadata().getTotalElements());
    return new ArrayList<Person>(rt.getForObject(URL, PagedResources.class).getContent()); // <-- empty
}

System.out:

0 // getContent().size()
4 // getLinks().size()
2 // getTotalElements()

カール:

C:\...>curl http://localhost:8080/spring-jsf-rest/rest/people
{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/spring-jsf-rest/rest/people{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "http://localhost:8080/spring-jsf-rest/rest/people/search"
    }
  },
  "_embedded" : {
    "people" : [ {
      "firstName" : "John",
      "lastName" : "Rambo",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/spring-jsf-rest/rest/people/1"
        }
      }
    }, {
      "firstName" : "Chuck",
      "lastName" : "Norris",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/spring-jsf-rest/rest/people/2"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

どうやら _embeddedはコンテンツに正しくマッピングされていませんか?!

37
user3563584

正しく検出したように、PagedResourcesには_embeddedプロパティがありません。そのため、contentプロパティが入力されません。

このジレンマは2つの異なる方法で解決できます。

  1. そもそも表現と一致する型を提供する。したがって、カスタムクラスを作成し、表現のプロパティ名に固執するか、Jacksonアノテーションなどを使用してカスタマイズします。

  2. カスタムMappingJackson2HttpMessageConverterをセットアップし、ObjectMapperをカスタマイズして、Spring HATEOASがそのまま出荷するJackson2HalModuleを構成します。

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.registerModule(new Jackson2HalModule());
    
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
    converter.setObjectMapper(mapper);
    
    RestTemplate template = new RestTemplate(Collections.<HttpMessageConverter<?>> singletonList(converter));
    
54
Oliver Drotbohm