在Spring Boot Data Rest中向HATEOAS响应添加更多信息

在Spring Boot Data Rest中向HATEOAS响应添加更多信息

问题描述:

我有以下REST控制器。在Spring Boot Data Rest中向HATEOAS响应添加更多信息

@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<Books> 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(查询,分页);)我回来这些对象。

enter image description here

然而,在我的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); 

} 
+1

由于东西似乎在'content'和'highlight'之间有所不同,您应该向我们展示'Books'的源代码。实际结果的实际片段以及您期望/希望的结果可能会有所帮助。 –

+0

请使变量和字段名称小写。大写名称看起来像Java开发人员的类名。 –

+0

如果你发布你的图书实体类会有所帮助。 –

我用Page<Books>代替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); 
    } 

可能是一个这样做的更好的办法,但我无法找到任何东西,会做什么,我想它,而无需改变一吨的代码做。希望这可以帮助!

+0

谢谢,但那是什么可能不适合我们。谢谢! – Cipous

+0

没问题!对你如何解决问题感到好奇。祝你好运。 –

+0

我已经添加了我的解决方案,也许它会帮助你。 – Cipous

好吧,这里是我是如何做到了: 我写我的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)); 
    } 
} 

我不得不添加到我的春天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" 
      ] 
     } 
     ] 
    } 
    ] 
}