消耗Spring Hateoas Pageable

我有一个使用HAteoas的Rest-Service,以前没有分页的工作。 现在我正在制作可分页的Json。 我用Spring-Hateoas的开箱即用function做到了这一点。 但现在我正在坚持消耗它,我想它确实没有很好的记录,如果是的话。

我的JSON如下所示:

{ "_embedded": { "vertragResourceList": [ { "identifier": 728, "auszubildender": "Rumm", "beruf": "Landwirt/in", "betrieb": "Mitterbauer Johann", "betriebsNummer": "e12d0949-67ae-4134-9dc2-fb67758b6b16", "zustaendigeStelle": "Irgendwo", "beginn": 529887600000, "status": "RECENT", "fachrichtung": null, "schwerpunkt": "Grünland oder Ackergras", "ende": 623113200000, "_links": { "self": { "href": "http://localhost:8080/bbsng-app-rest/vertrag/728" } } }, { "identifier": 803, "auszubildender": "Gossen", "beruf": "Landwirt/in", "betrieb": "Beer Johann", "betriebsNummer": "d5a20cb9-7273-4b75-85bd-f8e7d6a843c4", "zustaendigeStelle": "Woanders", "beginn": 278118000000, "status": "RECENT", "fachrichtung": null, "schwerpunkt": "Ackerfutterbau", "ende": 339116400000, "_links": { "self": { "href": "http://localhost:8080/bbsng-app-rest/vertrag/803" } } } ] }, "page": { "size": 2, "totalElements": 1000, "totalPages": 500, "number": 5 } } 

====

但是现在我的列表是“_embedded”,所以我怎样才能以最方便的方式使用它。 我更喜欢Spring-Hateoas或类似的开箱即用的解决方案。

我的代码之前的工作方式如下( Json在!!!之前没有包装在_embedded / vertragResourceList中 )。

 @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public VertragsListe findeAlleVertraege(final Integer firstDataSet, final Integer lastDataSet, final VertragDTFilter vertragsFilter, final VertragDTSorting vertragSorting) { final VertragsListe vertragsListe = new VertragsListe(); final String url = LinkUtils.findeVertrag(firstDataSet, lastDataSet, vertragsFilter, vertragSorting); final ResponseEntity entity = template.getForEntity(url, List.class); if (OK.equals(entity.getStatusCode())) { final List body = entity.getBody(); for (final LinkedHashMap map : body) { vertragsListe.add(getPopulatedVertrag(vertragsListe, map)); } } return vertragsListe; } 

堆栈跟踪:

 org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@e89d61c; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@e89d61c; line: 1, column: 1] 

=====

编辑:

对应的Resourceclass看起来像这样(Serverside和Clientside !!!):

 public class VertragPagedResources extends PagedResources { @SuppressWarnings("unchecked") public VertragPagedResources(final Collection content, final PageMetadata metadata) { super(content, metadata, CollectionUtils.EMPTY_COLLECTION); } public VertragPagedResources() { super(); } } 

在Clientside我现在改变了:

 @Autowired private RestTemplate template; @Override public VertragPagedResources findeAlleVertraege(final Integer firstDataSet, final Integer lastDataSet, final VertragDTFilter vertragsFilter, final VertragDTSorting vertragSorting) { final String url = LinkUtils.findeVertrag(firstDataSet, lastDataSet, vertragsFilter, vertragSorting); final ResponseEntity entity = template.getForEntity(url, VertragPagedResources.class); if (OK.equals(entity.getStatusCode())) { return entity.getBody(); } return new VertragPagedResources(); } 

现在我没有任何例外,但内容是空的。 正确填充的唯一内容是来自可分页的信息(numberOfReturned Datasets,pageSize等)。 内容为空列表!!! 在调试时,我在浏览器中尝试给定的URL,然后JSON看起来像上面提到的那样。

  

VertragResource(客户端和服务器):

 public class VertragResource extends IdentifierResourceSupport { @NotNull private String auszubildender; @NotNull private String beruf; @NotNull private String betrieb; @NotNull private String betriebsNummer; @NotNull private String zustaendigeStelle; @NotNull private Calendar beginn; @NotNull private String status; private String fachrichtung; private String schwerpunkt; private Calendar ende; // GETTER & SETTER .... 

控制器服务器端:

 @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE) public HttpEntity showAll( /* PARAMS */ ) { // FILTER ... final VertragFilter filter = new VertragFilter(); // FILL FILTER // SORTING ... final VertragSorting sorting = new VertragSorting(/* BLA */) // COMPUTE ... final VertragResourceAssembler assembler = new VertragResourceAssembler(); final List alleVertrage = service.findeAlleVertraege(/* BLA */); final List resources = assembler.toResources(alleVertrage); // final long totalElements = service.zaehleAlleVertraege(filter); final long size = Math.min(displayLength, totalElements); final long totalPages = totalElements / size; final PageMetadata pageMetadata = new PageMetadata(displayLength, displayStart, totalElements, totalPages); final VertragPagedResources pagedResources = new VertragPagedResources(resources, pageMetadata); return new HttpEntity(pagedResources, headerTotalNumberOfData()); } 

====

IdentifierResourceSupport:

 public class IdentifierResourceSupport extends ResourceSupport { private Long identifier; public Long getIdentifier() { return identifier; } public void setIdentifier(Long identifier) { this.identifier = identifier; } } 

=====

编辑2:

我现在做了什么,我将Spring-Boot从1.2.1切换回1.1.10。 现在我在尝试相同时遇到exception,似乎Spring-Boot 1.2.1隐藏了exception:

 org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "_embedded" (class at.compax.bbsng.client.mvc.client.resource.VertragPagedResources), not marked as ignorable (3 known properties: "links", "content", "page"]) at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@62532c56; line: 1, column: 15] (through reference chain: at.compax.bbsng.client.mvc.client.resource.VertragPagedResources["_embedded"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_embedded" (class at.compax.bbsng.client.mvc.client.resource.VertragPagedResources), not marked as ignorable (3 known properties: "links", "content", "page"]) at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@62532c56; line: 1, column: 15] (through reference chain: at.compax.bbsng.client.mvc.client.resource.VertragPagedResources["_embedded"]) 

好的,

我现在得到了解决方案。

首先,Spring Boot 1.2.1中有一个BUG。 就像在EDIT2中提到的那样。 Spring-Boot 1.1.10抛出exception,因为它无法映射_embedded中的内容。 这就是为什么我的内容保持空白。 Spring Boot 1.2.1只是让它没有任何提示作为例外。 降级到1.1.10给了我一些暗示。

那么改变的后果是什么:

Serverside上的控制器:

 @RequestMapping(method = GET, produces = "application/hal+json") public HttpEntity showAll( /* PARAMS */ ) { // LIKE CODE IN QUESTION ... return new HttpEntity(pagedResources); } 

====

RestTemplate配置:

然后,您需要配置Resttemplate以处理HAL格式。

 @Bean public RestTemplate restTemplate() { final ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new Jackson2HalModule()); final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); converter.setObjectMapper(mapper); return new RestTemplate(Collections.> singletonList(converter)); } 

客户端代码与第一个问题编辑保持一致!

Interesting Posts