1

我想将文件从 blobstore 上传到名为 Wisita 的服务。这是上传 API 的文档:

http://wistia.com/doc/upload-api

到目前为止,这是我的代码(我想我可能会错过 ssl 选项)

FileService fileService = FileServiceFactory.getFileService();
AppEngineFile binaryFile = fileService.getBlobFile(new BlobKey("my blob key"));

String param = "api_password=" + URLEncoder.encode("my wisita key", "UTF-8") +
                "&project_id=" + URLEncoder.encode("folder_id", "UTF-8");
String charset = "UTF-8";

String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.

URLConnection connection = new URL("https://upload.wistia.com/").openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
    OutputStream output = connection.getOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!

    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF);
    writer.append(param).append(CRLF).flush();

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getNamePart() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getNamePart())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    InputStream input = null;
    try {
            FileReadChannel ch = fileService.openReadChannel(binaryFile, true);
            input = Channels.newInputStream(ch);
            byte[] buffer = new byte[1024];
            for (int length = 0; (length = input.read(buffer)) > 0;) {
                output.write(buffer, 0, length);
            }
            output.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
    } finally {
            if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
            }
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of binary boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF);

    //resp part
    InputStream responseStream = new BufferedInputStream(connection.getInputStream());

    BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
    String line = "";
    StringBuilder stringBuilder = new StringBuilder();
    while ((line = responseStreamReader.readLine()) != null)
    {
        stringBuilder.append(line).append("\n");
    }
    responseStreamReader.close();
    String response = stringBuilder.toString();
    resp.getWriter().write(response);

    } finally {
        if (writer != null) writer.close();
    }

我收到此代码的 500 错误

4

2 回答 2

1

Thank you for your question. As a reference it solved the issue I was having doing a similar task.

The first change I made to my code was to set both the doOutput and the doInput to true (not just the doOutput). I'm not sure if that makes a difference, since I believe true is the default.

con.setDoOutput(true);
con.setDoInput(true);

Are you sure your content is being encoded correctly? I used the same setup and configuration you have, but instead of using a PrintWriter, I just called write and passed it the bytes from my String and bytes from my File contents:

connection.getOutputStream().write("Content-Disposition blah...".getBytes());
connection.getOutputStream().write(fileContentsByteArray);
connection.flush();

I then just read the data I needed back from my web service by reading from the connection's input stream like this:

FileOutputStream out = new FileOutputStream("received.bin");
InputStream in = connection.getInputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
out.close();
于 2013-05-06T21:36:10.173 回答
0

如何更改传递正常参数?

前:

param=..api_password...project_id...;
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(param).append(CRLF).flush();

后:

// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"api_password\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(api_password).append(CRLF).flush();
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"project_id\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(project_id).append(CRLF).flush();
于 2014-10-13T09:49:49.707 回答