which are the files uri on GAE java emulating cloud storage with GCS client library?

北城以北 提交于 2020-01-03 16:57:47

问题


I'm developing a web application using Google app engine for Java. I will use Google Cloud storage and according to the documentation, I'm using GCS client library to emulate cloud storage on local disk.

I have no problem saving the files, I can see them from eclipse under the war folder (under the path WEB-INF/appengine-generated) and I can see them from the web admin panel accessible from the url

localhost:8888/_ah/admin

as indicated in this question

My question is the following. Which are the files URI under localhost to access them with GCS emulation?

Example of one of uploaded files on localhost:

  • file key is aglub19hcHBfaWRyJwsSF19haF9GYWtlQ2xvdWRTdG9yYWdlX18xIgpxcmNvZGUuanBnDA
  • ID/name is encoded_gs_key:L2dzLzEvcXJjb2RlLmpwZw
  • filename is /gs/1/qrcode.jpg

Thanks in advance.


回答1:


You can see how this is done here: https://code.google.com/p/appengine-gcs-client/source/browse/trunk/java/src/main/java/com/google/appengine/tools/cloudstorage/dev/LocalRawGcsService.java

As of today this mapping is being maintained by the using the local datastore. This may change in the future, but you should be able to simply call into this class or one of the higher level classes provided with the GCS client to get at the data.




回答2:


Using getServingUrl()

The local gcs file is saved into a blob format. When saving it, I can use location like your filename "/gs/1/qrcode.jpg" Yet, when accessing it, this fake location is not working. I found a way. It may not be the best, but works for me.

BlobKey bk = BlobstoreServiceFactory.getBlobstoreService().createGsBlobKey(location);
String url = ImagesServiceFactory.getImagesService().getServingUrl(bk);

The url will be like:

http://127.0.0.1:8080/_ah/img/encoded_gs_key:yourkey

(I was hardly to find any direct solution by google search. I hope this answer can help others in need.)

Resource: ImagesServiceFactory ImageService FileServiceFactory




回答3:


For those who wish to serve the local GCS files that have been created by the GAE GCS library, one solution is to expose a Java Servlet like this:

package my.applicaion.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;

public final class GoogleCloudStorageServlet
  extends HttpServlet
{

  @Override
  protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
      throws ServletException, IOException
  {
    final BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
    final String fileName = "/gs" + request.getPathInfo();
    final BlobKey blobKey = blobstoreService.createGsBlobKey(fileName);
    blobstoreService.serve(blobKey, response);
  }

}

and in your web.xml:

<servlet>
  <servlet-name>GoogleCloudStorage</servlet-name>
  <servlet-class>my.applicaion.servlet.GoogleCloudStorageServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>GoogleCloudStorage</servlet-name>
  <url-pattern>/gcs/*</url-pattern>
</servlet-mapping>

If you host this servlet in your GAE application, the URL for accessing a GCS file with bucket bucket-name and with name fileName is http://localhost:8181:/gcs/bucket-name/fileName, the local GAE development server port number being 8181.

This works at least from GAE v1.9.50.

And if you intend to have the local GCS server working in a unit test with Jetty, here is a work-around, hopefully with the right comments:

  final int localGcsPortNumber = 8081;
  final Server localGcsServer = new Server(localGcsPortNumber);
  final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
  final String allPathSpec = "/*";
  context.addServlet(new ServletHolder(new HttpServlet()
  {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
      final BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
      final String fileName = "/gs" + request.getRequestURI();
      final BlobKey blobKey = blobstoreService.createGsBlobKey(fileName);

      if (blobKey != null)
      {
        // This is a work-around over the "ServeBlobFilter" which does not take the "Content-Type" from the "blobInfo", but attempts to retrieve it from the "blobKey"
        final BlobInfo blobInfo = BlobStorageFactory.getBlobInfoStorage().loadGsFileInfo(blobKey);
        if (blobInfo != null)
        {
          final String contentType = blobInfo.getContentType();
          if (contentType != null)
          {
            response.addHeader(HttpHeaders.CONTENT_TYPE, contentType);
          }
        }
      }

      blobstoreService.serve(blobKey, response);
    }

  }), allPathSpec);
  // The filter is responsible for taken the "blobKey" from the HTTP header and for fulfilling the response with the corresponding GCS content
  context.addFilter(ServeBlobFilter.class, allPathSpec, EnumSet.of(DispatcherType.REQUEST));
  // This attribute must be set, otherwise a "NullPointerException" is thrown
  context.getServletContext().setAttribute("com.google.appengine.devappserver.ApiProxyLocal", LocalServiceTestHelper.getApiProxyLocal());
  localGcsServer.setHandler(context);
  localGcsServer.start();


来源:https://stackoverflow.com/questions/17142004/which-are-the-files-uri-on-gae-java-emulating-cloud-storage-with-gcs-client-libr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!