Java - url 无法读取图像

Java - Unable to read image by url

我一直在到处寻找答案,但没有任何帮助。

这就是我的代码:

BufferedImage img1 = ImageIO.read(new File(dir1));
URL url = new URL(image_srcURL);
BufferedImage img2 = 
ImageIO.read(url.openStream());

现在,当我尝试阅读 url.

时,出现以下异常

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:198) at java.base/sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1974) at java.base/sun.security.ssl.Handshaker.fatalSE(Handshaker.java:345) at java.base/sun.security.ssl.Handshaker.fatalSE(Handshaker.java:339) at java.base/sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1968) at java.base/sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1777) at java.base/sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:264) at java.base/sun.security.ssl.Handshaker.processLoop(Handshaker.java:1098) at java.base/sun.security.ssl.Handshaker.processRecord(Handshaker.java:1026) at java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1137) at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074) at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) at java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245) at com.folderName.Tools.DataForAutomationV1.compareImg(DFA.java:606) at com.folderName.VendorTests.SettingsPage.editCompDets(SettingsPage.java:562) at com.folderName.VendorTests.SettingsPage.runTest(SettingsPage.java:62) at com.folderName.Vendor.vendorTests(Vendor.java:36) at com.folderName.Main.main(Main.java:40) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290) at java.base/sun.security.validator.Validator.validate(Validator.java:264) at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:343) at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:226) at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:133) at java.base/sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1947) ... 20 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 26 more

任何帮助都会很棒。 我正在尝试读取 url 中的图像并将其与现有文件进行比较。 这里没有任何问题给出答案。

编辑:

我尝试在我的命令行中输入“keytool -list -keystore keystore”,但它只显示了 trustedCertEntries。还没有解决方案。

首先您需要获取服务器的证书,将其添加到 keystone 文件中,可以添加到 jre 中的 java truststore 中,也可以添加到单独的文件中。如果您要创建新的信任库,请确保为您的程序提供信任库

下面是我如何实现它的示例。代码将响应主体读入 awt BufferedImage,然后写入 .jpg 文件,然后将文件读回字节数组,然后删除文件。我确定我在 SO 上找到了这方面的帮助,但我手头没有答案。我将尝试找到它,以便我可以引用。希望对你有帮助!

**正如@Srikanthkumar 在他的回答中提到的那样进行编辑,您还需要获取证书并将其添加到 JVM 的信任库中。您可以通过任何具有证书浏览工具的浏览器通过浏览器获取它。

import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.Base64;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public String getImage(String productNumber) throws EcomWebException {

try {
    BufferedImage image = ImageIO.read(url);
    File file = new File(guid.toString() + ".jpg");
    ImageIO.write(image, "jpg", file);
    String base64ImageString = Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath()));
    file.delete();
    return base64ImageString;
} catch (Exception e) {
    throw new EcomWebException(IMAGE_NOT_FOUND_MESSAGE + productNumber, e);
}
}

来自 this post 的以下片段可能对您有所帮助:

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }

        @Override
        public void checkClientTrusted(
            java.security.cert.X509Certificate[] certs, String authType
        ) {}

        @Override
        public void checkServerTrusted(
            java.security.cert.X509Certificate[] certs, String authType
        ) {}
    }
};

try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());

    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
}