【问题标题】:How to upload and store an image with google app engine (java)如何使用谷歌应用引擎(java)上传和存储图像
【发布时间】:2010-12-03 13:43:03
【问题描述】:

我正在寻找将图像(文件)上传和存储到 GAE (java) 的最简单方法。 谷歌搜索了几个小时,没有任何简单明了的结果。

找到this link

但我仍然不知道如何存储图像,以及如何检索它。 我正在寻找简单的 servlet 示例。

【问题讨论】:

    标签: java google-app-engine image-uploading


    【解决方案1】:

    使用blobstore API

    Blobstore API 允许您的应用程序提供数据对象,称为 blob,它比数据存储服务中允许的对象大小大得多。 Blob 对于提供大文件(例如视频或图像文件)以及允许用户上传大数据文件非常有用。 Blob 是通过 HTTP 请求上传文件来创建的。通常,您的应用程序将通过向用户显示带有文件上传字段的表单来完成此操作。提交表单后,Blobstore 会根据文件内容创建一个 blob,并返回对该 blob 的不透明引用,称为 blob 键,您以后可以使用它来提供该 blob。应用程序可以响应用户请求提供完整的 blob 值,或者它可以使用类似流文件的接口直接读取该值...

    【讨论】:

    【解决方案2】:

    使用 Google App Engine Blob Store 服务 URL 的最简单方法(节省实例时间)

    import com.google.appengine.api.files.FileService;
    import com.google.appengine.api.files.AppEngineFile;
    import com.google.appengine.api.files.FileWriteChannel;
    import com.google.appengine.api.blobstore.BlobKey;
    import com.google.appengine.api.images.ImagesServiceFactory;
    import com.google.appengine.api.images.ServingUrlOptions;
    ...
    
    
    // your data in byte[] format
    byte[] data = image.getData();
    /**
     *  MIME Type for
     *  JPG use "image/jpeg" for PNG use "image/png"
     *  PDF use "application/pdf"
     *  see more: https://en.wikipedia.org/wiki/Internet_media_type
     */
    String mimeType = "image/jpeg";
    
    // save data to Google App Engine Blobstore 
    FileService fileService = FileServiceFactory.getFileService();
    AppEngineFile file = fileService.createNewBlobFile(mimeType); 
    FileWriteChannel writeChannel = fileService.openWriteChannel(file, true);
    writeChannel.write(java.nio.ByteBuffer.wrap(data));
    writeChannel.closeFinally();
    
    // your blobKey to your data in Google App Engine BlobStore
    BlobKey blobKey = fileService.getBlobKey(file);
    
    // THANKS TO BLOBKEY YOU CAN GET FOR EXAMPLE SERVING URL FOR IMAGES
    
    // Get the image serving URL (in https:// format)
    String imageUrl =
      ImagesServiceFactory.getImagesService().getServingUrl(
        ServingUrlOptions.Builder.withBlobKey(blobKey
              ).secureUrl(true));
    

    【讨论】:

    【解决方案3】:

    您提供的链接"How do I handle file uploads to my app?" 说明了如何上传图片。

    要托管图像,您需要使用Datastore service 来存储和提供图像以及其他数据。

    这是一个示例代码。它是一个草图,用于说明如何让自己的实体(例如企业、用户等)拥有一个图像字段。为了简化代码,我忽略了所有错误处理和恢复。

    用图片声明你的实体。你可以想象有其他领域,例如标签、位置等

    @Entity
    public class MyImage {
        @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Long id;
    
        @Persistent
        private String name;
    
        @Persistent
        Blob image;
    
        public MyImage() { }
        public MyImage(String name, Blob image) {
            this.name = name; 
            this.image = image;
        }
    
        // JPA getters and setters and empty contructor
        // ...
        public Blob getImage()              { return image; }
        public void setImage(Blob image)    { this.image = image; }
    }
    

    然后当您开始接受图像时(除了典型的文件上传失败之外,还要注意已经上传了同名图像的情况)。 ServletFileUploadIOUtils 是属于 Apache Commons 库的类。

    // Your upload handle would look like
    public void doPost(HttpServletRequest req, HttpServletResponse res) {
        // Get the image representation
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iter = upload.getItemIterator(req);
        FileItemStream imageItem = iter.next();
        InputStream imgStream = imageItem.openStream();
    
        // construct our entity objects
        Blob imageBlob = new Blob(IOUtils.toByteArray(imgStream));
        MyImage myImage = new MyImage(imageItem.getName(), imageBlob);
    
        // persist image
        PersistenceManager pm = PMF.get().getPersistenceManager();
        pm.makePersistent(myImage);
        pm.close();
    
        // respond to query
        res.setContentType("text/plain");
        res.getOutputStream().write("OK!".getBytes());
    }
    

    最后,当您想提供一个给定名称的图像时:

    Blob imageFor(String name, HttpServletResponse res) {
        // find desired image
        PersistenceManager pm = PMF.get().getPersistenceManager();
        Query query = pm.newQuery("select from MyImage " +
            "where name = nameParam " +
            "parameters String nameParam");
        List<MyImage> results = (List<MyImage>)query.execute(name);
        Blob image = results.iterator().next().getImage();
    
        // serve the first image
        res.setContentType("image/jpeg");
        res.getOutputStream().write(image.getBytes());
    }
    

    【讨论】:

    • 太好了,谢谢。你能告诉我为什么字节数组不会给出正确的输出,尽管它被存储了等等,我刚才提出了这个问题stackoverflow.com/questions/2018597/…
    • Eclipse 告诉我 IOUtils 不受 GAE 支持...是否有特殊的包或什么?
    • 如何克服 1 MB 的限制
    • 2016 年有关如何使用 Google Cloud Storage 执行此操作的任何答案,这显然是推荐的方式?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2018-05-09
    • 2014-10-18
    • 2017-01-07
    • 2017-05-03
    相关资源
    最近更新 更多