当前位置 主页 > 服务器问题 > Linux/apache问题 >

    使用HttpClient实现文件的上传下载方法

    栏目:Linux/apache问题 时间:2019-11-07 10:01

    1 HTTP

    HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。

    虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

    一般的情况下我们都是使用Chrome或者其他浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据、文件上传下载等等。所访问的这些页面有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS。目前我们使用的浏览器处理这些情况都不会构成问题。但是一旦我们有需求不通过浏览器来访问服务器的资源呢?那该怎么办呢?

    下面以本地客户端发起文件的上传、下载为例做个小Demo。HttpClient有两种形式,一种是org.apache.http下的,一种是org.apache.commons.httpclient.HttpClient。

    2 文件上传

    文件上传可以使用两种方式实现,一种是PostMethod方式,一种是HttpPost方式。两者的处理大同小异。PostMethod是使用FileBody将文件包装流包装起来,HttpPost是使用FilePart将文件流包装起来。在传递文件流给服务端的时候,都可以同时传递其他的参数。

    2.1 客户端处理

    2.1.1 PostMethod方式

    将文件封装到FilePart中,放入Part数组,同时,其他参数可以放入StringPart中,这里没有写,只是单纯的将参数以setParameter的方式进行设置。此处的HttpClient是org.apache.commons.httpclient.HttpClient。

     

    public void upload(String localFile){
        File file = new File(localFile);
        PostMethod filePost = new PostMethod(URL_STR);
        HttpClient client = new HttpClient();
        
        try {
          // 通过以下方法可以模拟页面参数提交
          filePost.setParameter("userName", userName);
          filePost.setParameter("passwd", passwd);
    
          Part[] parts = { new FilePart(file.getName(), file) };
          filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
          
          client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
          
          int status = client.executeMethod(filePost);
          if (status == HttpStatus.SC_OK) {
            System.out.println("上传成功");
          } else {
            System.out.println("上传失败");
          }
        } catch (Exception ex) {
          ex.printStackTrace();
        } finally {
          filePost.releaseConnection();
        }
      }

    记得搞完之后,要通过releaseConnection释放连接。

    2.1.2 HttpPost方式

    这种方式,与上面类似,只不过变成了FileBody。上面的Part数组在这里对应HttpEntity。此处的HttpClient是org.apache.http.client.methods下的。

    public void upload(String localFile){
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
          httpClient = HttpClients.createDefault();
          
          // 把一个普通参数和文件上传给下面这个地址 是一个servlet
          HttpPost httpPost = new HttpPost(URL_STR);
          
          // 把文件转换成流对象FileBody
          FileBody bin = new FileBody(new File(localFile));
    
          StringBody userName = new StringBody("Scott", ContentType.create(
              "text/plain", Consts.UTF_8));
          StringBody password = new StringBody("123456", ContentType.create(
              "text/plain", Consts.UTF_8));
    
          HttpEntity reqEntity = MultipartEntityBuilder.create()
              // 相当于<input type="file" name="file"/>
              .addPart("file", bin)
              
              // 相当于<input type="text" name="userName" value=userName>
              .addPart("userName", userName)
              .addPart("pass", password)
              .build();
    
          httpPost.setEntity(reqEntity);
    
          // 发起请求 并返回请求的响应
          response = httpClient.execute(httpPost);
          
          System.out.println("The response value of token:" + response.getFirstHeader("token"));
            
          // 获取响应对象
          HttpEntity resEntity = response.getEntity();
          if (resEntity != null) {
            // 打印响应长度
            System.out.println("Response content length: " + resEntity.getContentLength());
            // 打印响应内容
            System.out.println(EntityUtils.toString(resEntity, Charset.forName("UTF-8")));
          }
          
          // 销毁
          EntityUtils.consume(resEntity);
        }catch (Exception e){
          e.printStackTrace();
        }finally {
          try {
            if(response != null){
              response.close();
            }
          } catch (IOException e) {
            e.printStackTrace();
          }
          
          try {
            if(httpClient != null){
              httpClient.close();
            }
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }