我正在研究毕加索作品,以将图像显示到我的android活动中。但是我的服务器具有针对HTTPS的自签名证书,这就是为什么我给我以下错误的原因:
com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 504
我以前修复了该问题,现在在答案中发布解决方案:您需要使用下面的RetrofitClient类(其代码如下)并在方法trustCertificatesInputStream中更新证书:
我希望这会节省一天的时间:)
答案 0 :(得分:-1)
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
public static Retrofit getApiClient(String baseUrl) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
try {
trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.sslSocketFactory(sslSocketFactory, trustManager)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
Log.e("RetrofitClient", baseUrl);
return retrofit;
}
public static OkHttpClient okClient(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
try {
trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.sslSocketFactory(sslSocketFactory, trustManager)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.build();
return client;
}
private static X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
// Put the certificates a key store.
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
private static KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = null; // By convention, 'null' creates an empty key store.
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static InputStream trustedCertificatesInputStream() {
// PEM files for root certificates of Comodo and Entrust. These two CAs are sufficient to view
// https://publicobject.com (Comodo) and https://squareup.com (Entrust). But they aren't
// sufficient to connect to most HTTPS sites including https://godaddy.com and https://visa.com.
// Typically developers will need to get a PEM file from their organization's TLS administrator.
String comodoRsaCertificationAuthority = "-----BEGIN CERTIFICATE-----\n" +
"MIIGHDCCBASgAwIBAgIJAL9YjcpQAkTLMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD\n" +
"VQQGEwJQSzEPMA0GA1UECAwGUHVuamFiMQ8wDQYDVQQHDAZNdWx0YW4xGzAZBgNV\n" +
"j2pjtSNqRIxmXE1ZtOj4f/RxUMoYUSg3AKvG0zRq1WgpKPgqkSi4i3AUI7bXoX7B\n" +
"ayGxYS6Dofx+LfQFugB3HVmn+7lpY/wb1Dp3z/wmi0xT+8BZL/qvI4ISS4mAPJ9d\n" +
"77JwSrQ40qnuWXkoJwC8ubWPP9bQWxolzW2rFn2yRyz9Po/tOYfpV/hhDNbuumxW\n" +
"MHVM3Z1pwTUM1xz8RlFE9uJOGVgMX/iikqZ1EMZ6QwIvXZ7Lcpd0Ov09xeeyIx0x\n" +
"Gj/t9/7PdrDTkTUG3qZ/UJNqcD2dKBY5E7bZn5QhLSJBTva9vCC/N2i4+i77K/Cy\n" +
"X/uaAUlYfUhBD4uet2C88syqtkW0+Vb0MuTO4sO1YSE=\n" +
"-----END CERTIFICATE-----\n";
return new Buffer()
.writeUtf8(comodoRsaCertificationAuthority)
.inputStream();
}
}
然后使用它来加载您的https图像:
// let's change the standard behavior before we create the Picasso instance
// for example, let's switch out the standard downloader for the OkHttpClient
picassoBuilder.downloader(new OkHttp3Downloader(RetrofitClient.okClient()));
// Picasso.Builder creates the Picasso object to do the actual requests
Picasso picasso = picassoBuilder.build();
Picasso.setSingletonInstance(picasso); //apply to default singleton instance
picasso.get().load("https://xxxxxxxxxx.xxx/uploads/16_registration_1575959841.jpeg").noPlaceholder().fit().centerCrop()
.into(imageView, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
Log.e("image Loade","image succssfully loaded");
}
@Override
public void onError(Exception e) {
Log.e("image Loade",e.toString());
}
});
}