博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenFeign学习(六):OpenFign进行表单提交参数或传输文件
阅读量:4096 次
发布时间:2019-05-25

本文共 4857 字,大约阅读时间需要 16 分钟。

说明

在之前的博文中,我简单介绍了OpenFeign的使用方式。其中在请求传递参数时,可以使用@Param和@QueryMap注解。本篇博文我将介绍学习如何使用OpenFeign进行表单参数提交或者传输文件。

正文

我们先看下之前示例中只使用@Param和@QueryMap的局限性:

@Param注解用来解析其他注解中的参数表达式,一般用于restful风格的请求方式中。@QueryMap注解则是用来定义参数的Map集合或者是POJO。这两种方式定义的参数在请求时都会直接拼接在连接中,如 http:xxx?name1=value1&name2=value2。

在使用时我们希望以POST方式将参数以表单的形式提交。这里我做了以下尝试,将请求方式改为POST,并配置请求头ContentType为application/x-www-form-urlencoded,方法的参数使用@Param标记并使用默认的encoder。

@RequestLine("POST /test/hello2")@Headers("Content-Type: application/x-www-form-urlencoded")ResultPojo hello2Post(@Param("name") String name);

在执行时抛出异常,默认的ecoder不支持LinkedHashMap的编码:

feign.codec.EncodeException: class java.util.LinkedHashMap is not a type supported by this encoder.

可以发现只将ContentType设置为application/x-www-form-urlencoded并不能实现表单提交,我们需要配置特殊的encoder。对此,OpenFeign官方在项目中为我们提供了Form Encoder。

Form Encoder

OpenFeign提供的该模块支持表单application/x-www-form-urlencoded 和 multipart/form-data 两种编码。

在使用前需要添加依赖:

io.github.openfeign.form
feign-form
3.8.0

之后可以直接配置Encoder

HelloService service = Feign.builder()			.logger(new Slf4jLogger())			.logLevel(Logger.Level.FULL)			.client(new OkHttpClient())//			.encoder(new JacksonEncoder())			.encoder(new FormEncoder())			.decoder(new JacksonDecoder())			.requestInterceptor(new HeadersInterceptor())			.errorDecoder(new CustomErrorDecoder())			.retryer(new MyRetryer(5))			.exceptionPropagationPolicy(ExceptionPropagationPolicy.UNWRAP)			.target(HelloService.class, "http://localhost:8080/");

可以看到我把之前的JacksonEncoder注释后,新配置了FormEncoder。但是我又希望同时使用这两种Encoder,OpenFeign对此也进行了支持,FormEncoder装饰JacksonEncoder,在FormEncoder类内部将另一个Ecoder对象作为类成员。

public class FormEncoder implements Encoder {    private static final String CONTENT_TYPE_HEADER = "Content-Type";    private static final Pattern CHARSET_PATTERN = Pattern.compile("(?<=charset=)([\\w\\-]+)");    private final Encoder delegate;    private final Map
processors; public FormEncoder() { this(new Default()); } public FormEncoder(Encoder delegate) { this.delegate = delegate; List
list = Arrays.asList(new MultipartFormContentProcessor(delegate), new UrlencodedFormContentProcessor()); this.processors = new HashMap(list.size(), 1.0F); Iterator var3 = list.iterator(); while(var3.hasNext()) { ContentProcessor processor = (ContentProcessor)var3.next(); this.processors.put(processor.getSupportedContentType(), processor); } } .....}

可以看到FormEncoder的无参构造函数也会创建默认的Encoder对象。我们可以使用以下方式进行配置:

.encoder(new FormEncoder(new JacksonEncoder()))

注意,在使用FormEncoder时,必须配置ContentType。FormEncoder支持两种类型:

application/x-www-form-urlencoded

在配置Header后,方法的参数我们可以使用@Param注解或者是参数类POJO

@RequestLine("POST /test/hello2")@Headers("Content-Type: application/x-www-form-urlencoded")ResultPojo hello2Post(@Param("name") String name);@RequestLine("POST /test/hello2")@Headers("Content-Type: application/x-www-form-urlencoded")ResultPojo hello2Post2(ParamPojo paramPojo);

与之前相同,Pojo的变量名将被作为key。

multipart/form-data

在上传文件时需要使用该类型的Content-Type,OpenFeign也提供了几种使用方式:

@RequestLine("POST /test/file")@Headers("Content-Type: multipart/form-data")String uploadFile(@Param("file") File file);@RequestLine("POST /test/bytedata")@Headers("Content-Type: multipart/form-data")String uploadByteData(@Param("bytedata") byte[] data);@RequestLine("POST /test/formdata")@Headers("Content-Type: multipart/form-data")String uploadByFormData(@Param("file") FormData formData);@RequestLine("POST /test/formpojo")@Headers("Content-Type: multipart/form-data")String uploadByPojo(FilePojo filePojo);

在上传文件时,文件可以支持几种不同的方法参数类型进行传输。

  • File 使用文件的扩展名来检测Content-Type
  • byte[] 字节数组将使用application/octet-stream作为Content-Type
  • FormData 将使用FormData设置的Content-Type和fileName
  • 自定义POJO

FormData

FormData是OpenFeign定义的请求参数类,该类有是三个成员变量,分别为contentType, fileName, byte[] data。

@SuppressFBWarnings({"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})public class FormData {    private String contentType;    private String fileName;    private byte[] data;    ...}

在请求时会根据设置值作为Content-Type和fileName

FormData formData = new FormData("image/png", "filename.png", myDataAsByteArray);

服务端使用MultipartFile file作为接受参数,设置的fileName将作为文件的原始名称。

自定义POJO

通过自定义POJO,可以将所有的请求参数组合到一起,使用@FormProperty来设置表单参数名称。服务端使用Multipart file和相应的参数进行接收。

public class FilePojo {    @FormProperty("id")    String id;    @FormProperty("filename")    File file;    public FilePojo() {    }    public FilePojo(String id, File file) {        this.id = id;        this.file = file;    }}
@RequestMapping("test/form-pojo")public String uploadPojo(@RequestParam(value = "filename") MultipartFile file,                         @RequestParam(value = "id") String id) {    return id + file.getOriginalFilename();}

至此,使用OpenFeign进行表单提交和文件上传的使用方式已经学习介绍完毕,更详细的内容请看。


源码地址:https://github.com/Edenwds/javaweb/tree/master/feigndemo

转载地址:http://rdeii.baihongyu.com/

你可能感兴趣的文章
由Python谈及编程语言的分类
查看>>
2 sum, 3 sum, 4sum以及python collections.Counter
查看>>
二叉树的中序遍历,每层遍历,以及Z字形遍历
查看>>
时间复杂度的定义,记号以及几种计算方法
查看>>
摊还分析,核算法与势能法
查看>>
使用快慢指针判断链表是否有环
查看>>
决策树的概念,分类和初步的建树过程
查看>>
决策树中的ID3, C4.5, CART算法及其优缺点
查看>>
Pandas 踩坑 dataframe.index.values
查看>>
在 PyPI 上发布 python 包
查看>>
DRF项目工程基础包
查看>>
inception安装使用
查看>>
Django Rest Swagger生成api文档
查看>>
docker-compose 环境变量问题
查看>>
vue 配置后台接口方式
查看>>
drf jwt 认证
查看>>
Vue 初体验
查看>>
记一次sentry部署过程
查看>>
python 开发环境配置
查看>>
Docker 部署Django项目
查看>>