java - 通过谷歌云端点通过 Android 客户端将文件上传到谷歌云存储

标签 java android google-app-engine google-cloud-storage google-cloud-endpoints

我需要使用 google 云端点将文件上传到 google 云存储并打印回该文件的 url。

我不想运行一个独立的 servlet 来处理文件上传。

服务器代码如下:

import java.io.File;

public void saveFile(File upload,User auth) throws IOException {
            if (auth!=null){
                String bucketName = "app-id.appspot.com";

            GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
                    .initialRetryDelayMillis(10)
                    .retryMaxAttempts(10)
                    .totalRetryPeriodMillis(15000)
                    .build());

            String sname = upload.getName();
            String extension = sname.substring(sname.lastIndexOf('.'),sname.length());

            String sctype =  URLConnection.guessContentTypeFromName(upload.getName());

            String filename;
            filename = String.valueOf(Calendar.getInstance().getTimeInMillis()) + extension;

            GcsFilename gcsfileName = new GcsFilename(bucketName, filename);

            GcsFileOptions options = new GcsFileOptions.Builder()
                    .acl("public-read").mimeType(sctype).build();

            GcsOutputChannel outputChannel =
                    gcsService.createOrReplace(gcsfileName, options);

            InputStream stream = new FileInputStream(upload);

            copy(stream, Channels.newOutputStream(outputChannel));
        }
    }

    private static final int BUFFER_SIZE = 2 * 1024 * 1024;

    private void copy(InputStream input, OutputStream output) throws IOException {
        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = input.read(buffer);
            while (bytesRead != -1) {
                output.write(buffer, 0, bytesRead);
                bytesRead = input.read(buffer);
            }
        } finally {
            input.close();
            output.close();
        }
    }

但是当我重建项目时,导入的 java.io.File 在生成的客户端库中被转换为 com.backend.managerApi.model.File

那么,有没有办法做到这一点,或者我们只需要运行一个独立的 servlet 来处理上传?

最佳答案

以防万一,如果有人希望 Servlet 代码做同样的事情:

import com.google.appengine.tools.cloudstorage.GcsFileOptions;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.appengine.tools.cloudstorage.GcsOutputChannel;
import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.util.Calendar;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UploadServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(UploadServlet.class.getName());

    private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
            .initialRetryDelayMillis(10)
            .retryMaxAttempts(10)
            .totalRetryPeriodMillis(15000)
            .build());

    private String bucketName = "app-id.appspot.com";

    /**Used below to determine the size of chucks to read in. Should be > 1kb and < 10MB */
    private static final int BUFFER_SIZE = 2 * 1024 * 1024;

    @SuppressWarnings("unchecked")
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

        String sctype = null, sfieldname, sname = null;
        ServletFileUpload upload;
        FileItemIterator iterator;
        FileItemStream item;
        InputStream stream = null;
        try {
            upload = new ServletFileUpload();
            res.setContentType("text/plain");

            iterator = upload.getItemIterator(req);
            while (iterator.hasNext()) {
                item = iterator.next();
                stream = item.openStream();

                if (item.isFormField()) {
                    log.warning("Got a form field: " + item.getFieldName());
                } else {
                    log.warning("Got an uploaded file: " + item.getFieldName() +
                            ", name = " + item.getName());

                    //sfieldname = item.getFieldName();

                    sname = item.getName();
                    String extension = sname.substring(sname.lastIndexOf('.'),sname.length());

                    sctype = item.getContentType();

                    String filename;
                    filename = String.valueOf(Calendar.getInstance().getTimeInMillis()) + extension;

                    GcsFilename gcsfileName = new GcsFilename(bucketName, filename);

                    GcsFileOptions options = new GcsFileOptions.Builder()
                            .acl("public-read").mimeType(sctype).build();

                    GcsOutputChannel outputChannel =
                            gcsService.createOrReplace(gcsfileName, options);

                    copy(stream, Channels.newOutputStream(outputChannel));

                    //res.sendRedirect("/");
                    res.getWriter().print(filename);
                }
            }
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }

    private void copy(InputStream input, OutputStream output) throws IOException {
        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = input.read(buffer);
            while (bytesRead != -1) {
                output.write(buffer, 0, bytesRead);
                bytesRead = input.read(buffer);
            }
        } finally {
            input.close();
            output.close();
        }
    }

}

然后像这样点击 servlet :

curl -F file=@"picture.jpg"http://myAppEngineProj.appspot.com/myServlet

关于java - 通过谷歌云端点通过 Android 客户端将文件上传到谷歌云存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30811328/

相关文章:

node.js - Winston 未在 Google Cloud Compute Engine 上托管的 Node.js 应用程序的生产版本中记录事件

java - 将 Log4net 与 Google App Engine 后端结合使用

java - Java中是否可以通过反射在新进程中调用main方法

java - Java 的 JIT 编译器运行速度有多快?

android - 当我按下onClick Android时按钮会缩小

android - FirebaseAuth和FirebaseUser类的uid属性有什么区别?

java - 使用 Eclipse 进行调试时,跟踪空指针异常的最佳方法是什么?

java - 使用 ServerSocket 的 SWING 应用程序

java - EditText 到 String 返回 Null

python - 使用 Python 灵活环境在 virtualenv 中包含 Google Cloud SDK