使用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。
1 public void upload(String localFile){ 2 File file = new File(localFile); 3 PostMethod filePost = new PostMethod(URL_STR); 4 HttpClient client = new HttpClient(); 5 6 try { 7 // 通过以下方法可以模拟页面参数提交 8 filePost.setParameter("userName", userName); 9 filePost.setParameter("passwd", passwd); 10 11 Part[] parts = { new FilePart(file.getName(), file) }; 12 filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams())); 13 14 client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); 15 16 int status = client.executeMethod(filePost); 17 if (status == HttpStatus.SC_OK) { 18 System.out.println("上传成功"); 19 } else { 20 System.out.println("上传失败"); 21 } 22 } catch (Exception ex) { 23 ex.printStackTrace(); 24 } finally { 25 filePost.releaseConnection(); 26 } 27 }
记得搞完之后,要通过releaseConnection释放连接。
2.1.2 HttpPost方式
这种方式,与上面类似,只不过变成了FileBody。上面的Part数组在这里对应HttpEntity。此处的HttpClient是org.apache.http.client.methods下的。
1 public void upload(String localFile){ 2 CloseableHttpClient httpClient = null; 3 CloseableHttpResponse response = null; 4 try { 5 httpClient = HttpClients.createDefault(); 6 7 // 把一个普通参数和文件上传给下面这个地址 是一个servlet 8 HttpPost httpPost = new HttpPost(URL_STR); 9 10 // 把文件转换成流对象FileBody 11 FileBody bin = new FileBody(new File(localFile)); 12 13 StringBody userName = new StringBody("Scott", ContentType.create( 14 "text/plain", Consts.UTF_8)); 15 StringBody password = new StringBody("123456", ContentType.create( 16 "text/plain", Consts.UTF_8)); 17 18 HttpEntity reqEntity = MultipartEntityBuilder.create() 19 // 相当于<input type="file" name="file"/> 20 .addPart("file", bin) 21 22 // 相当于<input type="text" name="userName" value=userName> 23 .addPart("userName", userName) 24 .addPart("pass", password) 25 .build(); 26 27 httpPost.setEntity(reqEntity); 28 29 // 发起请求 并返回请求的响应 30 response = httpClient.execute(httpPost); 31 32 System.out.println("The response value of token:" + response.getFirstHeader("token")); 33 34 // 获取响应对象 35 HttpEntity resEntity = response.getEntity(); 36 if (resEntity != null) { 37 // 打印响应长度 38 System.out.println("Response content length: " + resEntity.getContentLength()); 39 // 打印响应内容 40 System.out.println(EntityUtils.toString(resEntity, Charset.forName("UTF-8"))); 41 } 42 43 // 销毁 44 EntityUtils.consume(resEntity); 45 }catch (Exception e){ 46 e.printStackTrace(); 47 }finally { 48 try { 49 if(response != null){ 50 response.close(); 51 } 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 56 try { 57 if(httpClient != null){ 58 httpClient.close(); 59 } 60 } catch (IOException e) { 61 e.printStackTrace(); 62 } 63 } 64 }
相关推荐
创建一个 HttpClient 实例,这个实例需要调用 Dispose 方法释放资源,这里使用了 using 语句。接着调用 GetAsync,给它传递要调用的方法的地址,向服务器发送 Get 请求。