Как заставить ресурсы 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<> of Exercise объекты для конкретного Session. Когда сущность упражнений пуста, однако я получаю представление JSON следующим образом:

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

таким образом, в основном нет встроенной сущности, в то время как что-то вроде следующего было бы предпочтительным:

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

есть идеи, как обеспечить это?

3 ответов


проблема здесь в том, что без дополнительных усилий нет способа узнать, что пустая коллекция является коллекцией для Exercise. Spring HATEOAS имеет вспомогательный класс для работы с этим:

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

An EmbeddedWrapper позволяет явно пометить объекты, которые будут добавлены в Resource или Resources как встроенный, потенциально даже вручную определяющий rel, они должны быть выставлены под. Как вы можете видеть выше, помощник также позволяет добавить пустую коллекцию данного введите _embedded предложения.


можно использовать метод 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.


Spring по умолчанию использует парсер Jackson для сериализации / десериализации json. Согласноhttp://wiki.fasterxml.com/JacksonFeaturesSerialization Джексон имеет функцию под названием WRITE_EMPTY_JSON_ARRAYS и включена по умолчанию. Может быть!--4-->WRITE_EMPTY_JSON_ARRAYS установлено значение false в свой конфиг. пожалуйста, проверьте конфигурацию конвертеров сообщений.