Как передать Pageable в Feign Client в запросе POST с дополнительным @RequestBody

Я попытался создать имитацию клиента для своего контроллера службы REST в Spring.

@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestBody MeasureDto example, Pageable pageable) {
    ...
}

Клиент выглядит так:

@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestHeader("apiKey") String apiKey, @RequestBody MeasureDto example, Pageable pageable);

При запуске теста возникает следующее исключение:

Вызвано: java.lang.IllegalStateException: у метода слишком много параметров тела: public abstract org.springframework.data.domain.Page com.foo.bar.jobservice.client.MeasureServiceClient.searchMeasures (java.lang.String, com.example .foo.jobservice.client.dto.MeasureDto, org.springframework.data.domain.Pageable)

Что я уже знаю / пробовал:

На github есть закрытая проблема: https://github.com/spring-cloud/spring-cloud-netflix/issues/556

Проблема с фиксацией, которая должна была решить проблему:

https://github.com/spring-cloud/spring-cloud-openfeign/issues/26

Коммит:

https://github.com/spring-cloud/spring-cloud-openfeign/commit/6e0e63644ba34193f03c2cd74391cac73b9bfdb4

Что я настроил:

import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.support.PageJacksonModule;
import org.springframework.cloud.openfeign.support.PageableSpringEncoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@EnableFeignClients
@Configuration
public class FeignConfig {

    @Bean
    public PageJacksonModule pageJacksonModule() {
        return new PageJacksonModule();
    }

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    public Encoder feignEncoder() {
        return new PageableSpringEncoder(new SpringEncoder(messageConverters));
    }
}

Все еще не работает.

Что я использую:

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>

<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.3.RELEASE</version>

Что я делаю неправильно?


Обновление:

Я создал воспроизводимый пример:

https://github.com/manuelwaltschek/mre.git

Запустите клиентскую службу или вызовите spring / spring-cloud-openfeign / 375-pageable-not-working / parent / client / src / test / java / com / example / client / HelloServiceClientTest.java.

Открытые проблемы на github: https://github.com/spring-cloud/spring-cloud-openfeign/issues/375 https://github.com/spring-cloud/spring-cloud-openfeign/issues/385

Изменить: в основном я хочу знать, как передать страницу фальшивому клиенту. Может быть, закодировать в параметрах url?

Связанный вопрос: как передать Spring Pageable в FeignClient


person Manuel Waltschek    schedule 27.07.2020    source источник
comment
github.com/spring-cloud/spring-cloud-openfeign/issues/ 375   -  person Manuel Waltschek    schedule 27.07.2020
comment
Вероятно, spring интерпретирует пример @RequestBody MeasureDto и Pageable pageable как два разных RequestBody и принимает только один.   -  person Murilo Góes de Almeida    schedule 27.07.2020
comment
клиентский и симулируемый клиентские методы должны быть одинаковыми. Я думаю, что если вы скопируете клиентский метод и пропустите его, чтобы симулировать клиента, он сработает.   -  person fatma zehra güç    schedule 28.07.2020
comment
@ fatmazehragüç нет, это не сработает. @RequestHeader - это вообще не проблема   -  person Manuel Waltschek    schedule 28.07.2020
comment
на фальшивом клиенте, возможно, вам стоит сказать @PostMapping (/ your-service / search). что-то подобное.   -  person fatma zehra güç    schedule 28.07.2020


Ответы (2)


Теперь я отправляю страницу в параметрах URL-адреса запроса с помощью аннотации org.springframework.cloud.openfeign.SpringQueryMap в моем параметре Pageable в клиентском интерфейсе

@PostMapping("/search")
public Page<HelloDto> searchHellos(@RequestHeader("apiKey") String apiKey, @RequestBody HelloDto example, @SpringQueryMap Pageable pageable);
person Manuel Waltschek    schedule 29.07.2020

Исключение связано с слишком большим количеством параметров Body, что означает, что вам нужно отправить только один объект в RequestBody, в данном конкретном случае я считаю, что это пример MeasureDto. Страница, которую вы должны передать другим способом, обычно у меня есть целочисленный атрибут страницы в классе (в вашем случае MeasureDTO) или я отправляю номер страницы как @RequestParam, например:

@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestBody MeasureDto example, @RequestParam(required = true) Integer page) {
 
 // PageRequest.Of(numberPage, quantityRegisters) will send a Pageable, in this case bellow, number of page + number of records
    measureService.getMeasurePageable(example, PageRequest.of(page, 10)); 
 }

Несмотря на это, рассмотрите возможность использования GetMapping с queryParams, если вы ищете что-то, а не сохраняете его.

person Murilo Góes de Almeida    schedule 27.07.2020
comment
Спасибо за ваш подход, но я не могу изменить интерфейс зависимости (контроллер). Также я хочу иметь такой же интерфейс для клиента и службы. - person Manuel Waltschek; 27.07.2020
comment
GetMapping не вариант. Я хочу отправить RequestBody с помощью Paging, так как я ищу в репозитории MongoDB, например. - person Manuel Waltschek; 28.07.2020