我可以提供一个与 spring-data-rest GET 并行的端点吗? [英] Can i offer an endpoint in parallel to a spring-data-rest GET?

查看:52
本文介绍了我可以提供一个与 spring-data-rest GET 并行的端点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目正在从自定义 json 格式转向 json-hal 和 spring-data-rest.为了继续支持旧"json,我想运行现有的 Resource-Controller 与提供的新 Spring-Data-Rest 并行.

my project is moving away from a custom json format to json-hal and spring-data-rest. to continue the support for the "old" json i want to run the existing Resource-Controller parallel to the new Spring-Data-Rest provided one.

每当我将 spring-data-rest 配置为使用与我们现有控制器相同的 url 时,仅使用旧控制器,如果 accept-header 不匹配,我会收到错误响应.当我使用不同的网址时,一切正常

Whenever i configure spring-data-rest to use the same url as our existing controller ONLY the old controller is used and if the accept-header does not match i get an error response. when i use a different url, everything works

是否可以与 spring-data-rest 并行运行控制器并根据 Accept-Header 进行响应?

Is it possible to run a controller in parallel to the spring-data-rest one and respond based on the Accept-Header?

旧控制器:

@RepositoryRestController
@RequestMapping(value = "/api/accounts", produces = {"application/custom.account+json"})
public class AccountResource {

    @RequestMapping(method = RequestMethod.GET)
    @PreAuthorize("#oauth2.hasScope('read') and hasRole('ROLE_ADMIN')")
    public ResponseEntity<List<Account>> getAll(
        @RequestParam(value = "page", required = false) Integer offset,
        @RequestParam(value = "per_page", required = false) Integer limit,
        @RequestParam(value = "email", required = false) String email
    ) throws URISyntaxException {
        ...
    }
}

推荐答案

@RepositoryRestController类型级别.第一步,通过从 RequestMapping 中删除 produces 参数(我在这里使用 GetMapping 快捷方式),确保您确实设法捕获了请求.我还删除了 @PreAuthorize 注释,因为它现在不相关,并引入了一个参数来捕获 Accept 标头值(用于调试):

@RepositoryRestController does not play well with @RequestMapping at the type level. First step, make sure you actually manage to catch the request, by removing the produces parameter from the RequestMapping (I use the GetMapping shortcut here). I also removed the @PreAuthorize annotation for it's not relevant for now, and introduced a parameter to catch the Accept header value (for debug):

@RepositoryRestController
public class AccountResource {

    @GetMapping(value = "/api/accounts")
    public ResponseEntity<List<Account>> getAll(
        @RequestParam(value = "page", required = false) Integer offset,
        @RequestParam(value = "per_page", required = false) Integer limit,
        @RequestParam(value = "email", required = false) String email,
    ) throws URISyntaxException {
        ...
    }

}

有了这个,您应该能够随意自定义 GET/api/accounts 并且仍然受益于 POST/PUT/PATCH.../api/accounts由 Spring Data Rest 自动提供,并断言 content-type

With this, you should be able to customize the GET /api/accounts at will and still benefit from POST/PUT/PATCH... /api/accounts provided automagically by Spring Data Rest, and also assert that content-type

如果它按预期工作,那么您可以:

If it works as expected, you can then:

  • 尝试在 GetMapping 注释中使用 produces = "application/custom.account+json"(单个值不需要大括号)缩小方法范围,并查看您的端点和Spring 生成的端点方法可用
  • 恢复您的@PreAuthorize 注释
  • 去掉@RequestHeader 参数
  • try to narrow the method scope with produces = "application/custom.account+json" (no braces required for a single value) in the GetMapping annotation, and see that both your endpoint and the Spring generated endpoint method are avaiable
  • reinstate your @PreAuthorize annotation
  • get rid of the @RequestHeader parameter

这给了你:

@RepositoryRestController  // NO MAPPING AT THE TYPE LEVEL
public class AccountResource {

    @GetMapping(value = "/api/accounts", // Mapping AT THE METHOD LEVEL
                produces = "application/custom.account+json") // the content-type this method answers to
    @PreAuthorize("#oauth2.hasScope('read') and hasRole('ADMIN')")  // ROLE is 'ADMIN' not 'ROLE_ADMIN'
    public ResponseEntity<List<Account>> getAll(
        @RequestHeader("Content-Type") String contentType,
        @RequestParam(value = "page", required = false) Integer offset,
        @RequestParam(value = "per_page", required = false) Integer limit,
        @RequestParam(value = "email", required = false) String email,
    ) throws URISyntaxException {
        ...
    }

}

现在:

  • curl host:port/api/accounts 将命中 Spring 控制器端点
  • curl host:port/api/accounts -H "Accept: application/custom.account+json" 将命中您的自定义控制器端点.
  • curl host:port/api/accounts will hit the Spring controller endpoint
  • curl host:port/api/accounts -H "Accept: application/custom.account+json" will hit your custom controller endpoint.

这篇关于我可以提供一个与 spring-data-rest GET 并行的端点吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆