因?yàn)榉N種原因,沒有按時(shí)寫博客,最近準(zhǔn)備把博客重新拾起來税课。
最近在寫一個(gè)項(xiàng)目拴事,使用到了okhttp的代理毕莱,因?yàn)槭褂玫拇硎歉顿M(fèi)的弄匕,所以需要鑒權(quán)卜范。在使用的過程中碰到了一些問題所以記錄一下
默認(rèn)的okhttp代理鑒權(quán)如下:
import okhttp3.*;
import java.io.IOException;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;
public class ProxyTest {
public static void main(String[] args) {
String url = "https://www.baidu.com";
//設(shè)置socks代理服務(wù)器ip端口
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 1086));
Authenticator.setDefault(new Authenticator()
{
private PasswordAuthentication authentication = new PasswordAuthentication("username", "password".toCharArray());
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return authentication;
}
});
OkHttpClient client = new OkHttpClient().newBuilder().
connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).proxy(proxy)
// 解決內(nèi)存溢出問題
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build();
Request build = new Request.Builder()
.url(url)
.build();
Response response = null;
client.newCall(build).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("服務(wù)器端錯(cuò)誤: " + response);
}
System.out.println(response.body().string());
}
});
}
}
但是試了一下發(fā)現(xiàn)會(huì)報(bào)錯(cuò),代理鑒權(quán)失敗
java.io.IOException: Failed to authenticate with proxy
at okhttp3.internal.connection.RealConnection.createTunnel(RealConnection.java:401)
at okhttp3.internal.connection.RealConnection.connectTunnel(RealConnection.java:218)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:159)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
于是采用另外一種方式
import okhttp3.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;
public class ProxyTest {
public static void main(String[] args) {
String url = "https://www.baidu.com";
final String username = "username";
final String password = "password";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 1086));
Authenticator proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
OkHttpClient client = new OkHttpClient().newBuilder().
connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
// 解決內(nèi)存溢出問題
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build();
Request build = new Request.Builder()
.url(url)
.build();
Response response = null;
client.newCall(build).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("服務(wù)器端錯(cuò)誤: " + response);
}
System.out.println(response.body().string());
}
});
}
}
通過將用戶名和密碼增加到header中的這種方式解決,不過通過引入的包隧土,還是能夠看出第一種用的是java.net 包中的鑒權(quán)方式垛孔,應(yīng)該是跟okhttp的鑒權(quán)方式有區(qū)別導(dǎo)致的