版权声明:本文为【欧阳鹏】原创文章,欢迎转载,转载请注明出处! 【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/MillerKevin/article/details/78680856
- https://blog.csdn.net/jasonwang18/article/details/68486709
- https://blog.csdn.net/qiang_xi/article/details/53959437
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/ouyang_peng/article/details/82879221
☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
☞ github.com/ouyangpeng
☞ [email protected]
如果本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行打赏。