OkHTTP 基本身份验证什么都不做

问题描述

这是以下代码,我尝试按照一些示例使用 okhttp 进行基本身份验证。正常的 HTTP 请求(注释掉)工作正常,所以它不是网络问题或类似的问题。尝试进行身份验证的主要提取代码根本不会尝试连接到网络服务器。网络服务器日志中没有任何内容,如果我使用 tcpdump 检查端口 80,我什么也没有得到。

使用 OkHTTP 的人有什么想法吗?

package com.example.webclient;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

import androidx.appcompat.app.AppCompatActivity;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import okhttp3.Authenticator;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;


public class MainActivity extends AppCompatActivity {

  private OkHttpClient client;

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

   // works
   // client = new OkHttpClient();
   // run("http://192.168.1.1/old");

    //does not work
    String url = "http://192.168.1.1/new";

    try {
      fetch(url,"user","pass");
    } catch (Exception e) {
      e.printstacktrace();
    }



  }

  private void run(String url) {
    Request request = new Request.Builder()
            .url(url)
            .build();

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

      @Override
      public void onResponse(@NotNull Call call,@NotNull Response response){
        String url = response.body().toString();
        //your code here
      }
    });
  }


  public static Response fetch(String url,String username,String password) throws Exception {

    OkHttpClient httpClient = createAuthenticatedClient(username,password);
    // execute request
    return doRequest(httpClient,url);

  }

  private static OkHttpClient createAuthenticatedClient(final String username,final String password) {
    // build client with authentication information.
    OkHttpClient httpClient = new OkHttpClient.Builder().authenticator(new Authenticator() {
      public Request authenticate(Route route,Response response) throws IOException {
        String credential = Credentials.basic(username,password);
        if (responseCount(response) >= 3) {
          return null;
        }
        return response.request().newBuilder().header("Authorization",credential).build();
      }
    }).build();
    return httpClient;
  }

  private static Response doRequest(OkHttpClient httpClient,String anyURL) throws Exception {
    Request request = new Request.Builder().url(anyURL).build();
    Response response = httpClient.newCall(request).execute();
    if (!response.isSuccessful()) {
      throw new IOException("Unexpected code " + response);
    }
    System.out.println(response.body().string());
    return response;
  }

  private static int responseCount(Response response) {
    int result = 1;
    while ((response = response.priorResponse()) != null) {
      result++;
    }
    return result;
  }


}

解决方法

在这里,您正在应用程序的主线程(在 onCreate 中)尝试网络操作。在调用 fetch 方法之前,您应该允许 StrictMode ThreadPolicy 用于开发/调试目的。

 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();
        StrictMode.setThreadPolicy(policy);

    // works
   //  client = new OkHttpClient();
   //  run("http://192.168.1.1/old");

    //does not work
    String url = "http://192.168.1.1/new";
    try {
        fetch(url,"user","pass");
    } catch (Exception e) {
        e.printStackTrace();
    }