过滤HTTPEntity输出以包含新行

时间:2018-05-22 21:52:06

标签: java android io

我正在使用org.apache.http.HttpEntityHTTPURLConnection执行多部分/表单数据POST以上传文件。

以下是我正在使用的代码。

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
String part1 = "\n{\"name\":\"test.txt\",\"creationTime\":1527023510389,\"fileUri\":\"/storage/test.txt\"}";
File file = new File("/storage/test.txt");

HttpEntity entity = MultipartEntityBuilder.create()
                .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addBinaryBody("data", part1.getBytes(), ContentType.APPLICATION_JSON, "data.txt")
                .addBinaryBody("file", file, ContentType.TEXT_PLAIN, filename)
                .setBoundary(boundaryString)
                .build();
OutputStream os = conn.getOutputStream();
entity.writeTo(os);

我发现身体正在发布如下。

--BOUNDARY
Content-Disposition: form-data; name="metadata"; filename="metadata.txt"
Content-Type: application/json 
{"name":"test.txt","creationTime":1527023510389,"fileUri":"/storage/test.txt"}
--BOUNDARY
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain; charset=ISO-8859-1
test file contents
--BOUNDARY--

问题是服务器需要Content-Type和第一部分内容之间的新行。我尝试在初始内容中添加额外的"\n"(如图所示,但在使用HttpEntity.writeto()时会被删除。

我想要的输出如下:

--BOUNDARY
Content-Disposition: form-data; name="metadata"; filename="metadata.txt"
Content-Type: application/json 

{"name":"test.txt","creationTime":1527023510389,"fileUri":"/storage/test.txt"}
--BOUNDARY
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain; charset=ISO-8859-1

test file contents
--BOUNDARY--

我试图修改输出的重写,但不确定这是否是通过存储在临时文件中来实现的最佳方法。如果有任何不同,我将使用的文件将高达20mb。

entity.writeTo(new FileOutputStream("file.tmp"));

BufferedReader reader = new BufferedReader(new FileReader("file.tmp"));
OutputStream os = conn.getOutputStream();
PrintWriter writer = new PrintWriter(new BufferedOutputStream(os));
String str;
while ((str = reader.readLine()) != null) {
    writer.println(str);
    if (str.contains("Content-Type: ")) {
        writer.println("\n");
    }
}
writer.close();
reader.close();
os.close();

conn.connect();

if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
    // It's failing when accessing the above method
}

我尝试运行上面的代码,但是出现以下错误:

java.lang.IllegalStateException: state: 2
    at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:234)
    at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:104)
    at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:1156)
    at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:976)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:509)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:438)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:567)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java)

1 个答案:

答案 0 :(得分:0)

事实证明,HttpEntity.writeTo方法正在放置必要的新行,但当我将输出打印到System.out时,Android Studio的Logcat不会显示简单的新行。我通过打开上面创建的file.tmp确认了这一点,并且在那里有适当的新行。看起来请求中存在其他一些错误,因为正文对服务器有效。

编辑:在我的请求中发现错误。我没有设置Content-Type(我想我删除了一些其他代码时删除了它)。我最终使用它来设置内容类型。

conn.addRequestProperty(entity.getContentType().getName(), entity.getContentType().getValue());