21

使用spring-mvc注释:

  • 我如何定义一个@FeignClient可以POST form-url-encoded
4

5 回答 5

19

对 Feign使用FormEncoder

您的 Feign 配置可能如下所示:

class CoreFeignConfiguration {
  @Autowired
  private ObjectFactory<HttpMessageConverters> messageConverters

  @Bean
  @Primary
  @Scope(SCOPE_PROTOTYPE)
  Encoder feignFormEncoder() {
      new FormEncoder(new SpringEncoder(this.messageConverters))
  }
}

然后,客户端可以像这样映射:

@FeignClient(name = 'client', url = 'localhost:9080', path ='/rest',
    configuration = CoreFeignConfiguration)
interface CoreClient {
    @RequestMapping(value = '/business', method = POST, 
                 consumes = MediaType.APPLICATION_FORM_URLENCODED)
    @Headers('Content-Type: application/x-www-form-urlencoded')
    void activate(Map<String, ?> formParams)
}
于 2017-07-05T10:57:49.930 回答
18

带有简化版 kazuar 解决方案的完整 Java 代码,适用于 Spring Boot:

import java.util.Map;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;

@FeignClient(name = "srv", url = "http://s.com")
public interface Client {

    @PostMapping(value = "/form", consumes = APPLICATION_FORM_URLENCODED_VALUE)
    void login(@RequestBody Map<String, ?> form);

    class Configuration {
        @Bean
        Encoder feignFormEncoder(ObjectFactory<HttpMessageConverters> converters) {
            return new SpringFormEncoder(new SpringEncoder(converters));
        }
    }
}

依赖:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
于 2019-02-23T13:12:46.013 回答
1

只是为了补充接受的答案,也可以使用 POJO 而不是Map<String, ?>为了将表单参数传递给 feign 客户端:

@FeignClient(configuration = CustomConfig.class)
interface Client {

    @PostMapping(
        path = "/some/path", 
        consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    void postComment(CommentFormDto formDto);
    ...
}
...

class CustomConfig {
    @Bean
    Encoder formEncoder() {
        return new feign.form.FormEncoder();
    }
}
...

class CommentFormDto {

    private static String willNotBeSerialized;

    private final Integer alsoWillNotBeSerialized;

    @feign.form.FormProperty("author_id")
    private Long authorId;

    private String message;

    @feign.form.FormProperty("ids[]")
    private List<Long> ids;
    
    /* getters and setters omitted for brevity */  
}

这将导致请求的正文看起来像这样:

author_id=42&message=somemessage&ids[]=1&ids[]=2

@FeignProperty注释允许设置自定义字段名称;请注意 POJO 的静态或最终字段以及继承的字段不会被序列化为表单内容。

于 2021-12-14T09:42:18.133 回答
0

您必须FormEncoder在 Feign 编码器中使用 POST 中的 url-form-encoded 数据。

将依赖项包含到您的应用程序中:

马文:

<dependency>
  <groupId>io.github.openfeign.form</groupId>
  <artifactId>feign-form</artifactId>
  <version>3.8.0</version>
</dependency>

像这样将 FormEncoder 添加到您的 Feign.Builder 中:

SomeFeign sample  = Feign.builder()
                      .encoder(new FormEncoder(new JacksonEncoder()))
                      .target(SomeFeign.class, "http://sample.test.org");

在 Feign 界面中

@RequestLine("POST /submit/form")
@Headers("Content-Type: application/x-www-form-urlencoded")
void from (@Param("field1") String field1, @Param("field2") String field2);

更多信息请参考: https ://github.com/OpenFeign/feign-form

于 2020-07-27T17:28:51.100 回答
0

对于 Feign.Builder,我的工作没有 JacksonEncoder,只有 Feign FormEncoder:

将 FormEncoder 添加到 Feign.Builder:

SomeFeign sample  = Feign.builder()
                  .encoder(new FormEncoder())     <==difference here
                  .target(SomeFeign.class, "http://sample.test.org");

我添加到 pom.xml 的 feign 依赖项:

<dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-core</artifactId>
        <version>11.8</version>
    </dependency>

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-jackson</artifactId>
        <version>11.8</version>
    </dependency>
    
    <dependency>
        <groupId>io.github.openfeign.form</groupId>
        <artifactId>feign-form</artifactId>
        <version>3.8.0</version>
    </dependency>

pom.xml 中的父级是:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

Ramanan 给出的 feign 界面:

@RequestLine("POST /submit/form")
@Headers("Content-Type: application/x-www-form-urlencoded")
void from (@Param("field1") String field1, @Param("field2") String field2);
于 2021-12-27T19:21:21.943 回答