Spring REST响应在自定义控制器

时间:2016-12-01 23:49:37

标签: java spring spring-data spring-data-rest spring-rest

我有几个控制器会自动创建REST个端点。

@RepositoryRestResource(collectionResourceRel = "books", path = "books")
public interface BooksRepository extends CrudRepository<Books, Integer> {
    public Page<Books> findTopByNameOrderByFilenameDesc(String name);
}

当我访问时:http://localhost:8080/Books

我回来了:

{
    "_embedded": {
        "Books": [{
            "id": ,
            "filename": "Test123",
            "name": "test123",
            "_links": {
                "self": {
                    "href": "http://localhost:8080/books/123"
                },
                "Books": {
                    "href": "http://localhost:8080/books/123"
                }
            }
        }]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/books"
        },
        "profile": {
            "href": "http://localhost:8080/profile/books"
        },
        "search": {
            "href": "http://localhost:8080/books/search"
        },
        "page": {
            "size": 20,
            "totalElements": 81,
            "totalPages": 5,
            "number": 0
        }
    }
}

当我创建自己的控制器时:

@Controller
@RequestMapping(value = "/CustomBooks")
public class CustomBooksController {
    @Autowired
    public CustomBookService customBookService;

    @RequestMapping("/search")
    @ResponseBody
    public Page<Book> search(@RequestParam(value = "q", required = false) String query,
                                 @PageableDefault(page = 0, size = 20) Pageable pageable) {
        return customBookService.findAll();
    }
}

我会得到一个看起来与自动生成的控制器响应完全不同的响应:

{
    "content": [{
        "filename": "Test123",
        "name" : "test123"
    }],
    "totalPages": 5,
    "totalElements": 81,
    "size": 20,
    "number": 0,
}

我需要做些什么才能使我的回复看起来像自动生成的响应?我希望保持一致,所以我不必为不同的响应重写代码。我应该采用不同的方式吗?

<小时/> 修改:发现此信息:Enable HAL serialization in Spring Boot for custom controller method

但我不明白我需要在REST控制器中更改以启用:PersistentEntityResourceAssembler。我在谷歌上搜索了PersistentEntityResourceAssembler,但它一直让我回到类似的页面而没有太多的例子(或者这个例子似乎对我不起作用)。

1 个答案:

答案 0 :(得分:5)

正如@chrylis所建议的那样,你应该用@Controller替换@RepositoryRestController注释,以便spring-data-rest调用它的ResourceProcessors来自定义给定的资源。

对于您遵循HATEOAS规范的资源(如spring-data-rest BooksRepository),您的方法声明返回类型应该类似于HttpEntity<PagedResources<Resource<Books>>> 将Page对象转换为PagedResources:

  • 您需要自动装配此对象。

    @Autowired private PagedResourcesAssembler<Books> bookAssembler;

  • 您的退货声明应该是

    return new ResponseEntity<>(bookAssembler.toResource(customBookService.findAll()), HttpStatus.OK);

这些更改可帮助您获取包含"_embedded""_links&#34;的org.springframework.hateoas.Resources兼容响应。属性。