调用 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"));
    }
}