javascript - 从 Google App Engine (Java) 上传文件到 Google 云存储

标签 javascript java google-app-engine servlets google-cloud-storage

如何将文件从谷歌应用引擎中的 servlet 上传到谷歌云存储?

当我这样做时,谷歌云存储不知道文件的类型,我从 HTML 表单发送的文件。编写 HTML/JavaScript 和 servlet 以将文件上传到云存储的正确方法是什么?

最佳答案

下面是来自 Google 的代码示例,用于使用 JavaScript 与云存储进行交互。它的作用远不止上传,即您可以下载、创建新存储桶等。下面我添加了我用来上传的函数,该函数派生自该示例。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset='utf-8' />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script src="https://apis.google.com/js/client.js"></script>
    <script type="text/javascript">
        /**
         * The Project ID of your Google Cloud Storage Project.
         */
        var PROJECT = 'abcd';
        /**
         * Enter a client ID for a web application from the Google Developers
         * Console on the "APIs & auth", "Credentials" page.
         * In your Developers Console project add a JavaScript origin
         * that corresponds to the domain from where you will be running the
         * script. For more info see:
         * https://developers.google.com/console/help/new/#generatingoauth2
         */
        var clientId = '701111116470-55bj2lkjlkkjkljhe97di22gus5hs3.apps.googleusercontent.com';
        /**
         * Enter the API key from the Google Developers Console, by following these
         * steps:
         * 1) Visit https://cloud.google.com/console and select your project
         * 2) Click on "APIs & auth" in the left column and then click “Credentials”
         * 3) Find section "Public API Access" and use the "API key." If sample is
         * being run on localhost then delete all "Referers" and save. Setting
         * should display "Any referer allowed." For more info see:
         * https://developers.google.com/console/help/new/#generatingdevkeys
         */
        var apiKey = 'JHJhhguy8786875hghgjbS0nYjcMY';
        /**
         * To enter one or more authentication scopes, refer to the documentation
         * for the API.
         */
        var scopes = 'https://www.googleapis.com/auth/devstorage.full_control';
        /**
         * Constants for request parameters. Fill these values in with your custom
         * information.
         */
        var API_VERSION = 'v1';
        /**
         * Enter a unique bucket name to create a new bucket. The guidelines for
         * bucket naming can be found here:
         * https://developers.google.com/storage/docs/bucketnaming
         */
        //var BUCKET = 'code-sample-bucket-' + Date.now();
        var BUCKET = 'testbucket';
        /**
         * The name of the object inserted via insertObject method.
         */
        var object = "";
        /**
         * Get this value from the Developers Console. Click on the
         * “Cloud Storage” service in the Left column and then select
         * “Project Dashboard”. Use one of the Google Cloud Storage group IDs
         * listed and combine with the prefix “group-” to get a string
         * like the example below.
         */
        var GROUP =
                'group-kjhHJKHJKH897897878jgjghg8728f21c3ff22597efbfc63ccdb8f2294d8fd2561cb9';
        /**
         * Valid values are user-userId, user-email, group-groupId, group-email,
         * allUsers, allAuthenticatedUsers
         */
        var ENTITY = 'allUsers';
        /**
         * Valid values are READER, OWNER
         */
        var ROLE = 'READER';
        /**
         * Valid values are READER, OWNER
         */
        var ROLE_OBJECT = 'READER';
        /**
         * A list of example calls to the Google Cloud Storage JavaScript client
         * library, as well as associated explanations of each call.
         */
        var listApiRequestExplanations = {
            'listBuckets': 'This API call queries the Google Cloud Storage API ' +
            'for a list of buckets in your project, and returns the result as ' +
            'a list of Google Cloud Storage buckets.',
            'listObjects': 'This API call queries the Google Cloud Storage API ' +
            'for a list of objects in your bucket, and returns the result as ' +
            'a list of Google Cloud Storage objects.',
            'listBucketsAccessControls': 'This API call queries the Google Cloud ' +
            'Storage API for the list of access control lists on buckets in your ' +
            'project and returns the result as a list of Google Cloud Storage ' +
            'Access Control Lists.',
            'listObjectsAccessControls': 'This API call queries the Google Cloud ' +
            'Storage API for the list of access control lists on objects in your ' +
            'bucket and returns the result as a list of Google Cloud Storage ' +
            'Access Control Lists.',
            'getBucket': 'This API call queries the Google Cloud Storage API ' +
            'for a bucket in your project, and returns the result as a ' +
            'Google Cloud Storage bucket.',
            'getBucketAccessControls': 'This API call queries the Google Cloud ' +
            'Storage API for the access control list on a specific bucket ' +
            'and returns the result as a Google Cloud Storage Access Control List.',
            'getObjectAccessControls': 'This API call queries the Google Cloud ' +
            'Storage API for the access control list on a specific object ' +
            'and returns the result as a Google Cloud Storage Access Control List.',
            'insertBucket': 'This API call uses the Google Cloud Storage API ' +
            'to insert a bucket into your project.',
            'insertObject': 'This API call uses the Google Cloud Storage API ' +
            'to insert an object into your bucket.',
            'insertBucketAccessControls': 'This API uses the Google Cloud ' +
            'Storage API to insert an access control list on a specific bucket ' +
            'and returns the result as a Google Cloud Storage Access Control List.',
            'insertObjectAccessControls': 'This API uses the Google Cloud ' +
            'Storage API to insert an access control list on a specific object ' +
            'and returns the result as a Google Cloud Storage Access Control List.',
            'deleteBucket': 'This API uses the Google Cloud Storage API to delete ' +
            'an empty bucket and returns an empty response to indicate success.',
            'deleteObject': 'This API uses the Google Cloud Storage API to delete ' +
            'an object and returns an empty response to indicate success.'
        };
        /**
         * Google Cloud Storage API request to retrieve the list of buckets in
         * your Google Cloud Storage project.
         */
        function listBuckets() {
            var request = gapi.client.storage.buckets.list({
                'project': PROJECT
            });
            executeRequest(request, 'listBuckets');
        }
        /**
         * Google Cloud Storage API request to retrieve the list of objects in
         * your Google Cloud Storage project.
         */
        function listObjects() {
            var request = gapi.client.storage.objects.list({
                'bucket': BUCKET
            });
            executeRequest(request, 'listObjects');
        }
        /**
         * Google Cloud Storage API request to retrieve the access control list on
         * a bucket in your Google Cloud Storage project.
         */
        function listBucketsAccessControls() {
            var request = gapi.client.storage.bucketAccessControls.list({
                'bucket': BUCKET
            });
            executeRequest(request, 'listBucketsAccessControls');
        }
        /**
         * Google Cloud Storage API request to retrieve the access control list on
         * an object in your Google Cloud Storage project.
         */
        function listObjectsAccessControls() {
            var request = gapi.client.storage.objectAccessControls.list({
                'bucket': BUCKET,
                'object': object
            });
            executeRequest(request, 'listObjectsAccessControls');
        }
        /**
         * Google Cloud Storage API request to retrieve a bucket in
         * your Google Cloud Storage project.
         */
        function getBucket() {
            var request = gapi.client.storage.buckets.get({
                'bucket': BUCKET
            });
            executeRequest(request, 'getBucket');
        }
        /**
         * Google Cloud Storage API request to retrieve a bucket's Access Control
         * List in your Google Cloud Storage project.
         */
        function getBucketAccessControls() {
            var request = gapi.client.storage.bucketAccessControls.get({
                'bucket': BUCKET,
                'entity': GROUP
            });
            executeRequest(request, 'getBucketAccessControls');
        }
        /**
         * Google Cloud Storage API request to retrieve an object's Access Control
         * List in your Google Cloud Storage project.
         */
        function getObjectAccessControls() {
            var request = gapi.client.storage.objectAccessControls.get({
                'bucket': BUCKET,
                'object': object,
                'entity': GROUP
            });
            executeRequest(request, 'getObjectAccessControls');
        }
        /**
         * Google Cloud Storage API request to insert a bucket into
         * your Google Cloud Storage project.
         */
        function insertBucket() {
            resource = {
                'name': BUCKET
            };
            var request = gapi.client.storage.buckets.insert({
                'project': PROJECT,
                'resource': resource
            });
            executeRequest(request, 'insertBucket');
        }
        /**
         * Google Cloud Storage API request to insert an object into
         * your Google Cloud Storage bucket.
         */
        function insertObject(event) {
            try{
                var fileData = event.target.files[0];
            }
            catch(e) {
                //'Insert Object' selected from the API Commands select list
                //Display insert object button and then exit function
                filePicker.style.display = 'block';
                return;
            }
            const boundary = '-------314159265358979323846';
            const delimiter = "\r\n--" + boundary + "\r\n";
            const close_delim = "\r\n--" + boundary + "--";
            var reader = new FileReader();
            reader.readAsBinaryString(fileData);
            reader.onload = function(e) {
                var contentType = fileData.type || 'application/octet-stream';
                var metadata = {
                    'name': fileData.name,
                    'mimeType': contentType
                };
                var base64Data = btoa(reader.result);
                var multipartRequestBody =
                        delimiter +
                        'Content-Type: application/json\r\n\r\n' +
                        JSON.stringify(metadata) +
                        delimiter +
                        'Content-Type: ' + contentType + '\r\n' +
                        'Content-Transfer-Encoding: base64\r\n' +
                        '\r\n' +
                        base64Data +
                        close_delim;
                //Note: gapi.client.storage.objects.insert() can only insert
                //small objects (under 64k) so to support larger file sizes
                //we're using the generic HTTP request method gapi.client.request()
                var request = gapi.client.request({
                    'path': '/upload/storage/' + API_VERSION + '/b/' + BUCKET + '/o',
                    'method': 'POST',
                    'params': {'uploadType': 'multipart'},
                    'headers': {
                        'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                    },
                    'body': multipartRequestBody});
                //Remove the current API result entry in the main-content div
                listChildren = document.getElementById('main-content').childNodes;
                if (listChildren.length > 1) {
                    listChildren[1].parentNode.removeChild(listChildren[1]);
                }
                try{
                    //Execute the insert object request
                    executeRequest(request, 'insertObject');
                    //Store the name of the inserted object
                    object = fileData.name;
                }
                catch(e) {
                    alert('An error has occurred: ' + e.message);
                }
            }
        }
        /**
         * Google Cloud Storage API request to insert an Access Control List into
         * your Google Cloud Storage bucket.
         */
        function insertBucketAccessControls() {
            resource = {
                'entity': ENTITY,
                'role': ROLE
            };
            var request = gapi.client.storage.bucketAccessControls.insert({
                'bucket': BUCKET,
                'resource': resource
            });
            executeRequest(request, 'insertBucketAccessControls');
        }
        /**
         * Google Cloud Storage API request to insert an Access Control List into
         * your Google Cloud Storage object.
         */
        function insertObjectAccessControls() {
            resource = {
                'entity': ENTITY,
                'role': ROLE_OBJECT
            };
            var request = gapi.client.storage.objectAccessControls.insert({
                'bucket': BUCKET,
                'object': object,
                'resource': resource
            });
            executeRequest(request, 'insertObjectAccessControls');
        }
        /**
         * Google Cloud Storage API request to delete a Google Cloud Storage bucket.
         */
        function deleteBucket() {
            var request = gapi.client.storage.buckets.delete({
                'bucket': BUCKET
            });
            executeRequest(request, 'deleteBucket');
        }
        /**
         * Google Cloud Storage API request to delete a Google Cloud Storage object.
         */
        function deleteObject() {
            var request = gapi.client.storage.objects.delete({
                'bucket': BUCKET,
                'object': object
            });
            executeRequest(request, 'deleteObject');
        }
        /**
         * Removes the current API result entry in the main-content div, adds the
         * results of the entry for your function.
         * @param {string} apiRequestName The name of the example API request.
         */
        function updateApiResultEntry(apiRequestName) {
            listChildren = document.getElementById('main-content')
                    .childNodes;
            if (listChildren.length > 1) {
                listChildren[1].parentNode.removeChild(listChildren[1]);
            }
            if (apiRequestName != 'null') {
                window[apiRequestName].apply(this);
            }
        }
        /**
         * Determines which API request has been selected, and makes a call to add
         * its result entry.
         */
        function runSelectedApiRequest() {
            var curElement = document.getElementById('api-selection-options');
            var apiRequestName = curElement.options[curElement.selectedIndex].value;
            updateApiResultEntry(apiRequestName);
        }
        /**
         * Binds event listeners to handle a newly selected API request.
         */
        function addSelectionSwitchingListeners() {
            document.getElementById('api-selection-options')
                    .addEventListener('change',
                    runSelectedApiRequest, false);
        }
        /**
         * Template for getting JavaScript sample code snippets.
         * @param {string} method The name of the Google Cloud Storage request
         * @param {string} params The parameters passed to method
         */
        function getCodeSnippet(method, params) {
            var objConstruction = "// Declare your parameter object\n";
            objConstruction += "var params = {};";
            objConstruction += "\n\n";
            var param = "// Initialize your parameters \n";
            for (i in params) {
                param += "params['" + i + "'] = ";
                param += JSON.stringify(params[i], null, '\t');
                param += ";";
                param += "\n";
            }
            param += "\n";
            var methodCall = "// Make a request to the Google Cloud Storage API \n";
            methodCall += "var request = gapi.client." + method + "(params);";
            return objConstruction + param + methodCall;
        }
        /**
         * Executes your Google Cloud Storage request object and, subsequently,
         * inserts the response into the page.
         * @param {string} request A Google Cloud Storage request object issued
         *    from the Google Cloud Storage JavaScript client library.
         * @param {string} apiRequestName The name of the example API request.
         */
        function executeRequest(request, apiRequestName) {
            request.execute(function(resp) {
                console.log(resp);
                var apiRequestNode = document.createElement('div');
                apiRequestNode.id = apiRequestName;
                var apiRequestNodeHeader = document.createElement('h2');
                apiRequestNodeHeader.innerHTML = apiRequestName;
                var apiRequestExplanationNode = document.createElement('div');
                apiRequestExplanationNode.id = apiRequestName + 'RequestExplanation';
                var apiRequestExplanationNodeHeader = document.createElement('h3');
                apiRequestExplanationNodeHeader.innerHTML = 'API Request Explanation';
                apiRequestExplanationNode.appendChild(apiRequestExplanationNodeHeader);
                var apiRequestExplanationEntry = document.createElement('p');
                apiRequestExplanationEntry.innerHTML =
                        listApiRequestExplanations[apiRequestName];
                apiRequestExplanationNode.appendChild(apiRequestExplanationEntry);
                apiRequestNode.appendChild(apiRequestNodeHeader);
                apiRequestNode.appendChild(apiRequestExplanationNode);
                var apiRequestCodeSnippetNode = document.createElement('div');
                apiRequestCodeSnippetNode.id = apiRequestName + 'CodeSnippet';
                var apiRequestCodeSnippetHeader = document.createElement('h3');
                apiRequestCodeSnippetHeader.innerHTML = 'API Request Code Snippet';
                apiRequestCodeSnippetNode.appendChild(apiRequestCodeSnippetHeader);
                var apiRequestCodeSnippetEntry = document.createElement('pre');
                //If the selected API command is not 'insertObject', pass the request
                //paramaters to the getCodeSnippet method call as 'request.wc.wc.params'
                //else pass request paramaters as 'request.wc.wc'


/*                if (apiRequestName != 'insertObject') {
                    apiRequestCodeSnippetEntry.innerHTML =
                            getCodeSnippet(request.wc.wc.method, request.wc.wc.params);
                    //Selected API Command is not 'insertObject'
                    //hide insert object button
                    filePicker.style.display = 'none';
                } else {
                    apiRequestCodeSnippetEntry.innerHTML =
                            getCodeSnippet(request.wc.wc.method, request.wc.wc);
                }*/


                apiRequestCodeSnippetNode.appendChild(apiRequestCodeSnippetEntry);
                apiRequestNode.appendChild(apiRequestCodeSnippetNode);
                var apiResponseNode = document.createElement('div');
                apiResponseNode.id = apiRequestName + 'Response';
                var apiResponseHeader = document.createElement('h3');
                apiResponseHeader.innerHTML = 'API Response';
                apiResponseNode.appendChild(apiResponseHeader);
                var apiResponseEntry = document.createElement('pre');
                apiResponseEntry.innerHTML = JSON.stringify(resp, null, ' ');
                apiResponseNode.appendChild(apiResponseEntry);
                apiRequestNode.appendChild(apiResponseNode);
                var content = document.getElementById('main-content');
                content.appendChild(apiRequestNode);
            });
        }
        /**
         * Set required API keys and check authentication status.
         */
        function handleClientLoad() {
            gapi.client.setApiKey(apiKey);
            window.setTimeout(checkAuth, 1);
        }
        /**
         * Authorize Google Cloud Storage API.
         */
        function checkAuth() {
            gapi.auth.authorize({
                client_id: clientId,
                scope: scopes,
                immediate: true
            }, handleAuthResult);
        }
        /**
         * Handle authorization.
         */
        function handleAuthResult(authResult) {
            var authorizeButton = document.getElementById('authorize-button');
            if (authResult && !authResult.error) {
                authorizeButton.style.visibility = 'hidden';
                initializeApi();
                filePicker.onchange = insertObject;
            } else {
                authorizeButton.style.visibility = '';
                authorizeButton.onclick = handleAuthClick;
            }
        }
        /**
         * Handle authorization click event.
         */
        function handleAuthClick(event) {
            gapi.auth.authorize({
                client_id: clientId,
                scope: scopes,
                immediate: false
            }, handleAuthResult);
            return false;
        }
        /**
         * Load the Google Cloud Storage API.
         */
        function initializeApi() {
            gapi.client.load('storage', API_VERSION);
        }
        /**
         * Driver for sample application.
         */
        $(window)
                .bind('load', function() {
                    addSelectionSwitchingListeners();
                    handleClientLoad();
                });
    </script>
</head>
<body>
<!--Add a button for the user to click to initiate auth sequence -->
<button id="authorize-button" style="visibility: hidden">Authorize</button>
<header>
    <h1>Google Cloud Storage JavaScript Client Library Application</h1>
</header>
<label id="api-label">Try a sample API call!</label>
<select id="api-selection-options">
    <option value="null">
        Please select an example API call from the dropdown menu
    </option>
    <option value="listBuckets">
        List Buckets
    </option>
    <option value="insertBucket">
        Insert Bucket
    </option>
    <option value="getBucket">
        Get Bucket
    </option>
    <option value="getBucketAccessControls">
        Get Bucket Access Controls
    </option>
    <option value="insertBucketAccessControls">
        Insert Bucket Access Controls
    </option>
    <option value="listBucketsAccessControls">
        List Buckets Access Control List
    </option>
    <option value="insertObject">
        Insert Object
    </option>
    <option value="listObjects">
        List Objects
    </option>
    <option value="getObjectAccessControls">
        Get Object Access Controls
    </option>
    <option value="insertObjectAccessControls">
        Insert Object Access Controls
    </option>
    <option value="listObjectsAccessControls">
        List Objects Access Control List
    </option>
    <option value="deleteObject">
        Delete Object
    </option>
    <option value="deleteBucket">
        Delete Bucket
    </option>
</select>
<br/>
<input type="file" id="filePicker" style="display: none" />
<div id="main-content">
</div>
</body>
</html>

Below is the function to upload a file, fully inspired from the example above. Note that it uses the JavaScript client library to interact with Google API (gapi), which means that you can secure the upload with authentication via google accounts (https://developers.google.com/api-client-library/javascript/start/start-js).

function uploadFile(fileData, bucket) {
    var boundary = '-------314159265358979323846';
    var delimiter = "\r\n--" + boundary + "\r\n";
    var close_delim = "\r\n--" + boundary + "--";
    var reader = new FileReader();
    reader.readAsBinaryString(fileData);

    reader.onload = function (e) {
        var contentType = fileData.type || 'application/octet-stream';
        var metadata = {
            'name': fileData.name,
            'mimeType': contentType
        };
        var base64Data = btoa(reader.result);
        var multipartRequestBody =
                delimiter +
                'Content-Type: application/json\r\n\r\n' +
                JSON.stringify(metadata) +
                delimiter +
                'Content-Type: ' + contentType + '\r\n' +
                'Content-Transfer-Encoding: base64\r\n' +
                '\r\n' +
                base64Data +
                close_delim;

        var request = gapi.client.request({
            'path': '/upload/storage/v1/b/' + bucket + '/o',
            'method': 'POST',
            'params': {'uploadType': 'multipart'},
            'headers': {
                'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
            },
            'body': multipartRequestBody
        });

        try {
            request.execute(function (resp) {
                if (resp.hasOwnProperty("error")) {
                    //Treat Error
                } else {
                    //Treat Success
                }
            });
        }
        catch (e) {
            //Treat Error
        }

    };

}

最后,您可以使用云存储的对象更改通知来调用应用引擎中的任务。您可以传递存储桶和文件名,并处理刚刚通过 App Engine 上传的文件。 https://cloud.google.com/storage/docs/object-change-notification

关于javascript - 从 Google App Engine (Java) 上传文件到 Google 云存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41220348/

相关文章:

java - 通过 Windows 拖放启动 Java 类

java - Spring GAE/J Could Not find API 版本错误

python - 确定数据存储中存在一组键中的哪一个的最佳方法

javascript - 在 Bootstrap Accordion 面板中预期之前触发 Mouseout

javascript - call()函数与调用继承类的隐式构造函数的区别

javascript - 从 ASP.NET 中的操作方法检索 Json 对象

java - 获取文件的第二个元素

java - Sprint启动kafka Consumer无法连接到kafka容器

google-app-engine - 在 Google App Engine Python 3 上将游标传递给 ndb 会导致错误

javascript - 如何使 HTML Canvas 可点击网格(返回单元格以匹配数组元素?)