【我的Android进阶之旅】使用Retrofit进行Post请求报错: @Field parameters can only be used with form encoding.

版权声明:本文为【欧阳鹏】原创文章,欢迎转载,转载请注明出处! 【http://blog.csdn.net/ouyang_peng】 https://blog.csdn.net/qq446282412/article/details/82879221

一、问题描述

今天随手写一个post请求的时候,报错了,如下所示:
在这里插入图片描述

09-28 11:11:28.155 10547-10547/com.xtc.watch E/Fatal: {CrashHandler.saveAndPrintLog-58} 
    java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
        at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:112)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5981)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
     Caused by: rx.exceptions.OnErrorNotImplementedException: @Field parameters can only be used with form encoding. (parameter #1)
        for method WatchAccountHttpService.getByBindNumber
        at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
        at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
        at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
        at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:152)
        at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:115)
        at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:216)
        at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139)
        at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:227)
        at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107)
        	... 7 more
     Caused by: java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)
        for method WatchAccountHttpService.getByBindNumber
        at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:720)
        at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:711)
        at retrofit2.ServiceMethod$Builder.parameterError(ServiceMethod.java:729)
        at retrofit2.ServiceMethod$Builder.parseParameterAnnotation(ServiceMethod.java:501)
        at retrofit2.ServiceMethod$Builder.parseParameter(ServiceMethod.java:333)
        at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:202)
        at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
        at retrofit2.Retrofit$1.invoke(Retrofit.java:145)
        at java.lang.reflect.Proxy.invoke(Proxy.java:393)
        at $Proxy42.getByBindNumber(Unknown Source)
        	... 9 more

二、分析和解决问题

2.1 分析问题

根据错误信息,跟踪错误堆栈,然后找到对应的Retrofit接口定义之处,如下所示:

    @POST("/oyp/csdn/bindnumber")
    Observable<HttpResponse<NetWatchAccount>> getByBindNumber(@Field("number") String number);

参考retrofit官方介绍网站: http://square.github.io/retrofit/

在这里插入图片描述

哎,当POST请求时,@FormUrlEncoded和@Field简单的表单键值对。两个需要结合使用,否则会报错。 由于写的太快了,把@FormUrlEncoded注解忘记了。

2.2 解决问题

在 @POST注解之上,加上@FormUrlEncoded注解即可。

    @FormUrlEncoded
    @POST("/oyp/csdn/bindnumber")
    Observable<HttpResponse<NetWatchAccount>> getByBindNumber(@Field("number") String number);

三、Retrofit注解

在这里插入图片描述

  • 方法注解
注解代码 请求格式
@GET GET请求
@POST POST请求
@PUT PUT请求
@DELETE DELETE请求
@HEAD HEAD请求
@OPTIONS OPTIONS请求
@PATCH PATCH请求
@HTTP 作用于方法,用于发送一个自定义的HTTP请求
  • 标记注解
注解代码 说明
@FormUrlEncoded 请求体是 From 表单 @POST比起@GET多了一个@FromUrlEncoded的注解。如果去掉@FromUrlEncoded在post请求中使用@Field和@FieldMap,那么程序会抛出Java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. 的错误异常。所以如果平时公司如果是Post请求的话,千万别忘记了加这@FromUrlEncoded注解
@Multipart 请求体是支持文件上传的 From 表单
@Streaming 响应体的数据用流的形式返回,未使用该注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据较大时,需要使用该注解。
  • 参数注解
注解代码 说明
@Query 主要用于Get请求数据,用于拼接在拼接在Url路径后面的查询参数,一个@Query相当于拼接一个参数,多个参数中间用,隔开
@QueryMap 主要的效果等同于多个@Query参数拼接,主要也用于Get请求网络数据。
@Body 非表单请求体,是结合post请求的
@Field 表单字段,@Field的用法类似于@Query,就不在重复列举了,主要不同的是@Field主要用于Post请求数据。
@FieldMap 表单字段,@FieldMap的用法类似于@QueryMap。两者主要区别是:如果请求为post实现,那么最好传递参数时使用@Field、@FieldMap和@FormUrlEncoded。因为@Query和或QueryMap都是将参数拼接在url后面的,而@Field或@FieldMap传递的参数时放在请求体的。
@Part 表单字段,与 PartMap 配合,适合文件上传情况
@PartMap 表单字段,与 Part 配合,适合文件上传情况;默认接受 Map<String, RequestBody> 类型,非 RequestBody 会通过 Converter 转换
  • 其他注解
注解代码 说明
@Headers 静态添加一个或者多个Header请求头
@Header 动态添加Header请求头
@HeaderMap 使用Map动态添加多个Header请求头
@Url @Url是动态的Url请求数据的注解。需要注意的是使用@Url时,path对应的路径不能包含”/”,不然每个加到host Url后面的东西都会被省略掉。千万注意了
@Path @Path主要用于Get请求,用于替换Url路径中的变量字符。

参考链接


作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/ouyang_peng/article/details/82879221
☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
github.com/ouyangpeng
[email protected]


如果本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行打赏。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq446282412/article/details/82879221