【问题标题】:Adding more information to the HATEOAS response in Spring Boot Data Rest在 Spring Boot Data Rest 中向 HATEOAS 响应添加更多信息
【发布时间】:2017-04-17 23:31:32
【问题描述】:

我有以下 REST 控制器。

@RepositoryRestController
@RequestMapping(value = "/booksCustom")
public class BooksController extends ResourceSupport {

    @Autowired
    public BooksService booksService;

    @Autowired
    private PagedResourcesAssembler<Books> booksAssembler;

    @RequestMapping("/search")
    public HttpEntity<PagedResources<Resource<Books>>> search(@RequestParam(value = "q", required = false) String query, @PageableDefault(page = 0, size = 20) Pageable pageable) {
        pageable = new PageRequest(0, 20);

        Page<Books> booksResult = BooksService.findBookText(query, pageable);

        return new ResponseEntity<PagedResources<Resource<Books>>>(BooksAssembler.toResource(BooksResult), HttpStatus.OK);

    }

我的Page&lt;Books&gt; BooksResult = BooksService.findBookText(query, pageable); 得到SolrCrudRepository 的支持。当它运行时BookResult 有几个字段,内容字段和其他几个字段,一个是highlighted。不幸的是,我从 REST 响应中得到的唯一信息是 content 字段中的数据和 HATEOAS 响应中的元数据信息(例如页面信息、链接等)。将highlighted 字段添加到响应中的正确方法是什么?我假设我需要修改ResponseEntity,但不确定正确的方法。

编辑

型号:

@SolrDocument(solrCoreName = "Books_Core")
public class Books {
    @Field
    private String id;

    @Field
    private String filename;

    @Field("full_text")
    private String fullText;

    //Getters and setters omitted 
    ...
}

当搜索和调用 SolrRepository 时(例如 BooksService.findBookText(query, pageable);)我会取回这些对象。

但是,在我的 REST 响应中,我只看到“内容”。我希望能够将“突出显示”对象添加到 REST 响应中。看起来 HATEOAS 只发送“内容”对象中的信息(对象见下文)。

{
  "_embedded" : {
    "solrBooks" : [ {
      "filename" : "ABookName",
      "fullText" : "ABook Text"
    } ]
  },
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/booksCustom/search?q=ABook&page=0&size=20"
    },
    "self" : {
      "href" : "http://localhost:8080/booksCustom/search?q=ABook"
    },
    "next" : {
      "href" : "http://localhost:8080/booksCustom/search?q=ABook&page=0&size=20"
    },
    "last" : {
      "href" : "http://localhost:8080/booksCustom/search?q=ABook&page=0&size=20"
    }
  },
  "page" : {
    "size" : 1,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

只是为了让您能够全面了解,这是支持 BooksService 的存储库。该服务所做的只是调用此 SolrCrudRepository 方法。

public interface SolrBooksRepository extends SolrCrudRepository<Books, String> {

    @Highlight(prefix = "<highlight>", postfix = "</highlight>", fragsize = 20, snipplets = 3)
    HighlightPage<SolrTestDocuments> findBookText(@Param("fullText") String fullText, Pageable pageable);

}

【问题讨论】:

  • 由于contenthighlighted 之间似乎有些不同,您应该向我们展示Books 的源代码。实际结果的实际 sn-p 和您期望/想要的结果可能会有所帮助。
  • 请将变量名和字段名设为小写。大写名称对于 Java 开发人员来说就像类名。
  • 如果您发布您的 Books 实体类会有所帮助。
  • @JensSchauder。谢谢。我添加了您建议的信息和一些我认为会有所帮助的其他项目。
  • 你是怎么解决这个问题的?

标签: spring rest spring-data spring-data-rest spring-hateoas


【解决方案1】:

好的,我是这样做的: 我写了我的 HighlightPagedResources

public class HighlightPagedResources<R,T> extends PagedResources<R> {

    private List<HighlightEntry<T>> phrases;

    public HighlightPagedResources(Collection<R> content, PageMetadata metadata, List<HighlightEntry<T>> highlightPhrases, Link... links) {
        super(content, metadata, links);
        this.phrases = highlightPhrases;
    }

    @JsonProperty("highlighting")
    public List<HighlightEntry<T>> getHighlightedPhrases() {
        return phrases;
    }
}

和 HighlightPagedResourcesAssembler:

public class HighlightPagedResourcesAssembler<T> extends PagedResourcesAssembler<T> {

    public HighlightPagedResourcesAssembler(HateoasPageableHandlerMethodArgumentResolver resolver, UriComponents baseUri) {
        super(resolver, baseUri);
    }


    public <R extends ResourceSupport> HighlightPagedResources<R,T> toResource(HighlightPage<T> page, ResourceAssembler<T, R> assembler) {
        final PagedResources<R> rs = super.toResource(page, assembler);
        final Link[] links = new Link[rs.getLinks().size()];
        return new HighlightPagedResources<R, T>(rs.getContent(), rs.getMetadata(), page.getHighlighted(), rs.getLinks().toArray(links));
    }
}

我必须添加到我的 spring RepositoryRestMvcConfiguration.java:

@Primary
@Bean
public HighlightPagedResourcesAssembler solrPagedResourcesAssembler() {
    return new HighlightPagedResourcesAssembler<Object>(pageableResolver(), null);
}

在 cotroller 中,我必须将 PagedResourcesAssembler 更改为新实现的一个,并在请求方法中使用新的 HighlightPagedResources:

@Autowired
private HighlightPagedResourcesAssembler<Object> highlightPagedResourcesAssembler;

@RequestMapping(value = "/conversations/search", method = POST)

public HighlightPagedResources<PersistentEntityResource, Object> findAll(
        @RequestBody ConversationSearch search,
        @SortDefault(sort = FIELD_LATEST_SEGMENT_START_DATE_TIME, direction = DESC) Pageable pageable,
        PersistentEntityResourceAssembler assembler) {

    HighlightPage page = conversationRepository.findByConversationSearch(search, pageable);
    return highlightPagedResourcesAssembler.toResource(page, assembler);
}

结果:

  {
  "_embedded": {
    "conversations": [
    ..our stuff..
    ]
  },
  "_links": {
    ...as you know them...
  },
  "page": {
    "size": 1,
    "totalElements": 25,
    "totalPages": 25,
    "number": 0
  },
  "highlighting": [
    {
      "entity": {
        "conversationId": "a2127d01-747e-4312-b230-01c63dacac5a",
        ...
      },
      "highlights": [
        {
          "field": {
            "name": "textBody"
          },
          "snipplets": [
            "Additional XXX License for YYY Servers DCL-2016-PO0422 \n   \n<em>hi</em> bodgan  \n    \nwe urgently need the",
            "Additional XXX License for YYY Servers DCL-2016-PO0422\n \n<em>hi</em> bodgan\n \nwe urgently need the permanent"
          ]
        }
      ]
    }
  ]
}

【讨论】:

    【解决方案2】:

    我使用Page&lt;Books&gt; 而不是HighlightPage 来创建响应页面。页面显然不包含导致突出显示部分被截断的content。我最终基于 HighlightPage 创建了一个新页面,并将其作为我的结果而不是 Page 返回。

    @RepositoryRestController
    @RequestMapping(value = "/booksCustom")
    public class BooksController extends ResourceSupport {
    
        @Autowired
        public BooksService booksService;
    
        @Autowired
        private PagedResourcesAssembler<Books> booksAssembler;
    
        @RequestMapping("/search")
        public HttpEntity<PagedResources<Resource<HighlightPage>>> search(@RequestParam(value = "q", required = false) String query, @PageableDefault(page = 0, size = 20) Pageable pageable) {
    
            HighlightPage solrBookResult = booksService.findBookText(query, pageable);
            Page<Books> highlightedPages = new PageImpl(solrBookResult.getHighlighted(), pageable, solrBookResult.getTotalElements());
            return new ResponseEntity<PagedResources<Resource<HighlightPage>>>(booksAssembler.toResource(highlightedPages), HttpStatus.OK); 
        }
    

    这可能是一种更好的方法,但我找不到任何可以在不更改大量代码的情况下做我想做的事情。希望这会有所帮助!

    【讨论】:

    • 谢谢,但这可能不适合我们。谢谢!
    • 没问题!很好奇你是如何解决这个问题的。祝你好运。
    • 我已经添加了我的解决方案,也许它会对你有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-10-31
    • 2014-03-07
    • 2018-11-26
    • 2017-12-05
    • 2014-08-16
    • 2016-05-23
    • 2014-07-05
    • 2018-07-23
    相关资源
    最近更新 更多