Java Apache http库文件上载问题

时间:2017-03-28 19:04:21

标签: java php file-upload httpclient apache-httpclient-4.x

我有一个上传文件的网络服务。 (详情见第一个链接)

要与此Web服务通信,我使用org.apache.http库(Apache HttpComponents)。我找到了大部分代码,如果不是全部here

可悲的是,该解决方案仅适用于图片,尽管尝试上传视频时付出的努力仍显示Content Length too long的错误。为了尝试解决这个问题,我决定将其替换为当前使用的内容。首先使用HttpClientBuilder

HttpClient httpclient = HttpClientBuilder.create().disableContentCompression().build();

我尝试失败,因为它仍然会出现同样的错误,经过研究后我发现我需要使用CloseableHttpClient如下来禁用自动标题

CloseableHttpClient httpclient = HttpClients.custom()
        .setHttpProcessor(HttpProcessorBuilder.create().build())
        .build();

虽然有效,但在设置标题时,某些内容无法通过,我无法理解。我按照以下方式做到了

httppost.addHeader("Keep-Alive", "timeout=5, max=100");
httppost.addHeader("Connection", "Keep-Alive");
httppost.addHeader("Content-Type", "text/html; charset=UTF-8");

但在追踪回复时,这就是我所拥有的

Http Client Builder Trace
    Date,Tue, 28 Mar 2017 18:30:50 GMT
    Server,Apache/2.4.23 (Win64) PHP/7.0.10
    X-Powered-By,PHP/7.0.10
    Content-Length,43
    Keep-Alive,timeout=5, max=100
    Connection,Keep-Alive
    Content-Type,text/html; charset=UTF-8


Closable Response Trace
    Date,Tue, 28 Mar 2017 18:31:27 GMT
    Server,Apache/2.4.23 (Win64) PHP/7.0.10
    Content-Length,311
    Connection,close
    Content-Type,text/html; charset=iso-8859-1

我尝试将标头设置为响应,但我还没想到如何正确实例化它来设置标头。而且我也试图理解为什么没有考虑httppost。我错过了什么吗?

当我使用Closable时,最后一件事由于我猜错了标题,我不再上传了。

修改

上传视频时出错

Exception in thread "main" org.apache.http.ContentTooLongException: Content length is too long: 16363535
at org.apache.http.entity.mime.MultipartFormEntity.getContent(MultipartFormEntity.java:103)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:199)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:306)
at testfileupload.PostFile.main(PostFile.java:100)
C:\Users\User\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

修改

我在this之后更改了php的最大文件大小,但它仍显示相同的错误

更新

这是我处理multipart(我使用multipartform)

的方法
HttpEntity resEntity = MultipartEntityBuilder.create()
    .addBinaryBody("userfile", file, ContentType.create("video/mp4"), file.getName())
    .build();

我记得读一些关于它的事情(不确定)对于需要更高价值php.iniupload_max_filesize = 40M以及post_max_size = 40M我需要的memory_limit = 128M参数有点确定它(使用wamp64)。

我一直试图解决内容长度问题,因为..

我发现HttpEntity集合计算了长度并且我检查了它的2位值,我相信但是无论连接类型它只是不起作用并且坚持内容长度错误。

我也试过

HttpClient httpclient = HttpClients.custom().setDefaultHeaders(Arrays.asList(CustomHeader)).build();

但仍然没有。在这一点上,我高度怀疑它是关于设置标题,与HttpEntity与Multipart或HttpPost更相关,但它可能是其他。

上传

我尝试使用大小约为350Kb的9s视频,但仍然会显示内容长度错误,这意味着可能存在默认内容集或根本没有内容

1 个答案:

答案 0 :(得分:0)

所以我不知道我做了什么/改变了但现在它处理错误。

我真的想知道为什么这会导致一个它到目前为止没有意义的错误,除非它调用的东西不能占用太高的值(param类型的方法给定的值超过它的值)可以)

要清楚当我使用它(验证区域)时会产生错误

System.out.println(response.getStatusLine());
if (resEntity != null) {
// error from below, kinda forgot about it
      System.out.println(EntityUtils.toString(resEntity));
}

    if (resEntity != null) {
//      resEntity.consumeContent();
    }

网络服务与第一个链接相同。

以下是我的代码(不介意我没有删除/删除/替换/测试/不同方法的评论)

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.util.EntityUtils;


public class PostFile {
  public static void main(String[] args) throws Exception {
//    HttpClient httpclient = new DefaultHttpClient();

//    CloseableHttpClient httpclient = HttpClients.custom()
//        .setHttpProcessor(HttpProcessorBuilder.create().build())
//        .build();

//    Header headerCustom = new BasicHeader(HttpHeaders.CONTENT_LENGTH, "15");


//    HttpClient httpclient = HttpClients.custom().build();

//        HttpClient httpclient = HttpClientBuilder.create().disableContentCompression().build();
   HttpClient httpclient = HttpClientBuilder.create().build();     
//    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);


    HttpPost httppost = new HttpPost("http://localhost/userVids/upload.php");

    httppost.setProtocolVersion(new ProtocolVersion("HTTP", 1, 1));
    File file = new File("C:/Users/User/Desktop/test_video.mp4");

//    httppost.addHeader("Content-Length", String.valueOf(file.length()));

//    MultipartEntity mpEntity = new MultipartEntity();
//    ContentBody cbFile = new FileBody(file, ContentType.MULTIPART_FORM_DATA);
//    mpEntity.addPart("userfile", cbFile);
//      System.out.println(mpEntity.getContentLength());
//
//    httppost.setEntity(mpEntity);

    /*
        Date,Tue, 28 Mar 2017 18:30:50 GMT
        Server,Apache/2.4.23 (Win64) PHP/7.0.10
        X-Powered-By,PHP/7.0.10
        Content-Length,43
        Keep-Alive,timeout=5, max=100
        Connection,Keep-Alive
        Content-Type,text/html; charset=UTF-8
    */

    /*
        Date,Tue, 28 Mar 2017 18:31:27 GMT
        Server,Apache/2.4.23 (Win64) PHP/7.0.10
        Content-Length,311
        Connection,close
        Content-Type,text/html; charset=iso-8859-1
    */

    HttpEntity resEntity = MultipartEntityBuilder.create()
        .addBinaryBody("userfile", file, ContentType.create("video/mp4"), file.getName())
        .build();

      System.out.println("Entity Length " + resEntity.getContentLength());
//    httppost.addHeader("Keep-Alive", "timeout=5, max=100");
//    httppost.addHeader("Connection", "Keep-Alive");
//    httppost.addHeader("Content-Type", "text/html; charset=UTF-8");

//    httppost.addHeader("Content-Disposition", "form-data; name=\"userfile\"; filename=\"star_empty.png\"");
//    httppost.addHeader("Content-Type", "image/png");
//    httppost.addHeader("Content-Transfer-Encoding", "binary");
//    httppost.addHeader("Content-Length", "99999");

    httppost.setEntity(resEntity);

    System.out.println("executing request " + httppost.getRequestLine());
    HttpResponse response = httpclient.execute(httppost);
//    HttpEntity resEntity = response.getEntity();

    System.out.println("Headers (name,value)");
    List<Header> httpHeaders = Arrays.asList(response.getAllHeaders());        
    httpHeaders.forEach((header) -> {
        System.out.println(header.getName() + "," + header.getValue());
    });

    System.out.println(response.getStatusLine());
    if (resEntity != null) {
      System.out.println(EntityUtils.toString(resEntity));
    }
    if (resEntity != null) {
//      resEntity.consumeContent();
    }

//    httpclient.getConnectionManager().shutdown();
  }
}

但是一个巨大的通知我有我的php.ini(在wamp中更改了所有这些并不知道它是否只会考虑正在运行的版本或读取所有内容(没有#n测试))并将值更改为http://www.dbforums.com/showthread.php?575408-db2-OS390-TABLE-LOCK-DURING-DELETE(他修正了它,即我只是提供谁需要或可能解释)说,他值得赞扬。 (我确信它之前没有工作,我只是测试了很多而且不记得了。)