我想从 URL 获取 html 页面源代码。 Retrofit 在 post Lollipop 设备上完成这项工作。但在 Lollipop 之前的设备上,它会给出不支持的协议(protocol)错误。
代码:
private static final String TAG = "TESTTESTTESTTEST";
private static String url = "https://www.hepsiburada.com/lassa-235-65r17-108h-xl-competush-" +
"l-p-OTLST216410?magaza=LastikArt%C4%B1&utm_source=pc&utm_medium=cimri&utm_campaign" +
"=c&utm_content=c&utm_term=5083&wt_pc=cimri.c.5083.pc/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl("https://www.google.com/")
.build();
IGetHtml iGetHtml = retrofit.create(IGetHtml.class);
Call<String> stringCall = iGetHtml.getHtml(url);
stringCall.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
String responseString = response.body();
Log.e(TAG, "onResponse: " + response.body());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(TAG, "onFailure: " + t);
}
});
}
错误
E/NativeCrypto: Unknown error during handshake 07-09 12:23:57.606
E/TESTTESTTESTTEST:onFailure:javax.net.ssl.SSLHandshakeException:javax.ne.ssl.SSLProtocolException: SSL handshake aborted:ssl=0x7cf6f320: Failure in SSL library, usually a protocol error error:14077102:SSL routines:SSL23_GET_SERVER_HELLO:unsupported protocol (external/openssl/ssl/s23_clnt.c:714 0x7a084894:0x00000000)
最佳答案
我用这个解决方案解决了我的错误。
一切都和我在问题中写的一样,除了这个变化。
将此类添加到您的项目中。
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
delegate = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(delegate.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if (socket != null && (socket instanceof SSLSocket)) {
((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
然后onCreate方法改成这个。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OkHttpClient client = new OkHttpClient();
try {
client = new OkHttpClient.Builder()
.sslSocketFactory(new TLSSocketFactory())
.build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.google.com/")
.client(client)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
IGetHtml iGetHtml = retrofit.create(IGetHtml.class);
Call<String> stringCall = iGetHtml.getHtml(url);
stringCall.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
Log.e(TAG, "onResponse: " + response.headers());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(TAG, "onFailure: " + t);
}
});
}
关于android - retrofit 请求不适用于 Lollipop 之前的设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56949367/