英文:
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("/search")
public Page<MeasureDto> searchMeasures(@RequestBody MeasureDto example, Pageable pageable) {
...
}
The client looks like this:
@PostMapping("/search")
public Page<MeasureDto> searchMeasures(@RequestHeader("apiKey") 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:
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<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignEncoder() {
return new PageableSpringEncoder(new SpringEncoder(messageConverters));
}
}
Still not working.
What I am using:
<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>
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("/search")
public Page<HelloDto> searchHellos(@RequestHeader("apiKey") 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("/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));
}
Despite of that, consider using GetMapping with queryParams if you are searching things and not saving it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论