Дублированные конечные точки Spring Boot

#java #spring #spring-boot #request-mapping

#java #весна #весенняя загрузка #сопоставление запросов

Вопрос:

Первое, что нужно уточнить, это то, что, возможно, название не очень конкретное, но я не знаю, как выразить это лучше, потому что я не понимаю, в чем моя проблема.

Немного контекста: у меня установлено приложение Spring Boot с аутентификацией JWT и Swagger.

Контроллер, который я использую в качестве примера, имеет следующее содержимое.

 @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);
}
  

Как я уже сказал, не с каждым контроллером это происходит, на самом деле, когда я понял, что возникает эта проблема, я удалил фиктивный контроллер и снова скомпилировал проект, и все еще можно было получить информацию через /dummy, а не через /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, и кажется, что теперь он возвращает 404, но я не уверен, может ли это повлиять на работу

 spring.data.rest.detection-strategy=annotated
  

Комментарии:

1. Используете ли вы Spring Data Rest ?

2. Да, @wak786, я использую его

Ответ №1:

Поскольку вы используете spring-data-rest starter его, он многое делает за кулисами.

Например —

  • Предоставляет доступный для обнаружения REST API для вашей модели домена, используя HAL в качестве типа носителя.

  • Предоставляет ресурсы коллекции, элемента и ассоциации, представляющие вашу модель.

В основном все ваши репозитории и коллекции отображаются как API.

По умолчанию Spring Data REST обслуживает ресурсы REST в корневом URI, ‘/’. Вот почему вы можете получить ответ на http://localhost:8080/dummy .

Вы можете использовать этот root, установив spring.data.rest.basePath в application.properties.

Поэтому, если вы установите для этого 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