【Android开发】&okhttp+retrofit+rexjava提交cookie实现登陆与注册遇到的两次请求

今天实现登陆和注册功能,发送数据到服务器的过程中遇到两次提交数据的情况。而出现这个情况的原因是因为我使用两个拦截器。代码如下所示。首先这里设置请求头,将cookie放到请求头中,发送到服务器实现登陆与注册验证码的校验。

public class AddCookiesInterceptor implements Interceptor {

    Context context;

    public AddCookiesInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        /*设置cookie*/
        Request.Builder builder = chain.request().newBuilder();
        HashSet<String> preferences = (HashSet) this.context.getSharedPreferences("config",
                this.context.MODE_PRIVATE).getStringSet("cookie", null);
        if (preferences != null) {
            for (String cookie : preferences) {
                builder.addHeader("Cookie", cookie);
                builder.addHeader("Content-Type", "text/html; charset=UTF-8");
                Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
            }
        }
        chain.proceed(chain.request());



        return chain.proceed(builder.build());
    }
}

而另外一个拦截器则定义如下所示。主要是接收cookie,存储到移动端。在下一次也就是填好数据后,将cookie发送到服务器。

public class ReceivedCookiesInterceptor implements Interceptor {


    Context context;

    public ReceivedCookiesInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());
        if (!originalResponse.headers("Set-Cookie").isEmpty()) {
            HashSet<String> cookies = new HashSet<>();

            for (String header : originalResponse.headers("Set-Cookie")) {
                cookies.add(header);
            }

            SharedPreferences.Editor config = context.getSharedPreferences("config", context.MODE_PRIVATE)
                    .edit();
            config.putStringSet("cookie", cookies);
            config.commit();
        }

        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("Content-Type", "text/html; charset=UTF-8");

        //return originalResponse;
        return chain.proceed(builder.build());
    }
}

问题就出现在上面的这段代码,与后台交互过程中,出现两次请求,开始我也很懵逼。好像代码没有问题,后面发现问题出现在这一句代码。执行这句后,会发送发送一次请求。那么加上最开始那个类的chain.proceed(chain),一共就是两次请求了。

chain.proceed(chain.request());

这是因为在okhttp中做这样的拦截。

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间
        builder.writeTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS);//写操作 超时时间
        builder.readTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS);//读操作超时时间
        builder.retryOnConnectionFailure(false);
        //https://segmentfault.com/q/1010000003894433
        builder.addInterceptor(new AddCookiesInterceptor(mContext));
        builder.addInterceptor(new ReceivedCookiesInterceptor(mContext));

出现这样的问题后,导致我发送的验证码,无法和服务器相对应。好了,最后找到解决方案。如下代码。

  private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();     
 builder.cookieJar(new CookieJar() {
            @Override
            public void saveFromResponse(HttpUrl httpUrl, List<Cookie> cookies) {
                cookieStore.put(httpUrl.host(), cookies);
            }
            @Override
            public List<Cookie> loadForRequest(HttpUrl httpUrl) {
                List<Cookie> cookies = cookieStore.get(httpUrl.host());
                return cookies != null ? cookies : new ArrayList<Cookie>();
            }
        });

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值