使用Blob存储与谷歌的云计算终端和Android [英] using blobstore with google cloud endpoint and android

查看:122
本文介绍了使用Blob存储与谷歌的云计算终端和Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个应用程序引擎使用Eclipse插件连接Android项目。该应用的一个方面是允许用户阿尔法将图片发送到用户Bravo的。为了做到这一点,我有以下设置:

I am developing an app-engine connected android project using the eclipse plugin. One aspect of the app is to allow user Alpha to send pictures to user Bravo. To do that I have the following setup:

用户alpha发布:

  • 通过端点发送图像到我的应用程序引擎服务器
  • 在BLOB存储服务器存储图像
  • 在服务器存储blobkey在数据存储

用户布拉沃得到:

  • 服务器获取从数据存储blobkey
  • 在服务器上使用获取图像的blob键
  • 在服务器发送图像到Android使用的应用程序的端点

本安装需要高达两(2)当我的Andr​​oid应用程序发送的图像分钟的时候,我可以看到它在BLOB疼。不用说,这是完全不能接受的。

This setup takes upward of two (2) minutes from when my android app sends an image to when I can see it in the blob sore. Needless to say this is completely unacceptable.

我的服务器编程处理图像,直通下面的code:

My server is processing the image programmatically, thru the following code:

public static BlobKey toBlobstore(Blob imageData) throws FileNotFoundException, FinalizationException, LockException, IOException {
        if (null == imageData)
            return null;

        // Get a file service
        FileService fileService = FileServiceFactory.getFileService();

        // Create a new Blob file with mime-type "image/png"
        AppEngineFile file = fileService.createNewBlobFile("image/jpeg");// png

        // Open a channel to write to it
        boolean lock = true;
        FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);

        // This time we write to the channel directly
        writeChannel.write(ByteBuffer.wrap
            (imageData.getBytes()));

        // Now finalize
        writeChannel.closeFinally();
        return fileService.getBlobKey(file);
    }

有谁知道我可以适应官方例子来使用端点(在我必须用我的应用程序引擎实例),或者使用的情况下 getServingUrl (绕过我的情况下),以存储和提供我的斑点?不是的话请,包括code。谢谢你。

Does anyone know how I can either adapt the official example to use endpoints (in the case where I must use my app-engine instances) or use getServingUrl (bypassing my instances) to store and serve my blobs?
Please, instead of words, include the code. Thanks.

推荐答案

我将分享我如何做这个。我不使用谷歌的云为终点,而只是我自己的基于REST API,但它应该是同样的想法,无论采用哪种方式。

I'll share how I'm doing this. I'm not using the google-cloud-endpoints, but just my own rest based api, but it should be the same idea either way.

我就会把它逐步与code,希望这将是明显的。 你会简单地调整你把你的请求使用,而不是做更通用的就像这个例子端点的方式。我包括一些样板,但不包括try / catch语句,错误检查等为简洁起见。

I'll lay it out step by step with code, hopefully it will be clear. You'd simply adapt the way you send your requests to use endpoints instead of doing it more generic like in this example. I'm including some boilerplate, but excluding try/catch,error checking etc for brevity.

第1步(客户端)

第一个客户端请求一个URL上传从服务器:

First client requests an upload url from server:

HttpClient httpclient = new DefaultHttpClient();    
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //Timeout Limit

HttpGet httpGet = new HttpGet("http://example.com/blob/getuploadurl");
response = httpclient.execute(httpGet);

第2步(服务器)

在服务器端上传请求的servlet会是这个样子:

On the server side the upload request servlet would look something like this:

String blobUploadUrl = blobstoreService.createUploadUrl("/blob/upload");

res.setStatus(HttpServletResponse.SC_OK);
res.setContentType("text/plain");

PrintWriter out = res.getWriter();
out.print(blobUploadUrl);
out.flush();
out.close();

注意参数createUploadUrl。这是在客户端将  重定向一旦实际上传已经完成。这就是  你会处理存储blobkey和/或服务的网址,并返回给客户端。你必须一个servlet映射到URL,将处理步骤4

note the argument to createUploadUrl. This is where the client will be redirected once the actual upload has been completed. That's where you'll handle storing the blobkey and/or serving url and returning it to the client. You'll have to map a servlet to that url, which will handle step 4

步骤3(客户端) 回客户端再次发送实际文件以使用url上载的URL从步骤2返回

Step 3 (client) Back to the client again to send the actual file to the upload url using the url returned from step 2.

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(uploadUrlReturnedFromStep2);

FileBody fileBody  = new FileBody(thumbnailFile);
MultipartEntity reqEntity = new MultipartEntity();

reqEntity.addPart("file", fileBody);

httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost)

在这个请求被发送到servlet在步骤2中,它会被重定向到指定的的servlet的 createUploadUrl()前面

Once this request is sent to the servlet in step 2, it will be redirected to the servlet you specified in the createUploadUrl() earlier

第4步(服务器)

回到服务器端: 这是servlet处理URL映射到 BLOB /上传。我们将在blobkey和服务URL这里返回到客户端在一个JSON对象:

Back to the server side: This is the servlet handling the url mapped to blob/upload. We will here return the blobkey and serving url to the client in a json object:

List<BlobKey> blobs = blobstoreService.getUploads(req).get("file");
BlobKey blobKey = blobs.get(0);

ImagesService imagesService = ImagesServiceFactory.getImagesService();
ServingUrlOptions servingOptions = ServingUrlOptions.Builder.withBlobKey(blobKey);

String servingUrl = imagesService.getServingUrl(servingOptions);

res.setStatus(HttpServletResponse.SC_OK);
res.setContentType("application/json");

JSONObject json = new JSONObject();
json.put("servingUrl", servingUrl);
json.put("blobKey", blobKey.getKeyString());

PrintWriter out = res.getWriter();
out.print(json.toString());
out.flush();
out.close();

第5步(客户端)

我们会得到的JSON的blobkey,服务的URL,然后将其与用户ID等存储在数据存储实体发送。

We'll get the blobkey and serving url from the json and then send it along with user id etc to store in the datastore entity.

JSONObject resultJson = new JSONObject(resultJsonString);

String blobKey = resultJson.getString("blobKey");
String servingUrl = resultJson.getString("servingUrl");

List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

nameValuePairs.add(new BasicNameValuePair("userId", userId));
nameValuePairs.add(new BasicNameValuePair("blobKey",blobKey));
nameValuePairs.add(new BasicNameValuePair("servingUrl",servingUrl));

HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000);

HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);

// Continue to store the (immediately available) serving url in local storage f.ex

第六步(服务器) 其实一切都存储在数据存储(使用物化在这个例子中)

Step 6 (server) Actually storing everything in the datastore (using objectify in this example)

final String userId   = req.getParameter("userId");
final String blobKey  = req.getParameter("blobKey");
final String servingUrl = req.getParameter("servingUrl");

ExampleEntity entity = new ExampleEntity();
entity.setUserId(userId);
entity.setBlobKey(blobKey);
entity.setServingUrl(servingUrl);

ofy().save().entity(entity);

我希望这使事情变得更加清晰。如果有人想编辑使用,而不是这个更通用的例子云终端的回答,请随时:)

I hope this makes things more clear. If someone wants to edit the answer to use cloud endpoints instead of this more generic example, feel free :)

关于提供服务的网址

该服务的网址是一个伟大的方式将图像服务你的客户,的方式,因为它可以动态扩展的飞行图像。例如,你可以通过简单地追加 = SXXX 在服务URL的末尾发送较小的图像到您的LDPI用户。其中XXX为你的形象的最大尺寸的像素大小。你完全避免的情况下,仅支付带宽,而用户只下载她需要什么。

The serving url is a great way to serve images to your clients, because of the way it can dynamically scale images on the fly. For example you can send smaller images to your LDPI users by simply appending =sXXX at the end of the serving url. Where XXX is the pixel size of the largest dimension of your image. You completely avoid your instances and only pay for bandwidth, and the user only downloads what she needs.

PS!

这应该可以停止在步骤4中,只存储直接​​在那里,通过沿用户id f.ex在步骤3中传递的任何参数都应该沿着发送到步骤4,但我没有得到那个工作,所以这是我如何做到这一点的那一刻,让我分享这种方式,因为我知道它的工作原理。

It should be possible to stop at step 4 and just store it directly there, by passing along userId f.ex in step 3. Any parameters are supposed to be sent along to Step 4, but I did not get that to work, so this is how I do it at the moment, so I'm sharing it this way since i know it works.

这篇关于使用Blob存储与谷歌的云计算终端和Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆