4

我正在使用适用于 Java 的 Google 应用引擎开发 Web 应用程序。我将使用谷歌云存储,根据文档,我正在使用 GCS 客户端库来模拟本地磁盘上的云存储。

我保存文件没有问题,我可以从 eclipse 下的 war 文件夹(在路径 WEB-INF/appengine-generated 下)看到它们,我可以从 url 访问的 web 管理面板中看到它们

本地主机:8888/_ah/admin

如this question所示

我的问题如下。localhost 下的哪些文件 URI 可以通过 GCS 仿真访问它们?

本地主机上上传文件之一的示例:

  • 文件密钥是 aglub19hcHBfaWRyJwsSF19haF9GYWtlQ2xvdWRTdG9yYWdlX18xIgpxcmNvZGUuanBnDA
  • ID/名称编码_gs_key:L2dzLzEvcXJjb2RlLmpwZw
  • 文件名是 /gs/1/qrcode.jpg

提前致谢。

4

3 回答 3

3

使用getServingUrl()

本地 gcs 文件保存为 blob 格式。保存时,我可以使用您的文件名“/gs/1/qrcode.jpg”之类的位置但是,在访问它时,这个假位置不起作用。我找到了一个方法。它可能不是最好的,但对我有用。

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

网址将如下所示:

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

(我几乎没有通过谷歌搜索找到任何直接的解决方案。我希望这个答案可以帮助其他有需要的人。)

资源:ImageServiceFactory ImageService FileServiceFactory

于 2014-09-09T01:27:44.913 回答
3

您可以在此处查看这是如何完成的: https ://code.google.com/p/appengine-gcs-client/source/browse/trunk/java/src/main/java/com/google/appengine/tools/cloudstorage /dev/LocalRawGcsService.java

到今天为止,这个映射是通过使用本地数据存储来维护的。这在未来可能会改变,但是您应该能够简单地调用这个类或 GCS 客户端提供的更高级别的类之一来获取数据。

于 2013-06-18T18:29:05.390 回答
0

对于那些希望为 GAE GCS 库创建的本地 GCS 文件提供服务的人,一种解决方案是公开一个 Java Servlet,如下所示:

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);
  }

}

在你的 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>

如果您在 GAE 应用程序中托管此 servlet,则用于访问具有存储桶bucket-name和名称的 GCS 文件的 URLfileNamehttp://localhost:8181:/gcs/bucket-name/fileName,本地 GAE 开发服务器端口号为8181

这至少从 GAE v1.9.50 开始有效。

如果你打算让本地 GCS 服务器在 Jetty 的单元测试中工作,这里有一个变通方法,希望有正确的评论:

  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();
于 2017-11-04T09:24:37.770 回答