Java Http Client 通过 POST 上传文件

2022-09-02 19:50:10

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

Servlet 部分使用 Apache Commons FileUpload 进行介绍

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似乎只能上传多部分文件,但没有应用程序/八进制流。

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

另一种选择可能是使用HTTP Chunk upload,但我还没有找到一个明确的例子来说明如何实现这一点,特别是在servlet端。

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

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


答案 1

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

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

String url = "https://example.com";
File file = new File("/example.ext");

try (CloseableHttpClient client = HttpClients.createDefault()) {
    HttpPost post = new HttpPost(url);
    HttpEntity entity = MultipartEntityBuilder.create().addPart("file", new FileBody(file)).build();
    post.setEntity(entity);

    try (CloseableHttpResponse 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);

答案 2

以下代码可用于使用HTTP客户端4.x上传文件(上述答案使用多部分实体,现已弃用)

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()


推荐