如何在带有额外的 @RequestBody 的 POST 请求中将 Pageable 传递给 Feign 客户端

huangapple go评论75阅读模式
英文:

How to pass Pageable to Feign Client in POST Request with additional @RequestBody

问题

我尝试在Spring中为我的REST服务控制器创建一个Feign客户端。

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

在运行测试时抛出以下异常:

Caused by: java.lang.IllegalStateException: Method has too many Body parameters: 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

编辑:基本上,我想知道如何将Pageable传递给Feign客户端。也许可以将其编码为URL参数?

相关问题:https://stackoverflow.com/questions/63152147/how-to-pass-spring-pageable-to-feignclient

英文:

I tried to create a feign client for my REST service controller in Spring.

@PostMapping(&quot;/search&quot;)
public Page&lt;MeasureDto&gt; searchMeasures(@RequestBody MeasureDto example, Pageable pageable) {
    ...
}

The client looks like this:

@PostMapping(&quot;/search&quot;)
public Page&lt;MeasureDto&gt; searchMeasures(@RequestHeader(&quot;apiKey&quot;) String apiKey, @RequestBody MeasureDto example, Pageable pageable);

Following exception is thrown when running a test:

> Caused by: java.lang.IllegalStateException: Method has too many Body parameters: 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)

What I already know/tried:

There is a closed issue on github: https://github.com/spring-cloud/spring-cloud-netflix/issues/556

The issue with the commit that should have resolved the problem:

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

The commit:

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

What i configured:

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&lt;HttpMessageConverters&gt; messageConverters;

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

Still not working.

What I am using:

&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
&lt;version&gt;2.3.1.RELEASE&lt;/version&gt;

&lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
&lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
&lt;version&gt;2.2.3.RELEASE&lt;/version&gt;

What am I doing wrong?


Update:

I created a reproducable example:

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

Start up the client service or call
spring/spring-cloud-openfeign/375-pageable-not-working/parent/client/src/test/java/com/example/client/HelloServiceClientTest.java

Open issues on github:
https://github.com/spring-cloud/spring-cloud-openfeign/issues/375
https://github.com/spring-cloud/spring-cloud-openfeign/issues/385

Edit: Basically I want to know how to pass the pageable to the feign client. Maybe encode it in url params?

Related question: https://stackoverflow.com/questions/63152147/how-to-pass-spring-pageable-to-feignclient

答案1

得分: 8

我现在使用org.springframework.cloud.openfeign.SpringQueryMap注解在客户端接口的Pageable参数上,将可分页对象作为查询URL参数发送:

@PostMapping("/search")
public Page<HelloDto> searchHellos(@RequestHeader("apiKey") String apiKey, 
                                   @RequestBody HelloDto example,
                                   @SpringQueryMap Pageable pageable);
英文:

I'm now sending the pageable in query url params with org.springframework.cloud.openfeign.SpringQueryMap annotation on my Pageable Parameter in the Client interface

@PostMapping(&quot;/search&quot;)
public Page&lt;HelloDto&gt; searchHellos(@RequestHeader(&quot;apiKey&quot;) String apiKey, 
                                   @RequestBody HelloDto example,
                                   @SpringQueryMap Pageable pageable);

答案2

得分: 2

以下是翻译好的内容:

这个异常与“Body参数过多”有关,这意味着您必须在RequestBody中只发送一个对象,在这种特定情况下,我认为它是MeasureDto“example”。您需要以不同的方式传递页面,通常情况下,我在类中有一个“page”整数属性(在您的情况下是MeasureDTO),或者我将页码作为@RequestParam发送,如下所示:

@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestBody MeasureDto example, @RequestParam(required = true) Integer page) {
     
    // PageRequest.Of(numberPage, quantityRegisters)将发送一个Pageable,在这种情况下,页数+记录数
    measureService.getMeasurePageable(example, PageRequest.of(page, 10)); 
}

尽管如此,如果您要搜索内容而不是保存内容,考虑使用带有queryParams的GetMapping。

英文:

The exception is related "too many Body parameters", that means you have to send only one object in RequestBody, in this particular case I believe it is MeasureDto "example". The page you have to pass in a different way, generally I have a "page" integer attribute in the class (in your case, MeasureDTO) or I send the page number as @RequestParam, like it:

@PostMapping(&quot;/search&quot;)
public Page&lt;MeasureDto&gt; 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)); 
 }

Despite of that, consider using GetMapping with queryParams if you are searching things and not saving it.

huangapple
  • 本文由 发表于 2020年7月27日 20:43:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63115610.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定