首页 > 解决方案 > 如何在 vaadin 框架中实现 azure-storage

问题描述

我正在尝试将文件上传到 Azure Blob。我正在尝试通过 vaadin 框架中的 Upload 来实现。Vaadin 版本:6.7.8

我能够开发用于将文件上传到 azure blob 的代码。

我的问题陈述如下:

以下是 UploadToBlob.java 代码:

    package com.---.trs.scms.ui.components;

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.blob.CloudBlobContainer;

public class UploadToBlob {

    public static void main(String[] args) {

        try {

            final String storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=abcd;AccountKey=bmiA7+****==;EndpointSuffix=core.windows.net";
            System.out.println("---I am getting called Main-1 ");

            CloudStorageAccount storageAccount;

            storageAccount = CloudStorageAccount.parse(storageConnectionString);

            com.microsoft.azure.storage.blob.CloudBlobClient blobClient = storageAccount.createCloudBlobClient();

            CloudBlobContainer container = blobClient.getContainerReference("container2");

            container.createIfNotExists();

            String filePath = "C:\\Users\\----\\Desktop\\Timesheet - 19th Aug,2019.pdf";

            com.microsoft.azure.storage.blob.CloudBlockBlob blob = container.getBlockBlobReference("Timesheet.pdf");

            java.io.File source = new java.io.File(filePath);

            java.io.FileInputStream fileInputStream = new java.io.FileInputStream(source);

            blob.upload(fileInputStream, source.length());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

现在,我正在传递上面的手动文件 PATH 以在 azure blob 中上传,正如我上面所说的,这个类被调用直到代码行System.out.println("---I am getting called Main-1 ");

这是我调用 UploadToBlob.java 的 ModifyComplaintComponent 代码:

import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Upload;

public class ModifyComplaintComponent extends CustomComponent {


//other component  code which I haven't pasted here
    private Upload uploadnew;

    try {
            System.out.println("------Inside try block-----------");
            UploadToBlob fileReceiver= new UploadToBlob ();

            uploadnew = new Upload("Upload a file", fileReceiver);

            uploadnew.setReceiver(fileReceiver);
            uploadnew.addListener(fileReceiver);

            System.out.println("------end of try block-----------");
        }  catch (Exception e) {
            System.out.println("------catch block-----------");
            e.printStackTrace();

        } 

        HorizontalLayout hlayout = new HorizontalLayout();
        hlayout.setSpacing(true);
        hlayout.addComponent(uploadnew);

}

我在 UploadToBlob 代码中给出手动文件路径的原因是因为我首先想从 ModifyComplaintComponent 类调用此代码。

其次,当我尝试浏览文件时,文件被选中,但是当我点击上传时,我在 Vaadin Upload UI Part 上得到 NullPointerException,即使我选择了文件,UI 也会显示“未选择文件”

我面临的挑战是,如果我单独运行 Upload.java 文件,我可以将静态文件上传到 azure blob 中,但我想浏览 vaadin 框架中的文件并将其上传到 azure blob 存储中。

标签: javaazurevaadinazure-storageazure-blob-storage

解决方案


首先,Upload 是 Vaadin 的一个组件。您不应该创建自己的 Upload 类。

其次,public static main 方法是你的程序启动的入口。如果要使用类的方法,则需要显式调用它。

TheClassName.MethodName(...) // For static method
new TheClassName(...).MethodName(...) //For non-static method

第三,我做了一些测试,下面是一个成功的样本。将创建两个类:


类 UploadReceiver

这个类实现了 Receiver 接口和一些监听器。

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.vaadin.ui.Upload;
import org.springframework.stereotype.Component;

import java.io.OutputStream;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;

@Component
public class UploadReceiver implements Upload.Receiver, Upload.StartedListener, Upload.SucceededListener, Upload.ProgressListener {
    // Storage account connection string.
    public static String conn = "DefaultEndpointsProtocol=https;AccountName=stora***789;AccountKey=G3***w==;EndpointSuffix=core.windows.net";

    @Override
    public OutputStream receiveUpload(String filename, String mimeType) {
        System.out.println("Uploading -> " + mimeType + " ; File name -> " + filename);
        return GetOutputStream("vaadin",filename);
    }

    @Override
    public void uploadStarted(Upload.StartedEvent startedEvent) {
        System.out.println("Upload started!");
    }

    @Override
    public void uploadSucceeded(Upload.SucceededEvent succeededEvent) {
        System.out.println("Upload succeeded!");
    }


    public OutputStream GetOutputStream(String container, String blob){
        OutputStream outputStream = null;
        try{
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(conn);
            CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
            CloudBlobContainer blobContainer = blobClient.getContainerReference(container);
            CloudBlockBlob cloudBlockBlob = blobContainer.getBlockBlobReference(blob);
            outputStream = cloudBlockBlob.openOutputStream();
        } catch (StorageException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return outputStream;
    }

    @Override
    public void updateProgress(long readBytes, long contentLength) {
        System.out.println("Progress: readBytes -> " + readBytes + " ; contentLength -> " + contentLength);
    }
}

类 MainUI

这是用户界面页面。我只是添加了一个上传组件。

import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.UI;
import com.vaadin.ui.Upload;
import com.vaadin.ui.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired;

@SpringUI
public class MainUI extends UI {

    private VerticalLayout layout;
    private Upload upload;

    private UploadReceiver uploadReceiver;

    @Autowired
    public MainUI(UploadReceiver uploadReceiver){
        this.uploadReceiver = uploadReceiver;
    }

    @Override
    protected void init(VaadinRequest vaadinRequest) {

        // Set layout
        layout = new VerticalLayout();
        layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
        setContent(layout);


        // Add upload
        upload = new Upload("Upload a file", uploadReceiver);
        upload.addStartedListener(uploadReceiver);
        upload.addSucceededListener(uploadReceiver);
        upload.addProgressListener(uploadReceiver);
        layout.addComponent(upload);
    }
}

结果: 单击上传按钮并选择要上传的文件后,我可以从控制台获得以下输出:

在此处输入图像描述

而且,通过使用 Storage Explorer 检查存储帐户,我可以看到文件已成功上传: 在此处输入图像描述


更新:

这是上传的工作方式:

在此处输入图像描述

我不知道你的代码是如何通过编译的。要构造一个 Upload 对象,您需要传递一个标题字符串和一个实现 Upload.Receiver 接口的接收器。

public Upload(String caption, Receiver uploadReceiver)

而要实现 Upload.Receiver 接口,您必须重写 receiveUpload 方法。

OutputStream receiveUpload(String filename, String mimeType)

receiveUpload 将返回一个输出流,vaadin 最终将向其中写入内容。

就这样。给 vaadin 一个输出流,它会将所有内容写入流。

输入文件从您的浏览器发送并由 vaadin 处理。我没有找到在 vaadin 中手动设置输入内容的方法。对不起。


推荐阅读