在Java中如何等待URL准备就绪?

lfapxunr  于 2023-02-02  发布在  Java
关注(0)|答案(1)|浏览(113)

我创建了一个方法,该方法从带有图像的URL读取字节,并将其写入S3缓冲区。

public void saveFileToStorage(String url, Long timestamp, Integer vehicleId) {
    try {
        URL link = new URL(url);
        Thread.sleep(1500);//wait until URL is ready for download
        byte[] contentBytes = IOUtils.toByteArray(link);
        Long contentLength = (long) contentBytes.length;
        repository.uploadFile(timestamp + ".jpg", link.openStream(), vehicleId.toString() + "/", contentLength);
    } catch (IOException | InterruptedException e) {
        log.error(e.getMessage() + " - check thread sleep time!");
        throw new RuntimeException(e);
    }

}

储存库:

public void uploadFile(String keyName, InputStream file, String folder, Long contentLength) {
    ObjectMetadata folderMetadata = new ObjectMetadata();
    folderMetadata.setContentLength(0);
    ObjectMetadata fileMetadata = new ObjectMetadata();
    fileMetadata.setContentLength(contentLength);
    s3client.putObject(bucketName, folder, new ByteArrayInputStream(new byte[0]), folderMetadata);
    s3client.putObject(new PutObjectRequest(bucketName, folder + keyName, file, fileMetadata));
}

我使用这个方法的主要问题是URL准备时间,当我运行应用程序时,它总是抛出RuntimeException,因为URL还没有准备好读取。经过一些测试,我在查看URL响应时间后,我添加了Thread.sleep,之后应用程序工作正常。但响应时间可能会有所不同,我仍然不时地收到这些错误。检查URL是否准备就绪的最佳方法是什么?我尝试使用下面的代码来检查准备就绪情况,但我不知道如何"等待" URL准备好使用

public static boolean check(String URLName){
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e) {
       return false;
    }
ovfsdjhp

ovfsdjhp1#

我会把这个方法写成这样:

create and configure HttpURLConnection for GET requests
for retries in 0 ... N:
    try:
        connect
        if status code == 200:
            open and read connection input stream
            return
        else:
            if status code not retriable:
                fail
    catch FileNotFound:
        // noop
    catch IOException:
        fail
    sleep S seconds
fail

这和你的方法有一些关键的区别。

  • 这不执行HEAD。这需要额外的到服务器的往返。每次只执行GET。
  • 这不会对所有的状态码都重试。例如,如果你得到一个403,你就不应该重试。
  • 这将重试FileNotFound异常,您将获得404响应;请参阅javadoc。它不应该重试其他IO异常...除非它们可能在重试时成功。
  • 应调整最大重试次数和重试之间的延迟。

相关问题