Java Http Client通过POST上传文件

我正在开发一个J2ME客户端,它必须使用HTTP将文件上传到Servlet。

使用Apache Commons FileUpload覆盖servlet部分

protected void doPost(HttpServletRequest request, HttpServletResponse response) { ServletFileUpload upload = new ServletFileUpload(); upload.setSizeMax(1000000); File fileItems = upload.parseRequest(request); // Process the uploaded items Iterator iter = fileItems.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); File file = new File("\files\\"+item.getName()); item.write(file); } } 

Commons Upload似乎只能上传多部分文件,但没有application / octect-stream。

但是对于客户端,没有Multipart类,在这种情况下,也不可能使用任何HttpClient库。

其他选项可能是使用HTTP Chunk上传,但我还没有找到一个明确的例子,说明如何实现它,特别是在servlet端。

我的选择是: – 为http块上传实现一个servlet – 为http多部分创建实现一个原始客户端

我不知道如何实现上述选项。 有什么建议吗?

通过HTTP发送文件应该使用multipart/form-data编码进行。 您的servlet部分很好,因为它已经使用Apache Commons FileUpload来解析multipart/form-data请求。

但是,您的客户端部分显然不是很好,因为您似乎正在将文件内容原始写入请求正文。 您需要确保客户端发送正确的multipart/form-data请求。 具体操作方法取决于您用于发送HTTP请求的API。 如果它是普通的vanilla java.net.URLConnection ,那么你可以在这个答案的底部附近找到一个具体的例子。 如果您正在使用Apache HttpComponents Client ,那么这是一个具体的例子:

 HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(url); MultipartEntity entity = new MultipartEntity(); entity.addPart("file", new FileBody(file)); post.setEntity(entity); HttpResponse response = client.execute(post); // ... 

具体问题无关 ,您的服务器端代码中存在一个错误:

 File file = new File("\files\\"+item.getName()); item.write(file); 

这可能会覆盖任何以前上传的具有相同名称的文件。 我建议使用File#createTempFile()代替。

 String name = FilenameUtils.getBaseName(item.getName()); String ext = FilenameUtils.getExtension(item.getName()); File file = File.createTempFile(name + "_", "." + ext, new File("/files")); item.write(file); 

以下代码可用于使用HTTP Client 4.x上传文件(以上答案使用现已弃用的MultipartEntity)

 import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; String uploadFile(String url, File file) throws IOException { HttpPost post = new HttpPost(url); post.setHeader("Accept", "application/json"); _addAuthHeader(post); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // fileParamName should be replaced with parameter name your REST API expect. builder.addPart("fileParamName", new FileBody(file)); //builder.addPart("optionalParam", new StringBody("true", ContentType.create("text/plain", Consts.ASCII))); post.setEntity(builder.build()); HttpResponse response = getClient().execute(post);; int httpStatus = response.getStatusLine().getStatusCode(); String responseMsg = EntityUtils.toString(response.getEntity(), "UTF-8"); // If the returned HTTP response code is not in 200 series then // throw the error if (httpStatus < 200 || httpStatus > 300) { throw new IOException("HTTP " + httpStatus + " - Error during upload of file: " + responseMsg); } return responseMsg; } 

您将需要以下Apache库的最新版本:httpclient,httpcore,httpmime。

getClient()可以用HttpClients.createDefault()替换。

感谢所有我已经狙击的代码…这里有一些回来。

 Gradle compile "org.apache.httpcomponents:httpclient:4.4" compile "org.apache.httpcomponents:httpmime:4.4" import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; public class HttpClientUtils { public static String post(String postUrl, Map params, Map files) throws ClientProtocolException, IOException { CloseableHttpResponse response = null; InputStream is = null; String results = null; CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost(postUrl); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); if (params != null) { for (String key : params.keySet()) { StringBody value = new StringBody(params.get(key), ContentType.TEXT_PLAIN); builder.addPart(key, value); } } if (files != null && files.size() > 0) { for (String key : files.keySet()) { String value = files.get(key); FileBody body = new FileBody(new File(value)); builder.addPart(key, body); } } HttpEntity reqEntity = builder.build(); httppost.setEntity(reqEntity); response = httpclient.execute(httppost); // assertEquals(200, response.getStatusLine().getStatusCode()); HttpEntity entity = response.getEntity(); if (entity != null) { is = entity.getContent(); StringWriter writer = new StringWriter(); IOUtils.copy(is, writer, "UTF-8"); results = writer.toString(); } } finally { try { if (is != null) { is.close(); } } catch (Throwable t) { // No-op } try { if (response != null) { response.close(); } } catch (Throwable t) { // No-op } httpclient.close(); } return results; } public static String get(String getStr) throws IOException, ClientProtocolException { CloseableHttpResponse response = null; InputStream is = null; String results = null; CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpGet = new HttpGet(getStr); response = httpclient.execute(httpGet); assertEquals(200, response.getStatusLine().getStatusCode()); HttpEntity entity = response.getEntity(); if (entity != null) { is = entity.getContent(); StringWriter writer = new StringWriter(); IOUtils.copy(is, writer, "UTF-8"); results = writer.toString(); } } finally { try { if (is != null) { is.close(); } } catch (Throwable t) { // No-op } try { if (response != null) { response.close(); } } catch (Throwable t) { // No-op } httpclient.close(); } return results; } } 

没有输入血腥细节你的代码看起来很好。

现在你需要服务器端。 我建议你使用Jakarta FileUpload ,这样你就不必实现任何东西了。 只需部署和配置。