Google App Engine / Google Cloud Endpointsãã©ãããã©ãŒã ã§ã®Java Webéçº
ã«é¢ããäžé£ã®èšäºãç¶ããŠãGoogle Cloud Storageãã¡ã€ã«ã®ã¯ã©ãŠãã¹ãã¬ãŒãžã®ãµãŒãã¹ãèŠãŠãããŸãã
äžè¬ã«ãã¹ããŒã ã¯æ¬¡ã®ãšããã§ããããã¯ãšã³ãã®ãµãŒããŒã¯ãã¹ãã¬ãŒãžã®ç¹å®ã®ã³ã³ããïŒãã±ããïŒã«ãã¡ã€ã«ã転éããããã®äžæãªã³ã¯ïŒã¢ãã¬ã¹ïŒãçæããããã³ããšã³ãã®ãã¡ã€ã«ã転éãããã©ãŒã ã«æ¿å
¥ããŸãã ãŠãŒã¶ãŒã¯ãæå®ãããã¢ãã¬ã¹ã«1ã€ä»¥äžã®ãã¡ã€ã«ããªã¯ãšã¹ãæ¬æã«æå®ããŠPOST HTTPãªã¯ãšã¹ããéä¿¡ãããã¡ã€ã«ãåä¿¡ããŠââãªããžããªã«é
眮ããŸããé
眮ããããã¡ã€ã«ã«é¢ããããŒã¿ãšãšãã«HTTPãªã¯ãšã¹ãããµãŒãã¬ãããåä¿¡ããŸãããµãŒãã¬ããã¯ãé
眮ããããã¡ã€ã«ã«é¢ããæ
å ±ãåŠçããåŸãHTTPã¬ã¹ãã³ã¹ããŠãŒã¶ãŒã«è¿ããŸãïŒ JSONãŸãã¯text / htmlããŸãã¯ç§ãã¡ãæããã®ã
ãã¡ã€ã«ã¯ãªããžããªã«ä¿åããããµãŒãã¬ããã«ã¯ãã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ãèš±å¯ããããŒããããŸããç¹ã«ãå¥ã®ãµãŒãã¬ããã䜿çšããŠãŠãŒã¶ãŒã«ãã¡ã€ã«ãçºè¡ãããããéçããªã³ã¯ïŒhttpsïŒ//ïŒãäœæã§ããŸãã
ãªããžããªãžã®ã¢ã¯ã»ã¹ã¯ããŠã§ãã€ã³ã¿ãŒãã§ãŒã¹ãããããã³
gsutilãŠãŒãã£ãªãã£ã䜿çšããŠã³ãã³ãã©ã€ã³ãããå©çšã§ããŸãã
äŸãšããŠãGoogle Cloud StorageãGAEã®ã¢ããªã±ãŒã·ã§ã³ãšçµ±åããŸãïŒhello-habrahabr-api.appspot.com + hello-habrahabr-webapp.appspot.comã¯åã®
äŸã§äœ¿çšããŸããã
Google Cloud StorageãGoogle App Engine / Google Cloud Endpointsã®ãããžã§ã¯ãã«æ¥ç¶ããŸã
ãŸããApp Engine Developerã³ã³ãœãŒã«ã«ã¢ã¯ã»ã¹ããŸãïŒ
appengine.google.com/dashboard ?&
app_id=hello-habrahabr-api ïŒhttps://appengine.google.com/dashboard?&app_id={
project ID}ïŒ
[ã¢ããªã±ãŒã·ã§ã³ã®èšå®]> [ã¯ã©ãŠãçµ±å]ã«ç§»åããããŒãžã®äžéšã«ãã[äœæ]ãã¯ãªãã¯ããŸãã

ãã¯ã©ãŠãçµ±åã¿ã¹ã¯ãéå§ãããŸããããšããã¡ãã»ãŒãžã衚瀺ãããŸãã
Google Developer Consoleã«ã¯ãå€ãããšãæ°ãããã®2ã€ã®ããŒãžã§ã³ããããæ©èœã¯åŸã
ã«ãå€ãããããæ°ãããã«ç§»è¡ããŠããŸãã å€ãéçºè
ã³ã³ãœãŒã«ããCloud Integrationãå«ããŠããŸãïŒãã®æ©èœã¯ããã«æ°ããã³ã³ãœãŒã«ã«ãç»å ŽããããšãæåŸ
ãã¹ãã§ãïŒã
ãäœæããã¿ã³ã®ä»£ããã«ãã¯ã©ãŠãçµ±åã»ã¯ã·ã§ã³ã®äžéšã«ããŒãžããªããŒããããšãããããžã§ã¯ããæ£åžžã«äœæãããŸããã 詳现ã«ã€ããŠã¯ããåºæ¬ãã»ã¯ã·ã§ã³ãåç
§ããŠãã ããããåºæ¬ã»ã¯ã·ã§ã³ã®å°ãäžã«ãæ¥ç¶ãããGoogle Cloud Storageãã±ãããžã®ãªã³ã¯ã衚瀺ãããŸããããã©ã«ãã§ã¯ãGAEãããžã§ã¯ããšåãååãä»ããããŸãïŒç§ã®å Žåã¯hello-habrahabr-api.appspot.comïŒã

ãªã³ã¯ãã¯ãªãã¯ãããšãã¢ãã¬ã¹
console.developers.google.com/storage/browser {name Bucket} / Dã«ç§»åããŸãïŒç§ã®å ŽåïŒ
console.developers.google.com/storage/browser/hello-habrahabr-api.appspot.com ïŒåœç¶ã®ããšãªããæ¿èªãå¿
èŠã§ãïŒãã¹ãã¬ãŒãžãã©ãŠã¶ã«ã¢ã¯ã»ã¹ããŸãïŒ

ããã§ã¯ãæ°ãããã©ã«ããŒã®äœæããã¡ã€ã«ã®ã¢ããããŒããšåé€ããã¡ã€ã«ã®ã¢ã¯ã»ã¹èš±å¯ã®ç®¡çãè¡ãããšãã§ããŸããããšãã°ããã¡ã€ã«ãå
¬éããWebçšã®ãã¡ã€ã«ãžã®ããŒããªã³ã¯ãåãåãããšãã§ããŸãïŒããšãã°ãWebçšã«ç»åããã®ä»ã®éçãã¡ã€ã«ã䜿çšããå Žåãµã€ãïŒãæ€çŽ¢ããã³ãã£ã«ã¿ãŒã
Cloud Storageã¯ãGoogle App Engineã®ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã«ç¡æã®ãã±ãããæäŸããŸããããã®å Žåãã¹ãã¬ãŒãžãã©ãŠã¶ãŒã®ãŠã§ãã€ã³ã¿ãŒãã§ãŒã¹ã¯ãã±ããã®ã³ã³ãã³ãã衚瀺ããæ©èœã®ã¿ãæäŸããŸãã ã¹ãã¬ãŒãžãã©ãŠã¶ãŒã®ãã¹ãŠã®æ©èœãã¢ã¯ãã£ãã«ãã远å ã®ãã±ãããäœæããã«ã¯ãè«æ±ãæå¹ã«ããŠã¯ã¬ãžããã«ãŒãæ
å ±ãå
¥åããå¿
èŠããããŸãïŒãç¡æãã©ã€ã¢ã«ã«çœ²åããã¯ãªãã¯ããŠã¯ã¬ãžããã«ãŒãæ
å ±ãå
¥åãããšããã©ã€ã¢ã«æéã§ãã60æ¥éããŸãã¯300ãã«ä»¥å
ã§ç¡æãã©ã€ã¢ã«ãåŸãããŸãïŒ ïŒ
ãã¡ã€ã«ãããŠã³ããŒãããããã®äžæãªã³ã¯ãäœæãã
å¿
èŠãªã€ã³ããŒãïŒ
import com.google.appengine.api.blobstore.BlobstoreService; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.blobstore.UploadOptions;
ãªã³ã¯ãäœæããã³ãã³ãïŒ
String uploadUrl = BlobstoreServiceFactory.getBlobstoreService().createUploadUrl( "/upload",
ããšãã°ãCloud Endpointsã§APIãäœæãããšããã¡ã€ã«ãããŠã³ããŒãããããã®ãªã³ã¯ãè¿ãAPIã¯æ¬¡ã®ããã«ãªããŸãã
package com.appspot.hello_habrahabr_api; import com.google.api.server.spi.config.Api; import com.google.api.server.spi.config.ApiMethod; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.blobstore.UploadOptions; import java.io.Serializable; @Api(name = "uploadAPI", version = "ver.1.0", scopes = {Constants.EMAIL_SCOPE}, clientIds = { Constants.WEB_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID }, description = "uploads API") public class UploadAPI {
ããã³ããšã³ããã©ãŒã ïŒ
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <title>File Upload Form</title> </head> <body> <hr> One File: <hr> <form action="" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="Upload"> </form> <hr> Multiple Files: <hr> <form action="" method="post" enctype="multipart/form-data"> <input type="file" name="files[]" multiple> <input type="submit" value="Upload"> </form> <script> 'use strict'; $(document).ready(function () { var url = "https://hello-habrahabr-api.appspot.com/_ah/api/uploadAPI/ver.1.0/getCsUploadURL"; $.ajax(url, { method: "POST", </script> </body> </html>
JSPãšåã圢åŒïŒ
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="com.google.appengine.api.blobstore.BlobstoreService" %> <%@ page import="com.google.appengine.api.blobstore.BlobstoreServiceFactory" %> <%@ page import="com.google.appengine.api.blobstore.UploadOptions" %> <% BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); %> <html> <head> <title>File Upload Form</title> </head> <body> <hr> One File: <hr> <form action="<%= blobstoreService.createUploadUrl("/cs-upload", UploadOptions.Builder.withGoogleStorageBucketName("hello-habrahabr-api.appspot.com")) %>" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="Upload"> </form> <hr> Multiple Files: <hr> <form action="<%= blobstoreService.createUploadUrl("/cs-upload", UploadOptions.Builder.withGoogleStorageBucketName("hello-habrahabr-api.appspot.com")) %>" method="post" enctype="multipart/form-data"> <input type="file" name="files[]" multiple> <input type="submit" value="Upload"> </form> </body> </html>
衚瀺ããããªã³ã¯ã¯æ¬¡ã®ããã«ãªããŸãã
https://hello-habrahabr-api.appspot.com/_ah/upload/AMmfu6YJ0ci-sKP5k98sKaJEUjYwBFbkVfQ7iylXTJV52_gy5HIECKNG52IPUCJ9PB3wpL2wxgX82GkGkzetHt-6fuu4yzAzFFhD8HGOcD7eJ48KJLnKnb2EqbuoFEdyuc8r_FTR7779IIaf42rf_jhkl7Hju3GxWDmxh2WtmcPR2AbB9OWlQhYxBIWtZgBW9OsHO50pI21/ALBNUaYAAAAAVp2DRSZYST46t2kPmrGrrBoY3AFjyOiD/
ãã ããHTTPå¿çã¯ãã¢ãã¬ã¹
/cs-upload
ãããµãŒãã¬ããã«ãã£ãŠäœæãããŸã
HTTPå¿çãçæãããµãŒãã¬ããïŒã¢ããããŒããã³ãã©ãŒïŒ
ãã®ãµãŒãã¬ããã¯æ¬¡ã®ããã«ãªããŸãã
package com.appspot.hello_habrahabr_api; import com.google.appengine.api.blobstore.BlobKey; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.blobstore.FileInfo; import com.google.appengine.api.images.ImagesServiceFactory; import com.google.appengine.api.images.ServingUrlOptions; import com.google.appengine.repackaged.com.google.gson.Gson; import com.google.appengine.repackaged.com.google.gson.GsonBuilder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.logging.Logger; public class CSUploadHandlerServlet extends HttpServlet { private final static Logger LOG = Logger.getLogger(CSUploadHandlerServlet.class.getName()); private final static String HOST = "https://hello-habrahabr-api.appspot.com"; class UploadedFileData { FileInfo fileInfo; String BlobKey; String fileServeServletLink; String servingUrlFromgsObjectName; String servingUrlFromGsBlobKey; }
HTTPã¬ã¹ãã³ã¹ã§æ¬¡ã®JSONãçæããŸãã
ãžã§ã³ãœã³ [{ "fileInfo": { "contentType": "image/svg+xml", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "Sun_symbol.svg", "size": 188, "md5Hash": "YWZmM2UzMzk2ZDk2NTc0ZWM3NDI0YjYyMDMxZGIxYTM=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy42LWZnTzcybk1xNG03X1pw" }, "BlobKey": "AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O" }, { "fileInfo": { "contentType": "image/jpeg", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "world_map_04.jpg", "size": 44680, "md5Hash": "MzQyMzliZGQ4NmYyNmZiNzc3ZjAyMzBhNmM4NDVmNWE=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy5Ld1pSRTQ2M3J3ZWYxa3Bm" }, "BlobKey": "AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "servingUrlFromgsObjectName": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg", "servingUrlFromGsBlobKey": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg" }]
-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O"ã [{ "fileInfo": { "contentType": "image/svg+xml", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "Sun_symbol.svg", "size": 188, "md5Hash": "YWZmM2UzMzk2ZDk2NTc0ZWM3NDI0YjYyMDMxZGIxYTM=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy42LWZnTzcybk1xNG03X1pw" }, "BlobKey": "AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O" }, { "fileInfo": { "contentType": "image/jpeg", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "world_map_04.jpg", "size": 44680, "md5Hash": "MzQyMzliZGQ4NmYyNmZiNzc3ZjAyMzBhNmM4NDVmNWE=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy5Ld1pSRTQ2M3J3ZWYxa3Bm" }, "BlobKey": "AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "servingUrlFromgsObjectName": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg", "servingUrlFromGsBlobKey": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg" }]
-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB"ã [{ "fileInfo": { "contentType": "image/svg+xml", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "Sun_symbol.svg", "size": 188, "md5Hash": "YWZmM2UzMzk2ZDk2NTc0ZWM3NDI0YjYyMDMxZGIxYTM=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy42LWZnTzcybk1xNG03X1pw" }, "BlobKey": "AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O" }, { "fileInfo": { "contentType": "image/jpeg", "creation": "Jan 18, 2016 7:16:18 PM", "filename": "world_map_04.jpg", "size": 44680, "md5Hash": "MzQyMzliZGQ4NmYyNmZiNzc3ZjAyMzBhNmM4NDVmNWE=", "gsObjectName": "/gs/hello-habrahabr-api.appspot.com/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy5Ld1pSRTQ2M3J3ZWYxa3Bm" }, "BlobKey": "AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "fileServeServletLink": "https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB", "servingUrlFromgsObjectName": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg", "servingUrlFromGsBlobKey": "http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg" }]
ããã¯ãæã
ã¯ããªã³ã¯ã®ããããã®ã¿ã€ãã䜿çšããŠãŠãŒã¶ãŒãäžããããšãã§ããŸãããŠã³ããŒããããã¡ã€ã«ã§ãã
http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg
http://lh3.googleusercontent.com/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg
-ããã¯ãç»åãã¡ã€ã«ããŸãã¯ïŒãããã®å Žåã«ãïŒãåºæºãšããŠè¡šç€ºããããµãŒãã¬ããã§ããã°
https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB
https://hello-habrahabr-api.appspot.com/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB
serve
å Žæ
serve
-ãµãŒãã¬ãããã¹ã
blob-key
blob-key
-ç®çã®ãã¡ã€ã«ãèŠã€ããããã®ãã©ã¡ãŒã¿ãŒãæãæçœãªããªã¢ã³ãã§ã¯ããã®å€ã¯BlobKeyã«ãªããŸãã
BlobKeyã¯ããµãŒãã¬ããããã€ãã¹ããŠãã¡ã€ã«ã«çŽæ¥ã¢ã¯ã»ã¹ããããšã¯ã§ããããµãŒãã¬ããã¯ãèšå®ããåºæºã«å¿ããŠããã¡ã€ã«ã転éããå Žåãšè»¢éããªãå Žåãããããšã«æ³šæããŠãã ããã Google App EngineãæäŸããOAuth2.0èªèšŒã䜿çšãããããªã¯ãšã¹ãã§è¿œå ã®ãã©ã¡ãŒã¿ãŒã䜿çšãããã§ããŸãã
ãµãŒãã¬ããã®ã¢ããããŒããã¡ã€ã«ã¯æ¬¡ã®ããã«ãªããŸãã
package com.appspot.hello_habrahabr_api; import com.google.appengine.api.blobstore.BlobKey; import com.google.appengine.api.blobstore.BlobstoreService; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; public class FileServeServlet extends HttpServlet { private final static Logger LOG = Logger.getLogger(CSUploadHandlerServlet.class.getName()); private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Images Java API
äžèšã®ããã«ãImages Java APIã䜿çšããŠã
ImagesServiceFactory.getImagesService().getServingUrl( ServingUrlOptions.Builder.withGoogleStorageFileName(fileInfo.getGsObjectName()) );
ãŸãã¯ãš
ImagesServiceFactory.getImagesService().getServingUrl( ServingUrlOptions.Builder.withBlobKey(blobKey) );
ç»åãã¡ã€ã«ãæäŸããURLãååŸããŸãã ãã®ãã¡ã€ã«ã®ããŠã³ããŒãæ¹æ³ã¯ããµãŒãã¬ããã䜿çšãããããé«éã«æ©èœããŸãããããã«å¿ããŠãéçããã¡ã€ã«ãžã®ãªã³ã¯ãããããµãŒãã¬ããã䜿çšããå Žåã®ããã«ãªã¯ãšã¹ããåŠçã§ããŸããã
ãããããã¡ã€ã«ãžã®ãã®ãããªäœæããããªã³ã¯ã¯ã
.deleteServingUrlïŒBlobKey blobKeyïŒã¡ãœããã䜿çšããŠäœæãããããã«åé€ã§ããŸã
ããã¡ã€ã«èªäœã¯ãªããžããªããåé€ããããæ°ãããªã³ã¯ãäœæã§ããŸãã ã€ãŸã å¿
èŠã«å¿ããŠäœæããã³åé€ããããšã«ããããã®ãããªãªã³ã¯ãã1åéããäœæã§ããŸãã
getServingUrïŒïŒã䜿çšããŠäœæãããã€ã¡ãŒãžãžã®ãªã³ã¯ã«å ããŠã
http://[image-url]=s200-fh-p-b10-c0xFFFF0000
ã®åœ¢åŒã§ã€ã¡ãŒãžã倿Žãããã©ã¡ãŒã¿ãŒã远å ã§ããŸãã
http://[image-url]=s200-fh-p-b10-c0xFFFF0000
ïŒ
s640-æå€§ã®ãšããžã§640ãã¯ã»ã«ã®ç»åãçæããŸã
s0-å
ã®ç»åãµã€ãºïŒããã©ã«ãã§ã¯ãåºåç»åã¯çž®å°ãããŸãïŒïŒ
w100-å¹
100ãã¯ã»ã«ã®ç»åãçæããŸã
h100-é«ã100ãã¯ã»ã«ã®ç»åãçæããŸã
c-æå®ãããµã€ãºïŒããšãã°ãs200ïŒã«ç»åãããªãã³ã°ããŸã
p-ãã¹ããŒãããªç»åã®ããªãã³ã°ãé¡ã«åãããŠããªãã³ã°ã詊ã¿ãŸãïŒããŸãæ©èœããŸããïŒ
pp-åã®æ®µèœãšåãããšãè¡ãä»£æ¿æ¹æ³ïŒåãããã«æ©èœããŸãïŒ
cc-äžžãç»åãçæããŸã
fv-åçŽã«å転ããŸã
fh-æ°Žå¹³ã«å転ããŸã
r {90}-æå®ããè§åºŠãæèšåãã«å転ããŸã
rj-JPGã€ã¡ãŒãžãçæããŸã
rp-PNGç»åãçæããŸã
rw-WebP圢åŒã®ç»åãçæããŸã
rg-GIFã€ã¡ãŒãžãçæããŸã
b10-æå®ãããå¹
ã®ãã¬ãŒã ïŒãã®å Žåã¯10pxïŒã远å ããŸã
c0xffff0000-ãã¬ãŒã ã®è²ãèšå®ããŸãïŒãã®å Žåã¯èµ€ïŒ
d-ãã©ãŠã¶ãŒã§ã®èªã¿èŸŒã¿ãéå§ããããããŒã远å ããŸã
h-ç»åãå«ãHTMLããŒãžã衚瀺ããŸã
ããšãã°ãå
ã®ç»åããïŒ

ãã©ã¡ãŒã¿ãŒä»ãïŒ
=w100-h100-cc
=w100-h100-cc
-äžžãã¢ãã¿ãŒãçæã§ããŸãã

ãã©ã¡ãŒã¿ãŒä»ãïŒ
=s200-b3-c0xffff0000
=s200-b3-c0xffff0000
-é¡ã®æå€§ãµã€ãºã200ãã¯ã»ã«ãå¹
ã3ãã¯ã»ã«ã®èµ€ãå¢çç·ã®ãµã ãã€ã«ïŒ

ãã®å ŽåãCSSã®äœ¿çšãšã¯ç°ãªããç»åã¯æ¢ã«ç®çã®ãµã€ãºã«çž®å°ããããµãŒããŒããèªã¿èŸŒãŸããŸãã
ãã®ä»ã®ãªãã·ã§ã³ã«ã€ããŠã¯ã
stackoverflow.com / questions / 25148567 / list-of-all-the-app-engine-images-service-get-serving-url-uri- optionsãåç
§ããŠãã ãã
ã³ãã³ãã©ã€ã³ãããªããžããªã«ã¢ã¯ã»ã¹ããïŒ gsutilãŠãŒãã£ãªãã£ïŒ
gsutilã¯PythonïŒPython 2.6.xãŸãã¯2.7.xãå¿
èŠïŒã§èšè¿°ãããLinux / UnixãMac OSãããã³WindowsïŒXP以äžïŒã®ã³ãã³ãã©ã€ã³ããå®è¡ãããŸãã
ã€ã³ã¹ããŒã«æé ïŒ
cloud.google.com/storage/docs/gsutil_installã€ã³ã¹ããŒã«åŸã次ãå®è¡ããŸãã
gcloud auth login
ãã°ã€ã³ããŸãïŒ
habrahabr.ru/post/268863ã«èšèŒãããŠããå
容ãšåæ§ïŒ
gsutilã¯ãéåžžã®Linux / Unixã³ã³ãœãŒã«ã³ãã³ããšåæ§ã®ã³ãã³ãã䜿çšããã¹ãââã¬ãŒãžã³ã³ãããŒãžã®ã¢ã¯ã»ã¹ã衚ããŸã;ã¹ãã¬ãŒãžå
ã®ãã¡ã€ã«ã¯ãgsïŒ// {container name}ã®åœ¢åŒã®ããã¹ãã§ç€ºãããŸãã
ãã®ãããã³ã³ããå
ã®ãã¡ã€ã«ã«é¢ããæ
å ±ã衚瀺ããã«ã¯ã次ã®ã³ãã³ããå
¥åããŸã
gsutil ls gs://hello-habrahabr-api.appspot.com
çŸåšã®ãŠãŒã¶ãŒïŒGoogleã¢ã«ãŠã³ãïŒã䜿çšã§ãããã¹ãŠã®ã³ã³ããå
ã®ãã¹ãŠã®ãã¡ã€ã«ïŒ
gsutil ls gs://*
lsã³ãã³ãã§ããè©³çŽ°ãªæ
å ±ã衚瀺ããã«ã¯ã
-l
ãã©ã¡ãŒã¿ãŒãæå®ãããã¡ã€ã«ã«é¢ããå®å
šãªæ
å ±ã衚瀺ããã«ã¯ã
-L
ãã©ã¡ãŒã¿ãŒãæå®ããŸãã

ãããã£ãŠã
gs://{ } /{ }
ã䜿çšããŠã
cp
ã
mv
ã
rm
ã³ãã³ããã³ã³ããå
ã®ãã¡ã€ã«ã¢ãã¬ã¹ãšããŠäœ¿çšã§ããŸã
gs://{ } /{ }
gs://{ } /{ }
ããŒã«ã«OSäžã®ãã¡ã€ã«ã®éåžžã®ãã¹ãã¯ã€ã«ãã«ãŒãæåïŒ
gs://*
ããµããŒããããŠããŸã
gs://*
ïŒgsutilã³ãã³ãã®è©³çްïŒ
cloud.google.com/storage/docs/gsutilãããã£ãŠãgsutilã®æ©èœã䜿çšããŠããªããžããªå
ã®ãã¡ã€ã«ã䜿çšããäœæ¥ãæŽçããã³èªååã§ããŸãã
åç
§è³æ