如何强制Spring HATEOAS资源呈现一个空的嵌入式数组?

时间:2015-05-17 12:18:07

标签: spring spring-hateoas

我有以下控制器方法:

@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, value = "session/{id}/exercises")
public ResponseEntity<Resources<Exercise>> exercises(@PathVariable("id") Long id) {

  Optional<Session> opt = sessionRepository.findWithExercises(id);
  Set<Exercise> exercises = Sets.newLinkedHashSet();

  if (opt.isPresent()) {
    exercises.addAll(opt.get().getExercises());
  }

  Link link = entityLinks.linkFor(Session.class)
                         .slash(id)
                         .slash(Constants.Rels.EXERCISES)
                         .withSelfRel();

  return ResponseEntity.ok(new Resources<>(exercises, link));
}

所以基本上我试图为特定的Set<>公开ExerciseSession个实体。当exercise实体为空时,我得到一个像这样的JSON表示:

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/sessions/2/exercises"
        }
    }
}

所以基本上没有嵌入式实体,而以下类似的东西是可取的:

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/sessions/2/exercises"
        }
    }, 
    "_embedded": {
        "exercises": [] 
    }    
}

知道如何强制执行此操作吗?

4 个答案:

答案 0 :(得分:17)

这里的问题是,如果没有额外的努力,就无法找出空集合是Exercise的集合。 Spring HATEOAS有一个帮助类可以解决这个问题:

EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
EmbeddedWrapper wrapper = wrappers.emptyCollectionOf(Exercise.class);
Resources<Object> resources = new Resources<>(Arrays.asList(wrapper));

EmbeddedWrapper允许您明确标记要添加到嵌入的ResourceResources的对象,甚至可能手动定义它们应在其下公开的rel。如上所示,帮助程序还允许您将给定类型的空集合添加到_embedded子句中。

答案 1 :(得分:3)

可以使用PagedResourceAssembler :: toEmptyResource()方法。例如,以下工作:

Page<EWebProduct> products = elasticSearchTemplate.queryForPage(query, EWebProduct.class);

if(!products.hasContent()){
            PagedResources pagedResources = pageAssembler.toEmptyResource(products, WebProductResource.class,baseLink);
            return new ResponseEntity<PagedResources<WebProductResource>>(pagedResources, HttpStatus.OK);
}

我敢打赌它也适用于其他ResourceAssemblers。

答案 2 :(得分:0)

如果您有Page ,则可以这样转换:

 public static <T> PagedModel<EntityModel<T>> toModel(PagedResourcesAssembler<T> assembler,
                                                Page<T> page) {
        if (!page.isEmpty()) {
            return assembler.toModel(page);
        } else {
            // toEmptyModel renders the _embedded field (with an empty array inside)
            return (PagedModel<EntityModel<T>>) assembler.toEmptyModel(page, TenantSubscriptionResponseDto.class);
        }
    }

(只需将其作为参数添加到Controller方法中,就可以获取 PagedResourcesAssembler汇编程序

答案 3 :(得分:-1)

Spring默认使用Jackson解析器序列化/反序列化json。根据{{​​3}}杰克逊有一个名为 WRITE_EMPTY_JSON_ARRAYS 的功能,默认情况下启用它。在您的配置中, WRITE_EMPTY_JSON_ARRAYS 可能设置为false。请重新检查您的消息转换器配置。