BLOB-объект создан, но файл не загружен с помощью SignedURL - PullRequest
0 голосов
/ 25 октября 2018

Я использую SignedURL для загрузки файла напрямую в облачное хранилище, не просматривая экземпляры App Engine.Процесс, который я выполняю:

  1. Создание пустого объекта и создание SignedURL для этого объекта

    Storage storage = null;
    
    try{
    
    FileInputStream credentialsStream = new FileInputStream("JSONFile");
    
    Credentials credentials = GoogleCredentials.fromStream(credentialsStream);
    
    storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
    
    }catch(IOException e) {
    
      e.printStackTrace();
    
    }
    
    Acl aclObject = Acl.of(User.ofAllUsers(),Role.OWNER);
    
    List<Acl> aclAccess = new ArrayList<>();
    
    aclAccess.add(aclObject);
    
    //BucketName and User name are Strings.
    BlobId blobId = BlobId.of(BUCKET_NAME,USER_NAME+"TeamLogo");
    
    BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setAcl(aclAccess).setContentType("image/jpeg").build();
    
    Blob blob = storage.create(blobInfo); 
    

На данный момент, пустойОбъект создан в облачном хранилище

Object created in Cloud Storage

Я создаю подписанный URL для этого пустого объекта таким образом, что при загрузке пользователем файла его содержимое заменяетсяпустой объект

    HttpMethod httpMethod = HttpMethod.PUT;

    ServiceAccountSigner signer = ServiceAccountCredentials.newBuilder().setClientId(CLIENT_ID).setClientEmail(CLIENT_EMAIL).setPrivateKey(PRIVATEKEY).setPrivateKeyId(PRIVATE_KEY_ID).build()

    URL url = blob.signUrl(10,TimeUnit.MINUTES,Storage.SignUrlOption.httpMethod(httpMethod),Storage.SignUrlOption.signWith(signer),Storage.SignUrlOption.withContentType());
    return url;

Мой HTML-код для обработки загрузки файла

<form action="${signedURL}" method="put" enctype="multipart/form-data">
 <label>Enter Your User Name</label><br>
<input type="text" name="UserName" ><br><br>
<label>Enter Your Team Name</label><br>
<input type="text" name="TeamName" ><br><br>
<label>Upload Team Logo</label><br>
<input type="file" name="myFile" required="required"><br><br>
<input type="submit" value="Create Team">
<input type="hidden" name="success_action_redirect" value="http://localhost:8080/register">
</form>

После выбора файла и нажатия кнопки «Загрузить» выбранный файл не загружается в облачное хранилище и загружает эту страницу (белую страницу с URL-адресом).

Output Image

Я не достигаю желаемого результата.Что мне не хватает в моем кодексе?Документация Java для облачного хранилища не предлагает полную картину для новичков, как я.Кто-то, пожалуйста, помогите мне в этом отношении.

ОБНОВЛЕНИЕ: Javascript AJAX-запрос к облачному хранилищу

var signedURL;
function uploadFile(){
    var urlxhr = new XMLHttpRequest();
    //To get the SignedURL from server side
    urlxhr.open('GET','http://localhost:8080/getsignedurl')
    urlxhr.send();
    urlxhr.onreadystatechange = function(){
        if (urlxhr.readyState == 4 && urlxhr.status == 200) {	
            signedURL = urlxhr.responseText;
            var file = document.getElementById("myFile").files[0]
            var formData = new FormData();
            formData.append('imageFile',file);
            var storageXhr = new XMLHttpRequest();
            storageXhr.open('PUT',signedURL,true);
            storageXhr.onload = () => {
                if(storageXhr.status == 200){
                    alert("File Successfully Uploaded");
                }else{
                    alert("Something went Wrong");
                }
            };
            storageXhr.onerror = () => {
                alert("An Error occured while Uploading file");
            };
            storageXhr.setRequestHeader('Content-Type',file.type);
            storageXhr.send(formData);
        }
    }

    


}
<!-- Uploading Directly to Cloud storage by AJAX Request -->
<form action="#" method="put" onsubmit="uploadFile()">
<label>Select Your Team Logo</label>
<input type="file" id="myFile" required="required">
<input type="submit" value="Upload File">
</form>
</div>

1 Ответ

0 голосов
/ 25 октября 2018

Похоже, вы пытаетесь использовать команду POST Object , но используете команду PUT Object .Например, вы используете success_action_redirect, что только для команды объекта POST.Команда PUT Object не принимает данные формы таким способом.

Вы можете использовать команду объекта PUT с подписанным URL-адресом, но не таким способом.Вместо этого вы должны использовать JavaScript для выгрузки содержимого файла.

Команда объекта POST - это та команда, которая вам нужна, если вы планируете использовать форму HTML.Правила подписания этих запросов несколько иные.Ознакомьтесь с разделом «документ политики» документации: https://cloud.google.com/storage/docs/xml-api/post-object#usage_and_examples

Итак, чтобы изменить приведенный выше пример, переключите метод на POST, добавьте поле policy и поле Signature, котороесоздается сервером так же, как вы сейчас подписываете свои запросы и переключаете действие на 'https://storage.googleapis.com/bucket_name'.

...