【问题标题】:Azure storage through java MVC web site通过 java MVC 网站的 Azure 存储
【发布时间】:2016-06-21 23:55:56
【问题描述】:

我有一个使用 Spring 和 hibernate 框架的 java web 应用程序。我正在 azure 上移动这个网络应用程序。在本地网络应用程序中有一个功能,我首先将图像上传到 C 中的临时文件夹中:然后访问该文件以进行应用程序。上传文件的位置也存储在数据库中以供进一步参考。我已经定义了在属性文件中上传文件并在控制器中通过它访问的基本路径以及用于创建目录、文件名和文件路径的服务层。

谁能告诉我如何使用 azure 存储在 azure 中做同样的事情?任何帮助表示赞赏。

属性文件中的代码:

# Base File Path for Uploading Files 
fileupload.basepath=C:/webApp

创建临时文件夹的代码

    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
public @ResponseBody
String upload(MultipartHttpServletRequest request,
        HttpServletResponse response) {

    // 0. notice, we have used MultipartHttpServletRequest

    // 1. get the files from the request object
    Iterator<String> itr = request.getFileNames();

    MultipartFile mpf = request.getFile(itr.next());

    if (!CommonUtil.isNull(mpf)) {
        if (mpf.getSize() > ProductCommonConstants.MAX_FILE_UPLOAD_SIZE_IN_BYTES) {
            return CommonConstants.STR_FAILURE;
        }

    }

    long fileName = Calendar.getInstance().getTimeInMillis();

    final String modelImageDirPath = baseUploadFilePath + "/"
            + CommonConstants.TEMP_FILE_NAME;

    // Check for folder existence
    final File modelImageDir = new File(modelImageDirPath);
    if (!modelImageDir.exists()) {
        // Create the directory
        modelImageDir.mkdirs();
    }

    InputStream is = null;
    FileOutputStream fos = null;

    try {
        String contentType = mpf.getContentType();

        if (contentType != null) {

            is = new DataInputStream(mpf.getInputStream());

            // just temporary save file info
            File file = new File(modelImageDirPath + "/" + fileName);

            fos = new FileOutputStream(file);

            // Write to the file
            IOUtils.copy(is, fos);
        }

    } catch (FileNotFoundException ex) {

    } catch (IOException ex) {

    } finally {

        try {
            if (fos != null) {
                fos.close();
            }
            if (is != null) {
                is.close();
            }
        } catch (IOException ignored) {
            // Log the Exception

        }
    }

    // 2. send it back to the client as <img> that calls get method
    // we are using getTimeInMillis to avoid server cached image

    return "/service/common/file/get/" + fileName;

}

}

【问题讨论】:

  • 您仍然可以使用相对路径而不是绝对路径来存储这些文件。但是,请注意,在您重新部署 Web 应用程序后,这些文件将被覆盖。如果要将这些文件存储在存储中,可以阅读 Azure Storage 的 java API。这是文档 - How to use Blob storage from JavaHow to use File Storage from Java
  • 如何获取上传的blob的路径?我想将文件的路径存储在数据库中。
  • 您说需要将路径存储在数据库中。这意味着您不希望您的文件被覆盖。 Blob 的路径可能如下所示:http://&lt;storage-account-name&gt;.blob.core.windows.net/&lt;container-name&gt;/&lt;blob-name&gt;。请阅读我上面提供的 2 篇文章。您可以在 Blob 存储和文件存储之间进行选择。 Blob 存储可以通过浏览器提供目录,这对图像有好处,而文件存储可以挂载在 VM 或云服务中。

标签: java spring azure azure-storage azure-web-app-service


【解决方案1】:

根据我的经验,您可以使用 Class CloudBlobupload(InputStream sourceStream, long length) 将文件从 Spring MVC MultipartFile 上传到 Azure Blob 存储,请参阅下面从您的代码修改的代码。

@RequestMapping(value = "/file/upload", method = RequestMethod.POST)
public @ResponseBody String upload(MultipartHttpServletRequest request,
        HttpServletResponse response) {
    // 0. notice, we have used MultipartHttpServletRequest
    // 1. get the files from the request object
    Iterator<String> itr = request.getFileNames();
    MultipartFile mpf = request.getFile(itr.next());
    if (!CommonUtil.isNull(mpf)) {
        if (mpf.getSize() > ProductCommonConstants.MAX_FILE_UPLOAD_SIZE_IN_BYTES) {
            return CommonConstants.STR_FAILURE;
        }
    }
    long fileName = Calendar.getInstance().getTimeInMillis();
    // Modified from your code: START
    String storageConnectionString = "DefaultEndpointsProtocol=http;" + "AccountName=your_storage_account;" + "AccountKey=your_storage_account_key";
    CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
    CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
    CloudBlobContainer container = blobClient.getContainerReference("<blob-container-name>");
    InputStream is = null;
    try {
        String contentType = mpf.getContentType();
        if (contentType != null) {
            is = new DataInputStream(mpf.getInputStream());
            long length = mpf.getSize();
            CloudBlockBlob blob = container.getBlockBlobReference(""+fileName);
            blob.upload(is, length);
        }
    // Modified from your code: END
    } catch (FileNotFoundException ex) {

    } catch (IOException ex) {

    } finally {
        try {
            if (is != null) {
                is.close();
            }
        } catch (IOException ignored) {
            // Log the Exception

        }
    }   
    // 2. send it back to the client as <img> that calls get method
    // we are using getTimeInMillis to avoid server cached image
    return "/service/common/file/get/" + fileName;
}

为了下载或引用blob,您需要将blob的容器名称和blob名称记录到数据库中。

OutputStream os = ...; // get the OutputStream from the HTTP Response
CloudBlobContainer container = blobClient.getContainerReference("<container-name>");
CloudBlob blob = getBlockBlobReference("<blob-name>");
blob.download(os)

有关更多信息,您可以参考 Class CloudBlob http://azure.github.io/azure-storage-java/com/microsoft/azure/storage/blob/CloudBlob.html 的 Javadoc 和 Blob Storage https://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-blob-storage/ 的入门文档。

【讨论】:

  • 谢谢.. 有没有办法将缓冲图像上传到 azure 存储?
  • @Nidhee 除了使用 Azure Storage SDK for Java,还可以直接使用 Java 中的Azure Storage REST APIs。但这不是必需的,因为 SDK 包装了这些 REST API。
  • @非常感谢彼得。正如你上面所说的引用 blob,你需要在数据库中记录容器和 blob 名称。但是对于我的本地网络应用程序,我提供了图像的路径并将其作为徽标显示。对于 Azure 网站,我也需要相同的功能。我尝试将 url 保存到数据库中的 blob 并引用它,但它没有发生。可以给点建议吗?
  • @Nidhee 尝试使用Get Blob的REST API,您可以尝试使用SDK通过函数getUri获取url并生成通过函数generateSharedAccessSignature获取的SAS用于所需的请求标头。
  • 谢谢。我提到了你的回答here。它有帮助,但我们可以让签名永不过期吗?
猜你喜欢
  • 2016-05-15
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
相关资源
最近更新 更多