我正在尝试在 Google App Engine 上创建一个允许将视频上传到 Blobstore 的 REST API。在我的本地开发服务器上一切正常,但在部署到 GAE 时失败。在 GAE 上,它存储视频,但不调用我的回调 URL。相反,它返回一个 302,并将位置标头设置为我的回调 URL。我尝试从客户端手动访问回调 URL,但 GAE 然后抛出异常:java.lang.IllegalStateException: Must be called from a blob upload callback request
. 我正在使用 Spring MVC。
客户端上传代码:
/**
* URL has been generated by going to /game/{gameId}/video
*/
private void uploadVideo(String uploadUrl) throws Exception {
HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
HttpPost post = new HttpPost(uploadUrl);
MultipartEntity mp = new MultipartEntity();
File video = new File("src/test/resources/video.mp4");
assertTrue("Couldn't find video file.", video.exists());
mp.addPart("video", new FileBody(video));
post.setEntity(mp);
HttpResponse resp = httpClient.execute(post);
//Getting 302 here.
assertEquals("Unexpected HTTP status code.", 200, resp.getStatusLine().getStatusCode());
}
服务器代码:
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
/**
* Create a video entity and generate an upload URL.
*/
@RequestMapping(value = "/game/{gameId}/video", method=RequestMethod.POST)
@ResponseBody
public VideoMeta createVideo(@PathVariable Long gameId, @RequestBody VideoMeta meta, Principal auth) {
//Omitted authentication and video creation logic
//Get blobstore upload URL. Callback is /video/{videoId}/blob.
String uploadUrl = blobstoreService.createUploadUrl("/video/" + video.getId() + "/blob");
//Create response
VideoMeta videoMeta = new VideoMeta();
videoMeta.setVideoId(video.getId());
videoMeta.setUploadUrl(uploadUrl);
return videoMeta;
}
/**
* This method is never called on GAE!
*/
@RequestMapping(value = "/video/{videoId}/blob", method=RequestMethod.POST)
@ResponseBody
public VideoMeta uploadVideo(@PathVariable Long videoId, HttpServletRequest req) {
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
List<BlobKey> blobKeys = blobs.get("video");
blobstoreService.getByteRange(req);
int numBlobs = blobKeys.size();
if(numBlobs != 1) {
throw new RestException(HttpServletResponse.SC_NOT_ACCEPTABLE, "You should upload exactly one blob.");
}
BlobKey blobKey = blobKeys.get(0);
//Omitted video update logic
VideoMeta videoMeta = new VideoMeta();
videoMeta.setVideoId(video.getId());
return videoMeta;
}