问题描述
这是以下代码,我尝试按照一些示例使用 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();
}