在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(查询,分页);)我回来这些对象。
然而,在我的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);
}
我用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);
}
可能是一个这样做的更好的办法,但我无法找到任何东西,会做什么,我想它,而无需改变一吨的代码做。希望这可以帮助!
好吧,这里是我是如何做到了: 我写我的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"
]
}
]
}
]
}
由于东西似乎在'content'和'highlight'之间有所不同,您应该向我们展示'Books'的源代码。实际结果的实际片段以及您期望/希望的结果可能会有所帮助。 –
请使变量和字段名称小写。大写名称看起来像Java开发人员的类名。 –
如果你发布你的图书实体类会有所帮助。 –