{"id":272450,"date":"2016-01-19T16:40:02","date_gmt":"2016-01-19T13:40:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=272450"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=272450","title":{"rendered":"Google Cloud Storage c Java: \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043e\u0431\u043b\u0430\u043a\u0430\u0445"},"content":{"rendered":"<p>       \u0412 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">\u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439<\/a> \u043e \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Java \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Google App Engine \/ Google Cloud Endpoints \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 Google Cloud Storage. <\/p>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c \u0441\u0445\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 (\u0430\u0434\u0440\u0435\u0441) \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 (bucket) \u043d\u0430\u0448\u0435\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043b\u0430. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 POST HTTP-request \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432 \u0442\u0435\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0438 HTTP-request \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0432 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e HTTP response: JSON \u0438\u043b\u0438 text\/html, \u0438\u043b\u0438 \u0432 \u043e\u0431\u0449\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u0436\u0435\u043b\u0430\u0435\u043c. <\/p>\n<p>  \u0424\u0430\u0439\u043b\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0443 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430 \u0435\u0441\u0442\u044c \u0432 \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0438 \u043a\u043b\u044e\u0447 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430 \u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u00ab\u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0443\u044e\u00bb \u0441\u0441\u044b\u043b\u043a\u0443 (https:\/\/). <br \/>  \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0438 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u044b <a href=\"https:\/\/cloud.google.com\/storage\/docs\/gsutil\">gsutil<\/a>. <br \/>  <a name=\"habracut\"><\/a><br \/>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c Google Cloud Storage \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043d\u0430 GAE: hello-habrahabr-api.appspot.com + hello-habrahabr-webapp.appspot.com \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u043c\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">\u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445<\/a>. <\/p>\n<h4>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Google Cloud Storage \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043d\u0430 Google App Engine \/ Google Cloud Endpoints<\/h4>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0445\u043e\u0434\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 ( App Engine Developer console): <br \/>  <a href=\"https:\/\/appengine.google.com\/dashboard?&#038;app_id=hello-habrahabr-api\">appengine.google.com\/dashboard?&#038;app_id=hello-habrahabr-api<\/a> (https:\/\/appengine.google.com\/dashboard?&#038;app_id={\u043f\u0440\u043e\u0435\u043a\u0442 ID})<br \/>  \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043c\u0435\u043d\u044e Application Settings &gt; Cloud Integration \u0438 \u0432\u043d\u0438\u0437\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c &#8216;Create&#8217;: <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/981\/82d\/f3b\/98182df3b1df2be80576d83e2ebf6270.png\" alt=\"image\"\/><br \/>  \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u00abCloud integration tasks have started\u00bb <br \/>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 Google \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0434\u0432\u0443\u0445 \u0432\u0435\u0440\u0441\u0438\u044f \u00ab\u0441\u0442\u0430\u0440\u0430\u044f\u00bb \u0438 \u00ab\u043d\u043e\u0432\u0430\u044f\u00bb, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0438\u0437 \u00ab\u0441\u0442\u0430\u0440\u043e\u0439\u00bb \u0432 \u00ab\u043d\u043e\u0432\u0443\u044e\u00bb. Cloud Integration \u043c\u044b \u043f\u043e\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0439 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 (\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0447\u0442\u043e \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043a\u043e\u0440\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0438 \u0432 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u043e\u043b\u0438) <br \/>  \u041f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0432\u043d\u0438\u0437\u0443 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 Cloud Integration \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043d\u043e\u043f\u043a\u0438 &#8216;Create&#8217; \u0432 \u0432\u0438\u0434\u0438\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u00abThe project was created successfully. See the Basics section for more details.\u00bb<br \/>  \u0410 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 Basics \u0432\u0438\u0434\u0438\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 Google Cloud Storage Bucket, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0435\u043c\u0443 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0438\u043c\u044f \u043a\u0430\u043a \u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 GAE, \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 hello-habrahabr-api.appspot.com: <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/200\/542\/bd0\/200542bd0feb6f37b7570a024c9e2857.png\" alt=\"image\"\/><br \/>  \u041a\u043b\u0438\u043a\u0430\u0435\u043c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435, \u043e\u043d\u0430 \u0432\u0435\u0434\u0435\u0442 \u043d\u0430\u0441 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 <a href=\"https:\/\/console.developers.google.com\/storage\/browser\/\">console.developers.google.com\/storage\/browser<\/a>{\u0438\u043c\u044f Bucket}\/, \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435: <a href=\"https:\/\/console.developers.google.com\/storage\/browser\/hello-habrahabr-api.appspot.com\/\">console.developers.google.com\/storage\/browser\/hello-habrahabr-api.appspot.com<\/a> (\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438) \u0438 \u043c\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 Storage browser, <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/66a\/b24\/1f9\/66ab241f9a799e02a1951907da5cf2cf.png\" alt=\"image\"\/><br \/>  \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0430\u043f\u043a\u0438, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u044b, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0430\u043c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0430\u0439\u043b\u0443 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0432\u0435\u0431 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0430), \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e. <br \/>  Cloud Storage \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 bucket \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Google App Engine, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Storage browser \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 bucket. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 Storage browser \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 buckets \u043d\u0430\u0434\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0431\u0438\u043b\u043b\u0438\u043d\u0433 \u0438 \u0432\u0432\u0435\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0435\u0439 \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b (\u0436\u043c\u0435\u043c \u043d\u0430 \u00abSign for free trial\u00bb \u0438 \u0432\u0432\u043e\u0434\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b, \u043d\u0430 60 \u0434\u043d\u0435\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439, \u0432\u0435\u0440\u043d\u0435\u0435 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 $300, \u043f\u0440\u043e\u0431\u043d\u044b\u0439 \u043f\u0435\u0440\u0438\u043e\u0434)<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430<\/h4>\n<p>  \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b:   <\/p>\n<pre><code class=\"java\">import com.google.appengine.api.blobstore.BlobstoreService; import com.google.appengine.api.blobstore.BlobstoreServiceFactory; import com.google.appengine.api.blobstore.UploadOptions; <\/code><\/pre>\n<p>  \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u043a\u0438:  <\/p>\n<pre><code class=\"java\">String uploadUrl = BlobstoreServiceFactory.getBlobstoreService().createUploadUrl(     &quot;\/upload&quot;, \/\/ path to upload handler (servlet)     UploadOptions.Builder.withGoogleStorageBucketName(&quot;hello-habrahabr-api.appspot.com&quot;) \/\/ bucket name ) <\/code><\/pre>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c API \u043d\u0430 Cloud Endpoints, \u0442\u043e API, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c:   <\/p>\n<pre><code class=\"java\">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 = &quot;uploadAPI&quot;,         version = &quot;ver.1.0&quot;,         scopes = {Constants.EMAIL_SCOPE},         clientIds = {                 Constants.WEB_CLIENT_ID,                 Constants.API_EXPLORER_CLIENT_ID         },         description = &quot;uploads API&quot;)  public class UploadAPI {     \/\/ add this class to &lt;init-param&gt; of &lt;servlet-name&gt;SystemServiceServlet&lt;\/servlet-name&gt; in web.xml      \/* API methods can return JavaBean Objects only, so we use this as a wrapper for String *\/     class StringWrapperObject implements Serializable {         private String string;          public StringWrapperObject() {         }          public StringWrapperObject(String string) {             this.string = string;         }          public String getString() {             return string;         }          public void setString(String string) {             this.string = string;         }     } \/\/ end of StringWrapperObject class      @ApiMethod(             name = &quot;getCsUploadURL&quot;,             path = &quot;getCsUploadURL&quot;,             httpMethod = ApiMethod.HttpMethod.POST     )     @SuppressWarnings(&quot;unused&quot;)     public StringWrapperObject getCsUploadURL() {          String uploadURL = BlobstoreServiceFactory.getBlobstoreService().createUploadUrl(                 &quot;\/cs-upload&quot;, \/\/ upload handler servlet address                 UploadOptions.Builder.withGoogleStorageBucketName(                         &quot;hello-habrahabr-api.appspot.com&quot; \/\/ Cloud Storage bucket name                 )         );          return new StringWrapperObject(uploadURL);     }  } <\/code><\/pre>\n<p>  \u0424\u043e\u0440\u043c\u0430 \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0435:   <\/p>\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt;  &lt;head&gt;     &lt;meta charset=&quot;utf-8&quot;&gt;     &lt;script src=&quot;https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/2.2.0\/jquery.min.js&quot;&gt;&lt;\/script&gt;     &lt;title&gt;File Upload Form&lt;\/title&gt; &lt;\/head&gt;  &lt;body&gt; &lt;hr&gt; One File: &lt;hr&gt; &lt;form action=&quot;&quot; method=&quot;post&quot; enctype=&quot;multipart\/form-data&quot;&gt;     &lt;input type=&quot;file&quot; name=&quot;file&quot;&gt;     &lt;input type=&quot;submit&quot; value=&quot;Upload&quot;&gt; &lt;\/form&gt; &lt;hr&gt; Multiple Files: &lt;hr&gt; &lt;form action=&quot;&quot; method=&quot;post&quot; enctype=&quot;multipart\/form-data&quot;&gt;     &lt;input type=&quot;file&quot; name=&quot;files[]&quot; multiple&gt;     &lt;input type=&quot;submit&quot; value=&quot;Upload&quot;&gt; &lt;\/form&gt;  &lt;!-- JavaScript --&gt; &lt;script&gt;     'use strict';      $(document).ready(function () {          var url = &quot;https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api\/uploadAPI\/ver.1.0\/getCsUploadURL&quot;;          $.ajax(url, {             method: &quot;POST&quot;, \/\/ (default: 'GET')             async: false, \/\/ default: true             processData: true, \/\/ (default: true) (By default, data passed in to the 'data' option as an object)             success: function (data) {                  console.log(&quot;responce received:&quot;);                 console.log(data);                  $(&quot;form&quot;).attr(&quot;action&quot;, data.string);              }         })     }) &lt;\/script&gt; &lt;\/body&gt;  &lt;\/html&gt; <\/code><\/pre>\n<p>  \u0422\u0430 \u0436\u0435 \u0444\u043e\u0440\u043c\u0430 \u0432 \u0432\u0438\u0434\u0435 JSP:   <\/p>\n<pre><code class=\"java\">&lt;%@ page contentType=&quot;text\/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;  &lt;%@ page import=&quot;com.google.appengine.api.blobstore.BlobstoreService&quot; %&gt; &lt;%@ page import=&quot;com.google.appengine.api.blobstore.BlobstoreServiceFactory&quot; %&gt; &lt;%@ page import=&quot;com.google.appengine.api.blobstore.UploadOptions&quot; %&gt;  &lt;%     BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); %&gt; &lt;html&gt; &lt;head&gt;     &lt;title&gt;File Upload Form&lt;\/title&gt; &lt;\/head&gt; &lt;body&gt; &lt;hr&gt; One File: &lt;hr&gt; &lt;form         action=&quot;&lt;%= blobstoreService.createUploadUrl(&quot;\/cs-upload&quot;, UploadOptions.Builder.withGoogleStorageBucketName(&quot;hello-habrahabr-api.appspot.com&quot;)) %&gt;&quot;         method=&quot;post&quot; enctype=&quot;multipart\/form-data&quot;&gt;     &lt;input type=&quot;file&quot; name=&quot;file&quot;&gt;     &lt;input type=&quot;submit&quot; value=&quot;Upload&quot;&gt; &lt;\/form&gt; &lt;hr&gt; Multiple Files: &lt;hr&gt; &lt;form         action=&quot;&lt;%= blobstoreService.createUploadUrl(&quot;\/cs-upload&quot;, UploadOptions.Builder.withGoogleStorageBucketName(&quot;hello-habrahabr-api.appspot.com&quot;)) %&gt;&quot;         method=&quot;post&quot; enctype=&quot;multipart\/form-data&quot;&gt;     &lt;input type=&quot;file&quot; name=&quot;files[]&quot; multiple&gt;     &lt;input type=&quot;submit&quot; value=&quot;Upload&quot;&gt; &lt;\/form&gt;   &lt;\/body&gt; &lt;\/html&gt; <\/code><\/pre>\n<p>  \u0412\u044b\u0434\u0430\u0432\u0430\u0435\u043c\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a: <br \/>  <code> https:\/\/hello-habrahabr-api.appspot.com\/_ah\/upload\/AMmfu6YJ0ci-sKP5k98sKaJEUjYwBFbkVfQ7iylXTJV52_gy5HIECKNG52IPUCJ9PB3wpL2wxgX82GkGkzetHt-6fuu4yzAzFFhD8HGOcD7eJ48KJLnKnb2EqbuoFEdyuc8r_FTR7779IIaf42rf_jhkl7Hju3GxWDmxh2WtmcPR2AbB9OWlQhYxBIWtZgBW9OsHO50pI21\/ALBNUaYAAAAAVp2DRSZYST46t2kPmrGrrBoY3AFjyOiD\/ <\/code><\/p>\n<p>  \u041d\u043e HTTP-response \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0441\u044f \u0443 \u043d\u0430\u0441 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>\/cs-upload<\/code><\/p>\n<h4>\u0421\u0435\u0440\u0432\u043b\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0438\u0439 HTTP-response (upload handler)<\/h4>\n<p>  \u042d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:   <\/p>\n<pre><code class=\"java\">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 = &quot;https:\/\/hello-habrahabr-api.appspot.com&quot;;      \/* Object to be returned as JSON in HTTP-response (and can be stored in data base) *\/     class UploadedFileData {         FileInfo fileInfo;         String BlobKey;         String fileServeServletLink;         String servingUrlFromgsObjectName;         String servingUrlFromGsBlobKey;     } \/\/ end of uploadedFileData      @Override     public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {          \/\/ Returns the FileInfo for any files that were uploaded, keyed by the upload form &quot;name&quot; field.         \/\/ This method should only be called from within a request served by the destination of a createUploadUrl call.         \/\/ https:\/\/cloud.google.com\/appengine\/docs\/java\/javadoc\/com\/google\/appengine\/api\/blobstore\/BlobstoreService#getFileInfos-HttpServletRequest-         java.util.Map&lt;java.lang.String, java.util.List&lt;FileInfo&gt;&gt; fileInfoListsMap = BlobstoreServiceFactory.getBlobstoreService().getFileInfos(req);         LOG.warning(&quot;[LOGGER]: &quot; + new Gson().toJson(fileInfoListsMap));          ArrayList&lt;UploadedFileData&gt; uploadedFilesDataList = new ArrayList&lt;&gt;();          for (java.util.List&lt;FileInfo&gt; fileInfoList : fileInfoListsMap.values()) {              for (FileInfo fileInfo : fileInfoList) {                  UploadedFileData uploadedFileData = new UploadedFileData();                 uploadedFileData.fileInfo = fileInfo;                  LOG.warning(&quot;uploadedFileData created:&quot; + new Gson().toJson(uploadedFileData));                 BlobKey blobKey = BlobstoreServiceFactory.getBlobstoreService().createGsBlobKey(fileInfo.getGsObjectName());                 uploadedFileData.BlobKey = blobKey.getKeyString();                 uploadedFileData.fileServeServletLink = HOST + &quot;\/serve?blob-key=&quot; + blobKey.getKeyString();                  \/\/ Use Images Java API to create serving URL                 \/\/ works only for images (PNG, JPEG, GIF, TIFF, BMP, ICO, WEBP)                 for (com.google.appengine.api.images.Image.Format type : com.google.appengine.api.images.Image.Format.values()) {                     LOG.warning(&quot;com.google.appengine.api.images.Image.Format type: &quot; + type.toString());                     LOG.warning(&quot;fileInfo.getContentType(): &quot; + fileInfo.getContentType());                     if (fileInfo.getContentType().toLowerCase().contains(type.toString().toLowerCase())) {                         uploadedFileData.servingUrlFromgsObjectName = ImagesServiceFactory.getImagesService().getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(fileInfo.getGsObjectName())); \/\/ should be the same as servingUrlFromGsBlobKey                         uploadedFileData.servingUrlFromGsBlobKey = ImagesServiceFactory.getImagesService().getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKey)); \/\/ should be the same as servingUrlFromgsObjectName                      }                 }                  uploadedFilesDataList.add(uploadedFileData);              }          }          res.setContentType(&quot;application\/json&quot;);         res.setCharacterEncoding(&quot;UTF-8&quot;);         PrintWriter pw = res.getWriter(); \/\/get the stream to write the data         Gson gson = new GsonBuilder().disableHtmlEscaping().create();         pw.println(                 gson.toJson(uploadedFilesDataList)         );         LOG.warning(&quot;uploadedFilesDataMap&quot; + new Gson().toJson(uploadedFilesDataList));         pw.close(); \/\/closing the stream      } \/\/ doPost End  } <\/code><\/pre>\n<p>  \u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0432 HTTP-response JSON \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">JSON<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">[{     &quot;fileInfo&quot;: {         &quot;contentType&quot;: &quot;image\/svg+xml&quot;,         &quot;creation&quot;: &quot;Jan 18, 2016 7:16:18 PM&quot;,         &quot;filename&quot;: &quot;Sun_symbol.svg&quot;,         &quot;size&quot;: 188,         &quot;md5Hash&quot;: &quot;YWZmM2UzMzk2ZDk2NTc0ZWM3NDI0YjYyMDMxZGIxYTM=&quot;,         &quot;gsObjectName&quot;: &quot;\/gs\/hello-habrahabr-api.appspot.com\/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy42LWZnTzcybk1xNG03X1pw&quot;     },     &quot;BlobKey&quot;: &quot;AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O&quot;,     &quot;fileServeServletLink&quot;: &quot;https:\/\/hello-habrahabr-api.appspot.com\/serve?blob-key=AMIfv968eMcYEHQml68MAl4NVtOQGKjXUWadeyP7njbaVhHXq_1xDAnRQgHeHrOv4RPLm-KdmqEHP5nb1zNuCFFszRxOVUV4Z97B9slNi7SSGWZ1qKbYcbJi2nl5Z7JX9g1xN4RclYpmLPLfh5k2jAULi6p9g84JSyh5uP3RDkNnPuXkBjxSuBTOWCVxOmpRS-xsB1YedYAgF6cRYLq0hVpm_bOY3Cbl3Ai0W-_req9jxcuPWkoguhHiZ2SSBRF9NlvgG_hCf3vouYtYS2O9DBbioeOL_p1Ck8gfvhQiiK6XpXM4S7vAYqYZCQKJ_9T4tswy075-e6NlsdtXGj9zhSxCy_GfSSBrnvbwcQUDA7lN_IYIfm0QWs-XgzBl9izizUeE46jOI-1O&quot; }, {     &quot;fileInfo&quot;: {         &quot;contentType&quot;: &quot;image\/jpeg&quot;,         &quot;creation&quot;: &quot;Jan 18, 2016 7:16:18 PM&quot;,         &quot;filename&quot;: &quot;world_map_04.jpg&quot;,         &quot;size&quot;: 44680,         &quot;md5Hash&quot;: &quot;MzQyMzliZGQ4NmYyNmZiNzc3ZjAyMzBhNmM4NDVmNWE=&quot;,         &quot;gsObjectName&quot;: &quot;\/gs\/hello-habrahabr-api.appspot.com\/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlVxM3RWVU9nMWVxdmxfQ1dlSk5HaXIwNHpwamE3Y2FhVzlwRjF3dk4zQnFlU3JBMVkxaERGT2NRbXpLZ0pBOW0yTjZiaXhsZjFGWElmdFRNX1p2WXF4WTJnTlF1Zy5Ld1pSRTQ2M3J3ZWYxa3Bm&quot;     },     &quot;BlobKey&quot;: &quot;AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB&quot;,     &quot;fileServeServletLink&quot;: &quot;https:\/\/hello-habrahabr-api.appspot.com\/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB&quot;,     &quot;servingUrlFromgsObjectName&quot;: &quot;http:\/\/lh3.googleusercontent.com\/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg&quot;,     &quot;servingUrlFromGsBlobKey&quot;: &quot;http:\/\/lh3.googleusercontent.com\/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg&quot; }] <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043b\u0438\u0431\u043e \u0441\u0441\u044b\u043b\u043a\u0443 \u0432\u0438\u0434\u0430 <code> http:\/\/lh3.googleusercontent.com\/biRXwDZgclmYJa4hDUwOqBMK--VDNwj-9kZ27vzachWAGBunKVDelImXC9S5EZIhDm1T4xbyq8djFqNKkTzkSpcVkgbPO2ovxg  <\/code> \u2014 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043b\u0438\u0431\u043e (\u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435) \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a <code> https:\/\/hello-habrahabr-api.appspot.com\/serve?blob-key=AMIfv95nBw0rYnC39nCATxvyecFw0JEe64eTm-OhpsSsrR3Idv_rPbO2c6xTDx3q1xkulXfUyapqtEXdeQQur7FcppXa9rRcnlF7QnU8jur7a7AP3T5Ze_-bdD_F6F5mGP9Tteo7p7cN4UccqoYhnAyabAIsJBq3pZIwX2NlHhqcK_aelnu1tl3aszZU4cVmhLiZGE8hFvgDQyt-2oB4DurXUKTwGC56cZykCdYONO0EDETgkImiytbtk1iV_muyYZzfd7on3OS0LSmY8ls7QIcm1IMgl5jDPJANlsk_iWtnRJfEiYAC9pZ7DfhSPxTeYzko0b1TXrKuGjpG8cYMcxiA0Cmeya8y-7SCQuWQLlKCX8WFpIVOr26UguDaq8SFYplALbxgQUiB <\/code>, \u0433\u0434\u0435 <code> serve <\/code> \u2014 \u043f\u0443\u0442\u044c \u043a \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0443, <code> blob-key <\/code> \u2014 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u0432 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0431\u0443\u0434\u0435\u0442 BlobKey.<br \/>  \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0447\u0442\u043e BlobKey \u043d\u0435 \u0434\u0430\u0435\u0442 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443 \u0432 \u043e\u0431\u0445\u043e\u0434 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430, \u0430 \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430\u043c\u0438 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432, \u0432 \u0442.\u0447. \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u044e Google App Engine \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e OAuth2.0, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0438 \u0442.\u0434. <br \/>  \u0421\u0435\u0440\u0432\u043b\u0435\u0442 \u043e\u0442\u0434\u0430\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:   <\/p>\n<pre><code class=\"java\">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();      \/\/ works both for Bloobstore and Cloud Storage     public void doGet(             HttpServletRequest req,             HttpServletResponse res     )             throws IOException {          \/\/ --- check user:         UserService userService = UserServiceFactory.getUserService();         User user = userService.getCurrentUser();         if (user == null) {             LOG.warning(&quot;[LOGGER] User not logged in&quot;);          } else {             LOG.warning(&quot;[LOGGER] user: &quot; + user.getEmail());         }          \/\/ get parameter from url constructed with:         \/\/ &quot;\/serve?blob-key=&quot; + blobKey.getKeyString()         BlobKey blobKey = new BlobKey(req.getParameter(&quot;blob-key&quot;));                  blobstoreService.serve(blobKey, res);     } } <\/code><\/pre>\n<p>  <\/p>\n<h4>Images Java API<\/h4>\n<p>  \u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Images Java API \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e  <\/p>\n<pre><code class=\"java\">ImagesServiceFactory.getImagesService().getServingUrl(         ServingUrlOptions.Builder.withGoogleStorageFileName(fileInfo.getGsObjectName()) );  <\/code><\/pre>\n<p>  \u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e   <\/p>\n<pre><code class=\"java\">ImagesServiceFactory.getImagesService().getServingUrl(         ServingUrlOptions.Builder.withBlobKey(blobKey) );  <\/code><\/pre>\n<p>  \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c URL \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0447\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430, \u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043a\u0430\u043a \u0431\u044b \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u00ab\u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0439\u00bb \u0444\u0430\u0439\u043b \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043a\u0430\u043a \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430. <br \/>  \u041d\u043e \u0442\u0430\u043a\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c, \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0430, \u0443\u0434\u0430\u043b\u0435\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/javadoc\/com\/google\/appengine\/api\/images\/ImagesService#deleteServingUrl-com.google.appengine.api.blobstore.BlobKey-\">.deleteServingUrl(BlobKey blobKey)<\/a> \u0421\u0430\u043c \u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f, \u0438 \u043d\u0430 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430. \u0422.\u0435. \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u00ab\u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u043c\u0438\u00bb \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0438 \u0443\u0434\u0430\u043b\u044f\u044f \u0438\u0445 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u043a \u0441\u0441\u044b\u043b\u043a\u0430\u043c \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e getServingUr() \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code> http:\/\/[image-url]=s200-fh-p-b10-c0xFFFF0000 <\/code>: <\/p>\n<p>  s640 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 640 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0433\u0440\u0430\u043d\u0438<br \/>  s0 \u2014 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u044b\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f!) <br \/>  w100 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0448\u0438\u0440\u0438\u043d\u043e\u0439 100 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 <br \/>  h100 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u043e\u0439 100 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 <br \/>  c \u2014 \u043e\u0431\u0440\u0435\u0437\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 (s200, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440)<br \/>  p \u2014 \u00ab\u0443\u043c\u043d\u043e\u0435\u00bb \u043e\u0431\u0440\u0435\u0437\u0430\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0441\u0442\u0430\u0440\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0434\u043e \u043b\u0438\u0446\u0430 (\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e)<br \/>  pp \u2014 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0447\u0442\u043e \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0443\u043d\u043a\u0442\u0435 (\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e)<br \/>  cc \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u0440\u0443\u0433\u043b\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <br \/>  fv \u2014 \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e<br \/>  fh \u2014 \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e<br \/>  r{90} \u2014 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432 \u043f\u043e \u0447\u0430\u0441\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0435 <br \/>  rj \u2014 \u0432\u044b\u0434\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JPG<br \/>  rp \u2014 \u0432\u044b\u0434\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 PNG<br \/>  rw \u2014 \u0432\u044b\u0434\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 WebP<br \/>  rg \u2014 \u0432\u044b\u0434\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 GIF<br \/>  b10 \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0430\u043c\u043a\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u044b (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 10px)<br \/>  c0xffff0000 \u2014 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0446\u0432\u0435\u0442 \u0440\u0430\u043c\u043a\u0438 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u0440\u0430\u0441\u043d\u044b\u0439)<br \/>  d \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 header \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435<br \/>  h \u2014 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 HTML \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f: <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1f2\/8bb\/cbb\/1f28bbcbbdc1f2dd7c364b4cae720cc8.jpg\" alt=\"image\"\/><br \/>  \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438: <code> =w100-h100-cc <\/code> \u2014 \u043c\u043e\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0440\u0443\u0433\u043b\u044b\u0439 \u0430\u0432\u0430\u0442\u0430\u0440; <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/ed5\/25e\/28b\/ed525e28b76be6b156ac53555dafbcc9.jpg\" alt=\"image\"\/><br \/>  \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438: <code> =s200-b3-c0xffff0000 <\/code> \u2014 thumbnail \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0433\u0440\u0430\u043d\u0438 \u0432 200px \u0441 \u043a\u0440\u0430\u0441\u043d\u043e\u0439 \u0440\u0430\u043c\u043a\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u043e\u0439 3px:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/db7\/dfa\/6eb\/db7dfa6ebae86c34546525ef1f103153.jpg\" alt=\"image\"\/><br \/>  \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f CSS, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u043d\u043e\u0435 \u0434\u043e \u043d\u0443\u0436\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432. <\/p>\n<p>  \u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0441\u043c. \u043d\u0430 <a href=\"http:\/\/stackoverflow.com\/questions\/25148567\/list-of-all-the-app-engine-images-service-get-serving-url-uri-options\">stackoverflow.com\/questions\/25148567\/list-of-all-the-app-engine-images-service-get-serving-url-uri-options<\/a>  <\/p>\n<h4>\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0443\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/cloud.google.com\/storage\/docs\/gsutil\">gsutil<\/a>)<\/h4>\n<p>  gsutil \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430 Python (\u0442\u0440\u0435\u0431\u0443\u0435\u0442 Python 2.6.x \u0438\u043b\u0438 2.7.x) \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 on Linux\/Unix, Mac OS, \u0438 Windows (XP \u0438 \u0432\u044b\u0448\u0435). <br \/>  \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0446\u0438\u0438: <a href=\"https:\/\/cloud.google.com\/storage\/docs\/gsutil_install\">cloud.google.com\/storage\/docs\/gsutil_install<\/a> <br \/>  \u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0446\u0438\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c:   <\/p>\n<pre><code class=\"bash\">gcloud auth login <\/code><\/pre>\n<p>  \u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f (\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u043d\u0430 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">habrahabr.ru\/post\/268863<\/a> ) <br \/>  gsutil \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u043d\u0430 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043a\u043e\u043d\u0441\u043e\u043b\u0438 Linux\/Unix, \u0444\u0430\u0439\u043b\u044b \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0442\u0441\u044f \u00ab\u043f\u0443\u0442\u0435\u043c\u00bb \u0432\u0438\u0434\u0430 gs:\/\/{\u0438\u043c\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430}, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 gs:\/\/hello-habrahabr-api.appspot.com <br \/>  \u0422\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0444\u0430\u0439\u043b\u0430\u0445 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0432\u0432\u043e\u0434\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443  <\/p>\n<pre><code class=\"bash\">gsutil ls gs:\/\/hello-habrahabr-api.appspot.com  <\/code><\/pre>\n<p>  \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e (Google account):   <\/p>\n<pre><code class=\"bash\">gsutil ls gs:\/\/* <\/code><\/pre>\n<p>  \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 ls \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>-l<\/code>, \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0444\u0430\u0439\u043b\u0430\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>-L<\/code>: <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/4ab\/5e7\/5c2\/4ab5e75c208e428a88ca6cbafb35366d.png\"\/><\/p>\n<p>  \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>cp<\/code>, <code>mv<\/code>, <code>rm<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code> gs:\/\/{\u0438\u043c\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430} \/{\u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435} <\/code> \u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u041e\u0421, \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f wildcard characters (<code> gs:\/\/* <\/code>) \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0445 gsutil: <a href=\"https:\/\/cloud.google.com\/storage\/docs\/gsutil\">cloud.google.com\/storage\/docs\/gsutil<\/a> <br \/>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 gsutil \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. <\/p>\n<h4>\u0421\u0441\u044b\u043b\u043a\u0438:<\/h4>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/cloud.google.com\/storage\/docs\/overview\">What is Google Cloud Storage?<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/googlecloudstorageclient\/\">Java Client for Google Cloud Storage<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/images\/\">Images Java API Overview<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/blobstore\/\">Blobstore Java API Overview<\/a><\/li>\n<\/ul>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/275211\/\"> http:\/\/habrahabr.ru\/post\/275211\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0412 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">\u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439<\/a> \u043e \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Java \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Google App Engine \/ Google Cloud Endpoints \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 Google Cloud Storage. <\/p>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c \u0441\u0445\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 (\u0430\u0434\u0440\u0435\u0441) \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 (bucket) \u043d\u0430\u0448\u0435\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043b\u0430. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u0442 POST HTTP-request \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432 \u0442\u0435\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0438 HTTP-request \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0432 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e HTTP response: JSON \u0438\u043b\u0438 text\/html, \u0438\u043b\u0438 \u0432 \u043e\u0431\u0449\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u0436\u0435\u043b\u0430\u0435\u043c. <\/p>\n<p>  \u0424\u0430\u0439\u043b\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0443 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430 \u0435\u0441\u0442\u044c \u0432 \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0438 \u043a\u043b\u044e\u0447 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430 \u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u00ab\u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0443\u044e\u00bb \u0441\u0441\u044b\u043b\u043a\u0443 (https:\/\/). <br \/>  \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0438 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u044b <a href=\"https:\/\/cloud.google.com\/storage\/docs\/gsutil\">gsutil<\/a>.   <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-272450","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/272450","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=272450"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/272450\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=272450"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=272450"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=272450"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}