Retrofit Get请求中带有特殊字符(^)报400错误

版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/82422139

转眼又是一个月,回首已经过两年,唉。

修改了密码之后登陆app,发现无法登陆直接报错,赶紧查看代码log:

09-05 12:50:29.909 13653-13653/com.yiche.autoreport W/System.err: retrofit2.adapter.rxjava.HttpException: HTTP 400

        at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:43)

        at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:38)

        at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:162)

        at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:80)

        at rx.Subscriber.setProducer(Subscriber.java:211)

        at rx.internal.operators.OperatorSubscribeOn$1$1.setProducer(OperatorSubscribeOn.java:76)

        at rx.Subscriber.setProducer(Subscriber.java:205)

        at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:141)

        at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:127)

        at rx.Observable$2.call(Observable.java:233)

        at rx.Observable$2.call(Observable.java:225)

        at rx.Observable.unsafeSubscribe(Observable.java:8644)

        at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)

        at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)

        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)

        at java.util.concurrent.FutureTask.run(FutureTask.java:237)

        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)

        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)

        at java.lang.Thread.run(Thread.java:818)

没看太明白!

然后观察HttpLoggingInterceptor打印的请求log发现url参数如下:

║ --> GET https://xxxxxx/index/login?username=xxx&password=ssd123$%^ http/1.1

参数中未编码的password为ssd123$%^,”^”字符竟然没有进行url编码,我记得retrofit默认会自动对不符合规则的参数value进行编码。

查看文档可知:

Retrofit中类似@Query,@QueryMap,@QueryName等都会自动进行编码,

注解定义如下:

@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryMap {
    boolean encoded() default false;
}

public abstract boolean encoded

Specifies whether the parameter name and value are already URL encoded.

Default:

false

false表示特殊字符已进行url 编码。

看到这里解决办法已经有了,就是encoded = true,然后自己编码,我设置encoded = true,之后查看log,不符合规则的请求参数还是会进行编码。

/**
 * 登录
 */
@GET( BASE_URL + "index/login" )
Observable< LoginResult > requestLogin( @QueryMap(encoded = true) Map< String, String > params );

final Map< String, String > paramsMap = new ParamsProvider.Builder().
        append( "username", account ).
        append( "password",URLEncoded(password) ).
        build();



这里有个疑问是为什么自动编码时没有对“^”字符进行编码,很奇怪。

猜你喜欢

转载自blog.csdn.net/u010126792/article/details/82422139