Spring 引导重复端点

Spring Boot Duplicated Endpoints

首先要澄清的是,也许标题不是很具体,但我不知道如何表达更好,因为我不明白我遇到的问题。

一些背景信息: 我有一个安装了 JWT 身份验证和 Swagger 的 Spring 启动应用程序。

我拿来举例的控制器有以下内容

@RestController
@RequestMapping("/api/v1")
@CrossOrigin(origins = "*")
@Api(value = "Operations Dummy")
public class DummyController {

    @Autowired
    IDummyService _IDummyService;

    @ApiOperation(value = "Get All Dummy")
    @GetMapping("/dummy")
    public ResponseEntity<ResultList<DummyDTO>> getAllDummy() {
        return _IDummyService.getAll();
    }

}

像这个控制器还有好几个,都差不多

应用程序的正确功能是调用端点 GET http://localhost:8080/api/v1/dummy

响应将类似于以下内容:

{
  "data": [
    {
      "id": 0,
      "name": "test"
    },
    {
      "id": 1,
      "name": "dummy"
    }
  ],
  "metadata": {
    "count": 0
  }
}

问题是某些端点可以从根访问,如下所示: GET http://localhost:8080/dummy

它们产生不同的响应,但仍显示数据

{
  "_embedded" : {
    "dummy" : [ {
      "id" : "0",
      "name" : "test",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080A/dummy/0"
        }
    },{
      "id" : "1",
      "name" : "dummy",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/dummy/1"
        }
    } ]
  },
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/dummy"
    },
    .
    .
    .
  },
  "page" : {
    "size" : 20,
    "totalElements" : 32,
    "totalPages" : 2,
    "number" : 0
  }
}

有关详细信息,这是配置文件的副本:

@Override
protected void configure(HttpSecurity http) throws Exception {
    
    http.cors().and().csrf().disable().             
    authorizeRequests()
    .antMatchers("/api/v1/users/auth").permitAll()
    .antMatchers("/error",
            "/v2/api-docs",
            "/configuration/ui",
            "/swagger-resources/**",
            "/configuration/**",
            "/swagger-ui.html",
            "/webjars/**").permitAll()
    .antMatchers("/api/v1/**").authenticated()
    .and()
    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

正如我所说,并不是每个控制器都会发生这种情况,事实上,当我意识到这个问题正在发生时,我删除了虚拟控制器并重新编译了项目,仍然可以通过 / 获取信息虚拟而不是通过 /api/v1/dummy

至于日志,当我们调用 /dummy 时会生成以下日志:

o.s.web.servlet.DispatcherServlet        : GET "/dummy", parameters={}
m.m.a.RequestResponseBodyMethodProcessor : Using 'application/hal+json;q=0.8', ...
m.m.a.RequestResponseBodyMethodProcessor : Writing [PagedResource { content: 
o.s.web.servlet.DispatcherServlet        : Completed 200 OK

而对于 /api/v1/dummy 的调用是:

s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.es.controller.DummyController#getAllDummy()
o.s.web.servlet.DispatcherServlet        : GET "/api/v1/dummy", parameters={}
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.es.controller.DummyController#getAllDummy()
o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [com.example.es.util.ResultList@19771362]
o.s.web.servlet.DispatcherServlet        : Completed 200 OK

更新:

我在application.properties文件中添加了下面这行,现在好像是return404,但我不确定这是否会影响操作

spring.data.rest.detection-strategy=annotated

因为您使用的是 spring-data-rest starter 它在幕后做了很多事情。

如-

  • 使用 HAL 作为媒体类型为您的域模型公开可发现的 REST API。

  • 公开代表您的模型的集合、项目和关联资源。

基本上您所有的存储库和集合都公开为 APIs。

默认情况下,Spring Data REST 在根 URI“/”处提供 REST 资源。这就是为什么您能够收到 http://localhost:8080/dummy.

的回复

您可以通过在 application.properties 中设置 spring.data.rest.basePath 获得此根。

因此,如果您将其设置为 spring.data.rest.basePath=/pablo,那么您将不会获得 http://localhost:8080/dummy 的响应数据。相反,您会在 http://localhost:8080/pablo/dummy

上收到回复

一些有用的文档:-

https://docs.spring.io/spring-data/rest/docs/3.3.4.RELEASE/reference/html/#reference