- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试使用 google app engine blobstore 上传文件。
它应该像这样工作:您调用 BlobstoreService 来获取上传 URL,并提供回调 URL。客户端被重定向到上传 URL,发送数据,然后当他们完成后,他们将被重定向到回调 URL,其中包含几个代表 blobstore key 的参数。
正如我们将看到的,开发服务器的行为与生产服务器不同。
在生产环境中,我的代码完成了上传,然后没有重定向回我的回调 URL,而是收到了 400 错误响应(暗示我的请求有问题)。我如何在生产中调试它?我不知道如何打开 blobstore 的日志记录。
所以我尝试在开发服务器上本地运行它。这一次,如果我不设置“内容长度”属性,我会收到 411(未设置内容长度)。但如果我尝试设置该属性,我会得到“IllegalStateException:已经连接”。这些异常都不会发生在生产环境中。
所以我不知道下一步该去哪里。我需要让它在 dev 上工作,希望我可以在本地调试 blobstore,或者弄清楚为什么它不能在生产中的 blobstore 上工作。
public void upload(String uri, File file) throws IOException {
HttpURLConnection conn=null;
HttpURLConnection conn2=null;
FileInputStream fileInputStream = null;
DataOutputStream dos=null;
try {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
// open a URL connection to the Servlet
fileInputStream = new FileInputStream(file);
URL url = new URL(uri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
// conn.setChunkedStreamingMode(1024);
conn.setRequestProperty("content-length", String.valueOf(file.length())); //caused IllegalStateException "Already connected" locally, but not remotely
log("Orignal URL: " + conn.getURL());
//conn.connect(); //TODO duplicates url.openConnection() above?
conn.getInputStream(); //so we can follow the redirect
String redirectedUrl = conn.getHeaderField("Location");
log("Redirected URL: " + redirectedUrl);
//this is horrible and messy but let's get it working then clean it up later
conn.disconnect();
url = new URL(redirectedUrl);
// Open a new HTTP connection to the URL
conn2 = (HttpURLConnection) url.openConnection();
conn2.setDoInput(true); // Allow Inputs
conn2.setDoOutput(true); // Allow Outputs
conn2.setUseCaches(false); // Don't use a Cached Copy
conn2.setInstanceFollowRedirects(false);
conn2.setRequestMethod("POST");
conn2.setRequestProperty("Connection", "Keep-Alive");
conn2.setRequestProperty("ENCTYPE", "multipart/form-data");
conn2.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn2.setChunkedStreamingMode(maxBufferSize);
conn2.setRequestProperty("Content-Length", String.valueOf(file.length()));
conn2.connect();
dos = new DataOutputStream(conn2.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"myFile\";filename=\""+file.getName()+"\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
int serverResponseCode = conn2.getResponseCode();
String serverResponseMessage = conn2.getResponseMessage();
//we are expecting another redirect here
log("aaaargh! 400 instead of 302! "+serverResponseCode+" to "+conn2.getHeaderField("Location"));
}catch (IOException e) {
log(e.getMessage());
throw e;
}catch(Exception e) {
log(e.getMessage());
throw new IOException(e);
} finally {
//close the streams //
if (dos!=null) {
try {
dos.flush();
dos.close();
}catch(IOException ioe){}
}
if (fileInputStream!=null)
try {
fileInputStream.close();
}catch(IOException ioe){}
if (conn!=null )
try {
conn.disconnect();
}catch(Exception ioe){}
if (conn2!=null)
try {
conn2.disconnect();
}catch(Exception ioe){}
}
}
注意上面的 serverResponseMessage 字符串作为“错误请求”从生产 blobstore 返回
最佳答案
我不知道如何从 Android 客户端执行此操作,但我可以向您展示我们如何从 javascript 客户端执行此操作,因为它可能会给您一些指示。
客户端非常简单(这是一个 angular.js Controller ),我们获取要使用的 url 并上传到它
// model file upload
$scope.onFileSelect = function ($files) {
$scope.uploadStatus = 'loading';
for (var i = 0; i < $files.length; i++) {
var file = $files[i];
console.log(file);
$http.get('/endpoints/prototype/' + $scope.prototype.key + '/file/url')
.success((function (data) {
console.log(data);
$scope.upload = $upload.upload({
url: data,
withCredentials: true,
file: file
})
.success(function (data) {
console.log(data);
$scope.prototype.modelFile = data;
})
.error(function (data, status) {
console.error(data);
$scope.uploadStatus = 'error';
$scope.uploadError = status;
});
}))
.error((function (data, status) {
console.error(data);
$scope.uploadStatus = 'error';
$scope.uploadError = status;
}));
}
};
服务器端,我们有一个端点,它返回用于发布的 URL(这是一个 Spring MVC Controller )。注意我们在createUploadUrl()中指定成功路径
@RequestMapping(value = "/endpoints/prototype/{key}/file/url", method = RequestMethod.GET)
@ResponseBody
public String getFileUploadUrl(@PathVariable("key") String prototypeKey) {
final UploadOptions uploadOptions = Builder.withDefaults()
.googleStorageBucketName("palmyra-prototype-store");
return blobstoreService.createUploadUrl("/endpoints/prototype/" + prototypeKey + "/file", uploadOptions);
}
最后是上传成功后调用的端点
@RequestMapping(value = "/endpoints/prototype/{key}/file", method = RequestMethod.POST)
@ResponseBody
public String handleFileUpload(@PathVariable("key") String prototypeKey, HttpServletRequest request) {
final Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(request);
final Map<String, List<FileInfo>> allFileInfos = blobstoreService.getFileInfos(request);
final List<BlobKey> blobKeys = blobs.get(INPUT_FILE_NAME);
final List<FileInfo> fileInfos = allFileInfos.get(INPUT_FILE_NAME);
if ((blobKeys == null) || (fileInfos == null)) {
return "You failed to upload a model file for " + prototypeKey + " because the file was empty.";
} else if ((blobKeys.size() == 1) && (fileInfos.size() == 1)) {
final BlobKey blobKey = blobKeys.get(0);
final FileInfo fileInfo = fileInfos.get(0);
final Prototype prototype = prototypeService.findByKey(prototypeKey);
prototype.setModelFile(blobInfoFactory.loadBlobInfo(blobKey).getFilename());
prototype.setUploadedModelFile(fileInfo.getGsObjectName());
prototypeService.updatePrototype(prototypeKey, prototype);
return blobInfoFactory.loadBlobInfo(blobKey).getFilename();
} else {
return "One and only one file is allowed to be uploaded. The related prototype is " + prototypeKey +
". The number of blobs is " + blobKeys.size() + ", the number of files is " + fileInfos.size();
}
}
就是这样,希望它能帮助你解决你的问题。
关于java - 使用谷歌应用引擎将文件上传到 blobstore 时出现 http 400 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23798847/
以下代码: if (!(ep = engOpen("\0"))) { fprintf(stderr, "\nCan't start MATLAB engine\n");
我在谈论一些网络事物,例如 http://uservoice.com/ 你能推荐任何其他类似的服务、网站,或者可能是(甚至更好)一个现成的引擎来部署在自己的服务器上? 实际上,更多关于系统的问题,可以
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我正在寻找一个矩阵表达式解析器/引擎。例如, 3 * A + B * C 其中 A、B、C 是矩阵是一个典型的表达式。这应该类似于(单值)数学表达式解析器/引擎,但应该处理矩阵值和变量。我已经用谷歌搜
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 5年前关闭。 Improve this qu
是否有基于 .net 的 cometd 引擎?比如 Ajax 推送引擎 那是免费和开源的吗? 最佳答案 轨道式 Orbited是一个 HTTP 守护进程,针对长期 cometd 连接进行了优化。它旨在
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我正在寻找支持以下功能的 haml javascript“端口”: 存储在文件中的模板。 JSON 输入。 支持“集合”[{Booking},{Booking},{Booking}] 进行迭代处理。
我在 IronPython 中托管 IronPython。我没有找到使用等效的命令行参数初始化它的方法:-X:FullFrames . 我的代码有点像这样: import clr clr.AddRef
我想将我工作的公司的所有松散信息整合到一个知识库中。 Wiki 似乎是一种可行的方法,但大部分相关信息都隐藏在 PST 文件中,并且需要很长时间才能说服人们将他们的电子邮件(包括附件)手动翻译成 Wi
我已经使用缓存的 flutter 引擎 flutter 到现有的 native 应用程序(添加到应用程序)中。 override fun onCreate(savedInstanceState: Bu
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在使用 Django Cassandra我已经定义了我的模型,我可以用它来命名一个表: class Meta: db_table = "table_name" 但是,Cassand
类似于 NoSQL 数据库,但适用于 OLAP。当然是开源的:) 编辑: OLAP 引擎在幕后使用关系数据库。例如 SAPBW 可以使用 Oracle 等。我的意思是一个没有这个底层关系数据库的 OL
我正在使用以下片段来 enable Razor templating in my solution (在 ASP.NET MVC3 之外)。是否可以轻松实现布局? 背景资料: 我在这一点上(模板编译成
我们目前使用闭源知识库解决方案,所见即所得创建文章是TinyMCE(看起来可能是修改/简化的)。 他们目前根本不允许更改它(添加插件等,除非您可以以某种方式注入(inject)插件)。 我确实拥有对
我正在评估我们的高性能电信应用程序的 BPEL 引擎,但性能似乎很差。我们评估了 Apache Ode、SunBPEL 引擎、Active BPEL 等。您知道任何更快的 BPEL 引擎实现或 C/C
Elastic / Lucene真的需要在文档中存储所有索引数据吗?您难道不就通过通过传递数据,以便Lucene may index the words into its hash table并为每个
我是 3D 游戏新手?我正在使用 Libgdx。如何计算像 Tetromino Revolution 游戏这样的透视相机的参数?请给我任何想法。 看图片:http://www.terminalstud
我是一名优秀的程序员,十分优秀!