今天随手写一个post请求的时候,报错了,如下所示:

Android:使用Retrofit进行Post请求报错: @Field parameters can only be used with form encoding._android

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);
  • 1
  • 2

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

Android:使用Retrofit进行Post请求报错: @Field parameters can only be used with form encoding._表单_02

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

2.2 解决问题

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

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

三、Retrofit注解

Android:使用Retrofit进行Post请求报错: @Field parameters can only be used with form encoding._java_03

  • 方法注解

注解代码

请求格式

@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路径中的变量字符。