调用 spring 数据存储库方法不会 return 链接
Calling spring data rest repository method doesn't return links
我有存储库 "ClientRepository":
public interface ClientRepository extends PagingAndSortingRepository<Client, Long> {
}
当我请求 http://localhost:8080/clients/1 然后服务器响应
{
"algorithmId" : 1,
"lastNameTxt" : "***",
"firstNameTxt" : "**",
"middleNameTxt" : "**",
"_links" : {
"self" : {
"href" : "http://localhost:8080/clients/1121495168"
},
"client" : {
"href" : "http://localhost:8080/clients/1121495168"
}
}
}
响应包含预期的链接。
当我在另一个控制器中调用存储库继承方法 findOne 时
@RestController
public class SearchRestController {
@Autowired
public SearchRestController(ClientRepository clientRepository) {
this.clientRepository = clientRepository;
}
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
return clientRepository.findOne(Long.parseLong(query));
}
}
它响应
{
"algorithmId" : 1,
"lastNameTxt" : "***",
"firstNameTxt" : "**",
"middleNameTxt" : "**"
}
为什么在第二种情况下响应不包含链接?如何使 Spring 将它们添加到响应中?
HATEOAS 功能开箱即用,仅适用于使用 @RepositoryRestResource
注释的 Spring 数据 jpa 存储库。这会自动公开其余端点并添加链接。
当您在控制器中使用存储库时,您只需获取对象,jackson 映射器将其映射到 json。
如果您想在使用 Spring MVC 控制器时添加链接,请查看 here
Why doesn't response contain links in the second case?
因为Spring return你告诉它的是return:客户。
What to do to make Spring add them to response?
在您的控制器方法中,您必须构建 Resource 和 return 它。
根据您的代码,以下应该可以满足您的需求:
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
Client client = clientRepository.findOne(Long.parseLong(query));
BasicLinkBuilder builder = BasicLinkBuilder.linkToCurrentMapping()
.slash("clients")
.slash(client.getId());
return new Resource<>(client,
builder.withSelfRel(),
builder.withRel("client"));
}
在此基础上,我还建议您:
- 使用 /clients/search 而不是 /search 因为您搜索 client(对于 RESTful 服务更有意义)
- 使用 RepositoryRestController,原因已给出 here
那应该给你这样的东西:
@RepositoryRestController
@RequestMapping("/clients")
@ResponseBody
public class SearchRestController {
@Autowired
private ClientRepository clientRepository;
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
Client client = clientRepository.findOne(Long.parseLong(query));
ControllerLinkBuilder builder = linkTo(SearchRestController.class).slash(client.getId());
return new Resource<>(client,
builder.withSelfRel(),
builder.withRel("client"));
}
}
我有存储库 "ClientRepository":
public interface ClientRepository extends PagingAndSortingRepository<Client, Long> {
}
当我请求 http://localhost:8080/clients/1 然后服务器响应
{
"algorithmId" : 1,
"lastNameTxt" : "***",
"firstNameTxt" : "**",
"middleNameTxt" : "**",
"_links" : {
"self" : {
"href" : "http://localhost:8080/clients/1121495168"
},
"client" : {
"href" : "http://localhost:8080/clients/1121495168"
}
}
}
响应包含预期的链接。
当我在另一个控制器中调用存储库继承方法 findOne 时
@RestController
public class SearchRestController {
@Autowired
public SearchRestController(ClientRepository clientRepository) {
this.clientRepository = clientRepository;
}
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
return clientRepository.findOne(Long.parseLong(query));
}
}
它响应
{
"algorithmId" : 1,
"lastNameTxt" : "***",
"firstNameTxt" : "**",
"middleNameTxt" : "**"
}
为什么在第二种情况下响应不包含链接?如何使 Spring 将它们添加到响应中?
HATEOAS 功能开箱即用,仅适用于使用 @RepositoryRestResource
注释的 Spring 数据 jpa 存储库。这会自动公开其余端点并添加链接。
当您在控制器中使用存储库时,您只需获取对象,jackson 映射器将其映射到 json。
如果您想在使用 Spring MVC 控制器时添加链接,请查看 here
Why doesn't response contain links in the second case?
因为Spring return你告诉它的是return:客户。
What to do to make Spring add them to response?
在您的控制器方法中,您必须构建 Resource
根据您的代码,以下应该可以满足您的需求:
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
Client client = clientRepository.findOne(Long.parseLong(query));
BasicLinkBuilder builder = BasicLinkBuilder.linkToCurrentMapping()
.slash("clients")
.slash(client.getId());
return new Resource<>(client,
builder.withSelfRel(),
builder.withRel("client"));
}
在此基础上,我还建议您:
- 使用 /clients/search 而不是 /search 因为您搜索 client(对于 RESTful 服务更有意义)
- 使用 RepositoryRestController,原因已给出 here
那应该给你这样的东西:
@RepositoryRestController
@RequestMapping("/clients")
@ResponseBody
public class SearchRestController {
@Autowired
private ClientRepository clientRepository;
@RequestMapping(value = "/search", method = RequestMethod.GET)
Client readAgreement(@RequestParam(value = "query") String query,
@RequestParam(value = "category") String category) {
Client client = clientRepository.findOne(Long.parseLong(query));
ControllerLinkBuilder builder = linkTo(SearchRestController.class).slash(client.getId());
return new Resource<>(client,
builder.withSelfRel(),
builder.withRel("client"));
}
}