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

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

2.2 服务端处理

无论客户端是哪种上传方式,服务端的处理都是一样的。在通过HttpServletRequest获得参数之后,把得到的Item进行分类,分为普通的表单和File表单。

通过ServletFileUpload 可以设置上传文件的大小及编码格式等。

总之,服务端的处理是把得到的参数当做HTML表单进行处理的。

public void processUpload(HttpServletRequest request, HttpServletResponse response){
    File uploadFile = new File(uploadPath);
    if (!uploadFile.exists()) {
      uploadFile.mkdirs();
    }

    System.out.println("Come on, baby .......");

    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8"); 

    //检测是不是存在上传文件
    boolean isMultipart = ServletFileUpload.isMultipartContent(request); 

    if(isMultipart){
      DiskFileItemFactory factory = new DiskFileItemFactory(); 

      //指定在内存中缓存数据大小,单位为byte,这里设为1Mb
      factory.setSizeThreshold(1024*1024); 

      //设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
      factory.setRepository(new File("D:\\temp")); 

      // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory); 

      // 指定单个上传文件的最大尺寸,单位:字节,这里设为50Mb
      upload.setFileSizeMax(50 * 1024 * 1024);  

      //指定一次上传多个文件的总尺寸,单位:字节,这里设为50Mb
      upload.setSizeMax(50 * 1024 * 1024);
      upload.setHeaderEncoding("UTF-8");

      List<FileItem> items = null; 

      try {
        // 解析request请求
        items = upload.parseRequest(request);
      } catch (FileUploadException e) {
        e.printStackTrace();
      } 

      if(items!=null){
        //解析表单项目
        Iterator<FileItem> iter = items.iterator();
        while (iter.hasNext()) {
          FileItem item = iter.next(); 

          //如果是普通表单属性
          if (item.isFormField()) {
            //相当于input的name属性  <input type="text" name="content">
            String name = item.getFieldName();

            //input的value属性
            String value = item.getString();

            System.out.println("属性:" + name + " 属性值:" + value);
          }
          //如果是上传文件
          else {
            //属性名
            String fieldName = item.getFieldName(); 

            //上传文件路径
            String fileName = item.getName();
            fileName = fileName.substring(fileName.lastIndexOf("/") + 1);// 获得上传文件的文件名 

            try {
              item.write(new File(uploadPath, fileName));
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
      }
    } 

    response.addHeader("token", "hello");
  }

服务端在处理之后,可以在Header中设置返回给客户端的简单信息。如果返回客户端是一个流的话,流的大小必须提前设置!

response.setContentLength((int) file.length());

3 文件下载

文件的下载可以使用HttpClient的GetMethod实现,还可以使用HttpGet方式、原始的HttpURLConnection方式。

3.1 客户端处理

3.1.1 GetMethod方式

此处的HttpClient是org.apache.commons.httpclient.HttpClient。

public void downLoad(String remoteFileName, String localFileName) {
    HttpClient client = new HttpClient();
    GetMethod get = null;
    FileOutputStream output = null;

    try {
      get = new GetMethod(URL_STR);
      get.setRequestHeader("userName", userName);
      get.setRequestHeader("passwd", passwd);
      get.setRequestHeader("fileName", remoteFileName);

      int i = client.executeMethod(get);

      if (SUCCESS == i) {
        System.out.println("The response value of token:" + get.getResponseHeader("token"));

        File storeFile = new File(localFileName);
        output = new FileOutputStream(storeFile);

        // 得到网络资源的字节数组,并写入文件
        output.write(get.getResponseBody());
      } else {
        System.out.println("DownLoad file occurs exception, the error code is :" + i);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if(output != null){
          output.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

      get.releaseConnection();
      client.getHttpConnectionManager().closeIdleConnections(0);
    }
  }

3.1.2 HttpGet方式

此处的HttpClient是org.apache.http.client.methods下的。

public void downLoad(String remoteFileName, String localFileName) {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    OutputStream out = null;
    InputStream in = null;

    try {
      HttpGet httpGet = new HttpGet(URL_STR);

      httpGet.addHeader("userName", userName);
      httpGet.addHeader("passwd", passwd);
      httpGet.addHeader("fileName", remoteFileName);

      HttpResponse httpResponse = httpClient.execute(httpGet);
      HttpEntity entity = httpResponse.getEntity();
      in = entity.getContent();

      long length = entity.getContentLength();
      if (length <= 0) {
        System.out.println("下载文件不存在!");
        return;
      }

      System.out.println("The response value of token:" + httpResponse.getFirstHeader("token"));

      File file = new File(localFileName);
      if(!file.exists()){
        file.createNewFile();
      }

      out = new FileOutputStream(file);
      byte[] buffer = new byte[4096];
      int readLength = 0;
      while ((readLength=in.read(buffer)) > 0) {
        byte[] bytes = new byte[readLength];
        System.arraycopy(buffer, 0, bytes, 0, readLength);
        out.write(bytes);
      }

      out.flush();

    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }finally{
      try {
        if(in != null){
          in.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

      try {
        if(out != null){
          out.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

3.1.3 HttpURLConnection方式

public void download3(String remoteFileName, String localFileName) {
    FileOutputStream out = null;
    InputStream in = null;

    try{
      URL url = new URL(URL_STR);
      URLConnection urlConnection = url.openConnection();
      HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;

      // true -- will setting parameters
      httpURLConnection.setDoOutput(true);
      // true--will allow read in from
      httpURLConnection.setDoInput(true);
      // will not use caches
      httpURLConnection.setUseCaches(false);
      // setting serialized
      httpURLConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
      // default is GET
      httpURLConnection.setRequestMethod("POST");
      httpURLConnection.setRequestProperty("connection", "Keep-Alive");
      httpURLConnection.setRequestProperty("Charsert", "UTF-8");
      // 1 min
      httpURLConnection.setConnectTimeout(60000);
      // 1 min
      httpURLConnection.setReadTimeout(60000);

      httpURLConnection.addRequestProperty("userName", userName);
      httpURLConnection.addRequestProperty("passwd", passwd);
      httpURLConnection.addRequestProperty("fileName", remoteFileName);

      // connect to server (tcp)
      httpURLConnection.connect();

      in = httpURLConnection.getInputStream();// send request to
                                // server
      File file = new File(localFileName);
      if(!file.exists()){
        file.createNewFile();
      }

      out = new FileOutputStream(file);
      byte[] buffer = new byte[4096];
      int readLength = 0;
      while ((readLength=in.read(buffer)) > 0) {
        byte[] bytes = new byte[readLength];
        System.arraycopy(buffer, 0, bytes, 0, readLength);
        out.write(bytes);
      }

      out.flush();
    }catch(Exception e){
      e.printStackTrace();
    }finally{
      try {
        if(in != null){
          in.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

      try {
        if(out != null){
          out.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

3.2 服务端处理

尽管客户端的处理方式不同,但是服务端是一样的。

public void processDownload(HttpServletRequest request, HttpServletResponse response){
    int BUFFER_SIZE = 4096;
    InputStream in = null;
    OutputStream out = null;

    System.out.println("Come on, baby .......");

    try{
      request.setCharacterEncoding("utf-8");
      response.setCharacterEncoding("utf-8");
      response.setContentType("application/octet-stream");

      String userName = request.getHeader("userName");
      String passwd = request.getHeader("passwd");
      String fileName = request.getHeader("fileName");

      System.out.println("userName:" + userName);
      System.out.println("passwd:" + passwd);
      System.out.println("fileName:" + fileName);

      //可以根据传递来的userName和passwd做进一步处理,比如验证请求是否合法等
      File file = new File(downloadPath + "\\" + fileName);
      response.setContentLength((int) file.length());
      response.setHeader("Accept-Ranges", "bytes");

      int readLength = 0;

      in = new BufferedInputStream(new FileInputStream(file), BUFFER_SIZE);
      out = new BufferedOutputStream(response.getOutputStream());

      byte[] buffer = new byte[BUFFER_SIZE];
      while ((readLength=in.read(buffer)) > 0) {
        byte[] bytes = new byte[readLength];
        System.arraycopy(buffer, 0, bytes, 0, readLength);
        out.write(bytes);
      }

      out.flush();

      response.addHeader("token", "hello 1");

    }catch(Exception e){
      e.printStackTrace();
       response.addHeader("token", "hello 2");
    }finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
        }
      }
      if (out != null) {
        try {
          out.close();
        } catch (IOException e) {
        }
      }
    }
  }

4 小结

HttpClient最基本的功能就是执行Http方法。一个Http方法的执行涉及到一个或者多个Http请求/Http响应的交互,通常这个过程都会自动被HttpClient处理,对用户透明。用户只需要提供Http请求对象,HttpClient就会将http请求发送给目标服务器,并且接收服务器的响应,如果http请求执行不成功,httpclient就会抛出异常。所以在写代码的时候注意finally的处理。

所有的Http请求都有一个请求列(request line),包括方法名、请求的URI和Http版本号。HttpClient支持HTTP/1.1这个版本定义的所有Http方法:GET,HEAD,POST,PUT,DELETE,TRACE和OPTIONS。上面的上传用到了Post,下载是Get。

目前来说,使用org.apache.commons.httpclient.HttpClient多一些。看自己了~

以上就是小编为大家带来的使用HttpClient实现文件的上传下载方法全部内容了,希望大家多多支持我们~

(0)

相关推荐

  • HttpClient基础解析

    本文讲述了HttpClient基础知识,对相关概念进行解释在这里分享给大家,供大家参考. 1. 请求执行: HttpClient最重要的功能是执行HTTP方法.执行HTTP方法涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient内部处理.用户期望提供一个请求对象来执行,并且希望HttpClient将请求发送到目标服务器返回相应的响应对象,如果执行失败则抛出异常. 很自然,HttpClient API的主要入口点是定义上述合同的HttpClient接口. 这是一个请求执行过程

  • httpclient模拟post请求json封装表单数据的实现方法

    废话不说上代码: public static String httpPostWithJSON(String url) throws Exception { HttpPost httpPost = new HttpPost(url); CloseableHttpClient client = HttpClients.createDefault(); String respContent = null; // json方式 JSONObject jsonParam = new JSONObject(

  • Java爬虫Jsoup+httpclient获取动态生成的数据

    Java爬虫Jsoup+httpclient获取动态生成的数据 前面我们详细讲了一下Jsoup发现这玩意其实也就那样,只要是可以访问到的静态资源页面都可以直接用他来获取你所需要的数据,详情情跳转-Jsoup爬虫详解,但是很多时候网站为了防止数据被恶意爬取做了很多遮掩,比如说加密啊动态加载啊,这无形中给我们写的爬虫程序造成了很大的困扰,那么我们如何来突破这个梗获取我们急需的数据呢, 下面我们来详细讲解一下如何获取 String startPage="https://item.jd.com/1147

  • java web中 HttpClient模拟浏览器登录后发起请求

    HttpClient模拟浏览器登录后发起请求 浏览器实现这个效果需要如下几个步骤: 1请求一个需要登录的页面或资源 2服务器判断当前的会话是否包含已登录信息.如果没有登录重定向到登录页面 3手工在登录页面录入正确的账户信息并提交 4服务器判断登录信息是否正确,如果正确则将登录成功信息保存到session中 5登录成功后服务器端给浏览器返回会话的SessionID信息保存到客户端的Cookie中 6浏览器自动跳转到之前的请求地址并携带之前的Cookie(包含登录成功的SessionID) 7服务器

  • java 中HttpClient传输xml字符串实例详解

    java 中HttpClient传输xml字符串实例详解 介绍:我现在有一个对象page,需要将page对象转换为xml格式并以binary方式传输到服务端 其中涉及到的技术点有: 1.对象转xml流 2.输出流转输入流 3.httpClient发送二进制流数据 POM文件依赖配置 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifact

  • Java使用HttpClient实现Post请求实例

    基于项目需求,想要实现Post消息推送,故采用HttpClient组件进行实现,相关代码如下(注:程序采用的httpclient和httpcore依赖包的版本为4.2.5): import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache

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

    1 HTTP HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源. 虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活.HttpClient 用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议. 一般的情况下我们都是使用Chrome或者

  • ASP.NET中文件上传下载方法集合

    文件的上传下载是我们在实际项目开发过程中经常需要用到的技术,这里给出几种常见的方法,本文主要内容包括: 1.如何解决文件上传大小的限制 2.以文件形式保存到服务器 3.转换成二进制字节流保存到数据库以及下载方法 4.上传Internet上的资源 第一部分: 首先我们来说一下如何解决ASP.NET中的文件上传大小限制的问题,我们知道在默认情况下ASP.NET的文件上传大小限制为2M,一般情况下,我们可以采用更改WEB.Config文件来自定义最大文件大小,如下: <httpRuntime exec

  • SocketIo+SpringMvc实现文件的上传下载功能

    socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址: https://github.com/fengcharly/sockeio-springMvcUpload.git 部分代码如下: 服务端的代码: ChuanServer: import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.c

  • Java实现七牛云文件图片上传下载

    目录 一.准备工作 1.1.为什么选择七牛云? 1.2.七牛云注册 二.java操作七牛云对象存储下载 2.1.pom.xml引入依赖 2.2.上传下载具体代码 三.具体业务例子(七牛云做图片服务器–SpringBoot) 四.总结 一.准备工作 1.1.为什么选择七牛云? 免费 免费 免费 而且注册之后每个月 有免费100 万 次get请求. 10G免费空间,10G免费流量,对于搭建自己的博客网站已经绰绰有余了. 1.2.七牛云注册 注册七牛云账号 获取自己的AK,SK: 二.java操作七牛

  • 前端vue+express实现文件的上传下载示例

    新建server.js yarn init -y yarn add express nodemon -D var express = require("express"); const fs = require("fs"); var path = require("path"); const multer = require("multer"); //指定路径的 var app = express(); app.use(exp

  • SpringMVC深入讲解文件的上传下载实现

    目录 SpringMVC文件下载 SpringMVC文件上传 1.基本介绍 2.需求分析/图解 3.应用实例 4.Debug-file.transferTo(目标文件) SpringMVC文件下载 说明: 在 SpringMVC 中,通过返回 ResponseEntity的类型,可以实现文件下载的功能 案例演示 1.修改 json.jsp <h1>下载文件的测试 </h1> <a href="<%=request.getContextPath()%>/d

  • Asp.net实现MVC处理文件的上传下载功能实例教程

    上传于下载功能是程序设计中非常常见的一个功能,在ASP.NET程序开发中有着非常广泛的应用.本文就以实例形式来实现这一功能. 一.概述 如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个,而这个控件的缺席给我们带来一些小问题.这篇文章主要说如何在Asp.net MVC中上传文件,然后如何再从服务器中把上传过的文件下载下来. 二.实现方法 1.文件上传

  • 利用ssh实现服务器文件上传下载

    通过ssh实现服务器文件上传下载 写在前面的话 之前记录过一篇使用apache的FTP开源组件实现服务器文件上传下载的方法,但是后来发现在删除的时候会有些权限问题,导致无法删除服务器上的文件.虽然在Windows上使用FileZilla Server设置读写权限后没问题,但是在服务器端还是有些不好用. 因为自己需要实现资源管理功能,除了单文件的FastDFS存储之外,一些特定资源的存储还是打算暂时存放服务器上,项目组同事说后面不会专门在服务器上开FTP服务,于是改成了sftp方式进行操作. 这个

  • Java实现FTP批量大文件上传下载篇1

    本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比较通用且功能较强的j-ftp类库,对一些比较常见的功能如进度条.断点续传.内外网的映射.在Applet中回调JavaScript函数等问题进行详细的阐述及代码实现,希望通过此文起到一个抛砖引玉的作用. 一.引子 笔者在实施一个项目过程中出现了一种基于Web的文件上传下载需求.在全省(或全国)各地的用

  • JAVA技术实现上传下载文件到FTP服务器(完整)

    具体详细介绍请看下文: 在使用文件进行交互数据的应用来说,使用FTP服务器是一个很好的选择.本文使用Apache Jakarta Commons Net(commons-net-3.3.jar) 基于FileZilla Server服务器实现FTP服务器上文件的上传/下载/删除等操作. 关于FileZilla Server服务器的详细搭建配置过程,详情请见 FileZilla Server安装配置教程 .之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲

随机推荐