【问题标题】:How to send requset after another one in OkHTTP3?如何在 OkHTTP3 中发送一个又一个请求?
【发布时间】:2017-08-09 10:17:29
【问题描述】:

如何在另一个使用 OkHTTP3 之后发送请求? 我必须这样做: 1) 我使用方法 OkHTTPRequest 发送 request1 到服务器 2) 服务器用 COOKIE 发送响应 request1 3) 我保存这个 cookie 4) 我用保存的 cookie 发送 request2。

我在第 4 步遇到问题。 似乎 request2 在 request1 之后发送,在 request1 保存他的cookie之前。 如何解决? 我想在请求保存他自己的 cookie 后发送 reuest2。

  @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);

        try
        {
            // Получаем cookie и авторизируемся
            Log.d("TAG", "Вызываем  OkHTTPRequest1");
            OkHTTPRequest(postUrl, "POST", postData1);
            Log.d("TAG", "Вызываем  OkHTTPRequest2");
            OkHTTPRequest(postUrl2, "PUT", postData2);

            int a;
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (JSONException e)
        {
            e.printStackTrace();
        }

    }

    // Сохраняем cookieFromServer
    public void saveCookie(List<Cookie> cookies)
    {
        for (int i = 0; i < cookies.size(); i++)
        {
            String str = cookies.get(i).toString();
            if (str.indexOf("issa7=") != -1)
            {
                cookieFromServer.add(cookies.get(i));
                Log.d("TAG", "Сохраняем cookie в глобальную переменную  ="+ cookies.get(i).toString());
            }
        }
    }

    // Создаем клиент OkHTTPRequest и обрабатываем запросы
    void OkHTTPRequest(String postUrl, String requestMethodType, String postData) throws IOException, JSONException
    {
        // Создаем клиент OkHTTPRequest
        OkHttpClient client = new OkHttpClient()
                .newBuilder()
                // Переопределяем методы чтобы можно было сохранять и применять ccokie в запросах
                .cookieJar(new CookieJar()
                {
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies)
                    {
                        saveCookie(cookies);
                        Log.d("TAG", "Вызываем  saveCookie ");
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url)
                    {
                        Log.d("TAG","Читаем cookie");
                        return cookieFromServer;
                    }
                })
                .build();

        Log.d("TAG","Создаем OkHttpClient клиента " + client.toString());

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, postData);
        Request request = new Request.Builder()
                .url(postUrl)
                .method(requestMethodType, body)
                .addHeader("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4")
                .addHeader("Cache-Control", "max-age=0")
                .addHeader("Connection", "keep-alive")
                .addHeader("User-Agent", "Mango Mobile Android")
                .build();

        client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException
            {
                // Получать response.body().string() можно только один раз. Иначе будет ошибка так реализованно.
                String html = response.body().string();
                //Log.d("TAG", "Код сайта "+ html);
                Document doc = Jsoup.parse(html);
                // Копируем содержание response.body()
                setDoc(doc);
                parseResult(bids);
                // Чтобы обращаться к компанентам из MainActivity нужно использовать runOnUiThread
                MainActivity.this.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        // Отключаем progressBar
                        progressBar.setVisibility(View.GONE);
                        // Устанавливаем адаптер
                        adapter = new MyRecyclerViewAdapter(MainActivity.this, feedsList);
                        mRecyclerView.setAdapter(adapter);
                    }
                });


            }
        });
    }

    // Сохраняем Document код страницы
    void setDoc(Document doc)
    {
        this.doc = doc;
        // Получаем список БИДОВ
        Log.d("TAD", "Получаем список БИДОВ");
        Elements tmpBids = doc.select("a.go-product[href$=\"vats\"]");

        for (int i = 0; i < tmpBids.size(); i++)
        {
            bids.add(tmpBids.get(i).attr("href"));
            //Log.d("TAD", bids.get(i).toString());
        }
    }


    private void parseResult(List<String> bids)
    {
        // Формируем данные feedsList для адаптера
        Log.d("TAD", "Формируем данные feedsList для адаптера");
        feedsList = new ArrayList<>();
        for (int i = 0; i < bids.size(); i++)
        {
            FeedItem item = new FeedItem();
            item.setTitle(bids.get(i));
            item.setThumbnail("thumbnail");
            feedsList.add(item);
        }
    }
}

【问题讨论】:

  • Checkout RxJava 它有 Observables,您可以使用它发出请求链

标签: android okhttp


【解决方案1】:

您的代码存在一些问题。

  1. 方法名称应为小写(风格)OkHTTPRequest(...) 一开始有点混乱。
  2. 您正在异步触发 HTTP 请求,您可以通过调用 client.newCall(request).execute() 来强制 HTTP 客户端阻塞,我相信或者正如其他人建议的那样,使用 RxJava 之类的库来处理链式异步命令。
  3. OkHttpClient 旨在用于多个请求,尤其是在使用 cookie jar 时。理想情况下,您只有一个 OkHttpClient 实例并将其重用于多个请求。您的 cookie jar 似乎可以工作,但这只是因为您使用全局列表来存储 cookie,这可能是一种不好的做法。

如果您可以添加 okhttp3.JavaNetCookieJar 依赖项,您可以使用以下代码获得一个开箱即用的工作 cookie jar。

import okhttp3.JavaNetCookieJar;

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
JavaNetCookieJar cookieJar = new JavaNetCookieJar(cookieManager);

OkHttpClient client = new OkHttpClient.Builder().cookieJar(cookieJar).build();

此外,当您在使用 OkHttp 进行调试时遇到问题时,最好设置一个 OkHttp Logging Interceptor

HttpLoggingInterceptor logging =
    new HttpLoggingInterceptor((msg) -> {
        Log.d(msg);
    });
logging.setLevel(Level.BODY);

client.addNetworkInterceptor(logging);

【讨论】:

    【解决方案2】:

    检查Retrofit。它是一个出色的 Android 和 Java REST 客户端,建立在 OkHttp 之上。它使使用 RxJava 成为一种乐趣。

    这是一篇有用的帖子,可以为您提供更多关于如何使用 Retrofit 和 RxJava helpful post链接您的请求的上下文@

    【讨论】:

      猜你喜欢
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多