Android:使用Retrofit进行Post请求报错: @Field parameters can only be used with form encoding.
转载
今天随手写一个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路径中的变量字符。
|