为啥上传图片到 Blobstore 后回调失败?
Posted
技术标签:
【中文标题】为啥上传图片到 Blobstore 后回调失败?【英文标题】:Why does callback fail after uploading image to Blobstore?为什么上传图片到 Blobstore 后回调失败? 【发布时间】:2015-01-29 18:47:27 【问题描述】:我正在尝试将照片上传到 blobstore。照片已成功上传到 blobstore,但我无法取回 blobkey 和 servingUrl。我尝试调试,发现没有对 BlobUpload.java 进行回调。它给出了一个错误“连接到 http://localhost:8888 被拒绝”我很困惑,因为 BlobUrlGet.java 调用没有问题并且照片已上传。我尝试了服务器和 servlet 的每种类型的 url,但它们都不起作用。
编辑: 我意识到如果我在调试模式(str 变量)中手动将“localhost:8888”更改为“10.0.2.2:8888”,“连接被拒绝”问题就会消失,但是这次它显示以下错误。
http://localhost:8888/_ah/upload/ahFteWZpcnN0YXBwZGVtbzEyM3IiCxIVX19CbG9iVXBsb2FkU2Vzc2lvbl9fGICAgICAgN4KDAError 405 HTTP 方法 POST 不受此 URL 支持
错误 405 HTTP 方法 POST 不受此 URL 支持
这是从 post 方法返回的。当我部署到 appengine 并从那里工作时,也是同样的错误。
我的代码如下。
BlobUrlGet.java
public class BlobUrlGet extends HttpServlet
BlobstoreService blServ = BlobstoreServiceFactory.getBlobstoreService();
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException
String blobUploadUrl = blServ.createUploadUrl("/blob");
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print(blobUploadUrl);
BlobUpload.java
public class BlobUpload extends HttpServlet
BlobstoreService blobstoreService = BlobstoreServiceFactory
.getBlobstoreService();
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException
try
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);
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("application/json");
JSONObject json = new JSONObject();
json.put("servingUrl", servingUrl);
json.put("blobKey", blobKey.getKeyString());
PrintWriter out = resp.getWriter();
out.print(json.toString());
out.flush();
out.close();
catch (JSONException e)
e.printStackTrace();
安卓客户端
private class GetBlobUrlTask extends AsyncTask<Void, Void, Void>
@Override
protected Void doInBackground(Void... arg0)
HttpClient httpClient = new DefaultHttpClient();
//This will invoke "ImgUpload servlet
HttpGet httpGet = new HttpGet("http://10.0.2.2:8888/bloburl");
HttpResponse response;
try
response = httpClient.execute(httpGet);
HttpEntity urlEntity = response.getEntity();
InputStream in = urlEntity.getContent();
String str = "";
StringWriter writer = new StringWriter();
String encoding = "UTF-8";
IOUtils.copy(in, writer, encoding);
str = writer.toString();
// str = URLDecoder.decode(str, "UTF-8");
HttpPost httppost = new HttpPost(str);
File f = new File(picturePath);
FileBody fileBody = new FileBody(f);
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.addPart("file", fileBody);
reqEntity.addBinaryBody("Photo", f, ContentType.create("image/jpeg"), "foto2.jpg");
httppost.setEntity(reqEntity.build());
response = httpClient.execute(httppost); //Here "uploaded" servlet is automatically invoked
urlEntity = response.getEntity(); //Response will be returned by "uploaded" servlet in JSON format
in = urlEntity.getContent();
str = "";
IOUtils.copy(in, writer, encoding);
str = writer.toString();
JSONObject resultJson = new JSONObject(str);
blobKey = resultJson.getString("blobKey");
servingUrl = resultJson.getString("servingUrl");
catch (ClientProtocolException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (JSONException e)
// TODO Auto-generated catch block
e.printStackTrace();
return null;
web.xml
<servlet>
<servlet-name>BlobstoreURL</servlet-name>
<servlet-class>com.google.samplesolutions.mobileassistant.BlobUrlGet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BlobstoreURL</servlet-name>
<url-pattern>/bloburl</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>BlobstoreUpload</servlet-name>
<servlet-class>com.google.samplesolutions.mobileassistant.BlobUpload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BlobstoreUpload</servlet-name>
<url-pattern>/blob</url-pattern>
</servlet-mapping>
提前致谢。
【问题讨论】:
【参考方案1】:doPost 应该被覆盖。现在它完美地工作了。
public class BlobUpload extends HttpServlet
BlobstoreService blobstoreService = BlobstoreServiceFactory
.getBlobstoreService();
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException
try
List<BlobKey> blobs = blobstoreService.getUploads(req).get("file");
BlobKey blobKey = blobs.get(0);
【讨论】:
以上是关于为啥上传图片到 Blobstore 后回调失败?的主要内容,如果未能解决你的问题,请参考以下文章
GAE Blobstore:ImagesService.getServingUrl() 给了我更小的图像
如何在将 Blob 上传到 Blobstore 的 POST 请求中提交文本字段并在 Blob 的上传处理程序中检索它?
上传到 Blobstore 会产生 Java 堆 OutOfMemoryError
从 android 客户端将图像存储到 Blobstore 并检索 blobkey 并上传 url 以存储在 Datastore 中。 - 盖伊