HttpClient文件上传下载
1 HTTP
HTTP 协议可能是如今 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序须要直接通过 HTTP 协议来訪问网络资源。
尽管在 JDK 的 java.net 包中已经提供了訪问 HTTP 协议的基本功能,可是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 用来提供高效的、最新的、功能丰富的支持 HTTP 协议的client编程工具包,而且它支持 HTTP 协议最新的版本号和建议。
一般的情况下我们都是使用Chrome或者其它浏览器来訪问一个WEBserver,用来浏览页面查看信息或者提交一些数据、文件上传下载等等。所訪问的这些页面有的不过一些普通的页面,有的须要用户登录后方可使用,或者须要认证以及是一些通过加密方式传输,比如HTTPS。
眼下我们使用的浏览器处理这些情况都不会构成问题。
可是一旦我们有需求不通过浏览器来訪问server的资源呢?那该怎么办呢?
以下以本地客户端发起文件的上传、下载为例做个小Demo。HttpClient有两种形式,一种是org.apache.http下的,一种是org.apache.commons.httpclient.HttpClient。
2 文件上传
文件上传能够使用两种方式实现,一种是PostMethod方式,一种是HttpPost方式。两者的处理大同小异。PostMethod是使用FileBody将文件包装流包装起来,HttpPost是使用FilePart将文件流包装起来。在传递文件流给服务端的时候。都能够同一时候传递其它的參数。
2.1 client处理
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 }
2.2 服务端处理
不管client是哪种上传方式,服务端的处理都是一样的。
在通过HttpServletRequest获得參数之后,把得到的Item进行分类,分为普通的表单和File表单。
通过ServletFileUpload 能够设置上传文件的大小及编码格式等。
总之。服务端的处理是把得到的參数当做HTML表单进行处理的。
1 public void processUpload(HttpServletRequest request, HttpServletResponse response){
2 File uploadFile = new File(uploadPath);
3 if (!uploadFile.exists()) {
4 uploadFile.mkdirs();
5 }
6
7 System.out.println("Come on, baby .......");
8
9 request.setCharacterEncoding("utf-8");
10 response.setCharacterEncoding("utf-8");
11
12 //检測是不是存在上传文件
13 boolean isMultipart = ServletFileUpload.isMultipartContent(request);
14
15 if(isMultipart){
16 DiskFileItemFactory factory = new DiskFileItemFactory();
17
18 //指定在内存中缓存数据大小,单位为byte,这里设为1Mb
19 factory.setSizeThreshold(1024*1024);
20
21 //设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的文件夹
22 factory.setRepository(new File("D:\\temp"));
23
24 // Create a new file upload handler
25 ServletFileUpload upload = new ServletFileUpload(factory);
26
27 // 指定单个上传文件的最大尺寸,单位:字节,这里设为50Mb
28 upload.setFileSizeMax(50 * 1024 * 1024);
29
30 //指定一次上传多个文件的总尺寸,单位:字节。这里设为50Mb
31 upload.setSizeMax(50 * 1024 * 1024);
32 upload.setHeaderEncoding("UTF-8");
33
34 List<FileItem> items = null;
35
36 try {
37 // 解析request请求
38 items = upload.parseRequest(request);
39 } catch (FileUploadException e) {
40 e.printStackTrace();
41 }
42
43 if(items!=null){
44 //解析表单项目
45 Iterator<FileItem> iter = items.iterator();
46 while (iter.hasNext()) {
47 FileItem item = iter.next();
48
49 //假设是普通表单属性
50 if (item.isFormField()) {
51 //相当于input的name属性 <input type="text" name="content">
52 String name = item.getFieldName();
53
54 //input的value属性
55 String value = item.getString();
56
57 System.out.println("属性:" + name + " 属性值:" + value);
58 }
59 //假设是上传文件
60 else {
61 //属性名
62 String fieldName = item.getFieldName();
63
64 //上传文件路径
65 String fileName = item.getName();
66 fileName = fileName.substring(fileName.lastIndexOf("/") + 1);// 获得上传文件的文件名称
67
68 try {
69 item.write(new File(uploadPath, fileName));
70 } catch (Exception e) {
71 e.printStackTrace();
72 }
73 }
74 }
75 }
76 }
77
78 response.addHeader("token", "hello");
79 }
服务端在处理之后。能够在Header中设置返回给client的简单信息。假设返回client是一个流的话,流的大小必须提前设置!
response.setContentLength((int) file.length());
3 文件下载
文件的下载能够使用HttpClient的GetMethod实现。还能够使用HttpGet方式、原始的HttpURLConnection方式。
3.1 client处理
3.1.1 GetMethod方式
此处的HttpClient是org.apache.commons.httpclient.HttpClient。
1 public void downLoad(String remoteFileName, String localFileName) {
2 HttpClient client = new HttpClient();
3 GetMethod get = null;
4 FileOutputStream output = null;
5
6 try {
7 get = new GetMethod(URL_STR);
8 get.setRequestHeader("userName", userName);
9 get.setRequestHeader("passwd", passwd);
10 get.setRequestHeader("fileName", remoteFileName);
11
12 int i = client.executeMethod(get);
13
14 if (SUCCESS == i) {
15 System.out.println("The response value of token:" + get.getResponseHeader("token"));
16
17 File storeFile = new File(localFileName);
18 output = new FileOutputStream(storeFile);
19
20 // 得到网络资源的字节数组,并写入文件
21 output.write(get.getResponseBody());
22 } else {
23 System.out.println("DownLoad file occurs exception, the error code is :" + i);
24 }
25 } catch (Exception e) {
26 e.printStackTrace();
27 } finally {
28 try {
29 if(output != null){
30 output.close();
31 }
32 } catch (IOException e) {
33 e.printStackTrace();
34 }
35
36 get.releaseConnection();
37 client.getHttpConnectionManager().closeIdleConnections(0);
38 }
39 }
3.1.2 HttpGet方式
此处的HttpClient是org.apache.http.client.methods下的。
1 public void downLoad(String remoteFileName, String localFileName) {
2 DefaultHttpClient httpClient = new DefaultHttpClient();
3 OutputStream out = null;
4 InputStream in = null;
5
6 try {
7 HttpGet httpGet = new HttpGet(URL_STR);
8
9 httpGet.addHeader("userName", userName);
10 httpGet.addHeader("passwd", passwd);
11 httpGet.addHeader("fileName", remoteFileName);
12
13 HttpResponse httpResponse = httpClient.execute(httpGet);
14 HttpEntity entity = httpResponse.getEntity();
15 in = entity.getContent();
16
17 long length = entity.getContentLength();
18 if (length <= 0) {
19 System.out.println("下载文件不存在。");
20 return;
21 }
22
23 System.out.println("The response value of token:" + httpResponse.getFirstHeader("token"));
24
25 File file = new File(localFileName);
26 if(!file.exists()){
27 file.createNewFile();
28 }
29
30 out = new FileOutputStream(file);
31 byte[] buffer = new byte[4096];
32 int readLength = 0;
33 while ((readLength=in.read(buffer)) > 0) {
34 byte[] bytes = new byte[readLength];
35 System.arraycopy(buffer, 0, bytes, 0, readLength);
36 out.write(bytes);
37 }
38
39 out.flush();
40
41 } catch (IOException e) {
42 e.printStackTrace();
43 } catch (Exception e) {
44 e.printStackTrace();
45 }finally{
46 try {
47 if(in != null){
48 in.close();
49 }
50 } catch (IOException e) {
51 e.printStackTrace();
52 }
53
54 try {
55 if(out != null){
56 out.close();
57 }
58 } catch (IOException e) {
59 e.printStackTrace();
60 }
61 }
62 }
3.1.3 HttpURLConnection方式
1 public void download3(String remoteFileName, String localFileName) {
2 FileOutputStream out = null;
3 InputStream in = null;
4
5 try{
6 URL url = new URL(URL_STR);
7 URLConnection urlConnection = url.openConnection();
8 HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
9
10 // true -- will setting parameters
11 httpURLConnection.setDoOutput(true);
12 // true--will allow read in from
13 httpURLConnection.setDoInput(true);
14 // will not use caches
15 httpURLConnection.setUseCaches(false);
16 // setting serialized
17 httpURLConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
18 // default is GET
19 httpURLConnection.setRequestMethod("POST");
20 httpURLConnection.setRequestProperty("connection", "Keep-Alive");
21 httpURLConnection.setRequestProperty("Charsert", "UTF-8");
22 // 1 min
23 httpURLConnection.setConnectTimeout(60000);
24 // 1 min
25 httpURLConnection.setReadTimeout(60000);
26
27 httpURLConnection.addRequestProperty("userName", userName);
28 httpURLConnection.addRequestProperty("passwd", passwd);
29 httpURLConnection.addRequestProperty("fileName", remoteFileName);
30
31 // connect to server (tcp)
32 httpURLConnection.connect();
33
34 in = httpURLConnection.getInputStream();// send request to
35 // server
36 File file = new File(localFileName);
37 if(!file.exists()){
38 file.createNewFile();
39 }
40
41 out = new FileOutputStream(file);
42 byte[] buffer = new byte[4096];
43 int readLength = 0;
44 while ((readLength=in.read(buffer)) > 0) {
45 byte[] bytes = new byte[readLength];
46 System.arraycopy(buffer, 0, bytes, 0, readLength);
47 out.write(bytes);
48 }
49
50 out.flush();
51 }catch(Exception e){
52 e.printStackTrace();
53 }finally{
54 try {
55 if(in != null){
56 in.close();
57 }
58 } catch (IOException e) {
59 e.printStackTrace();
60 }
61
62 try {
63 if(out != null){
64 out.close();
65 }
66 } catch (IOException e) {
67 e.printStackTrace();
68 }
69 }
70 }
3.2 服务端处理
虽然client的处理方式不同,可是服务端是一样的。
1 public void processDownload(HttpServletRequest request, HttpServletResponse response){
2 int BUFFER_SIZE = 4096;
3 InputStream in = null;
4 OutputStream out = null;
5
6 System.out.println("Come on, baby .......");
7
8 try{
9 request.setCharacterEncoding("utf-8");
10 response.setCharacterEncoding("utf-8");
11 response.setContentType("application/octet-stream");
12
13 String userName = request.getHeader("userName");
14 String passwd = request.getHeader("passwd");
15 String fileName = request.getHeader("fileName");
16
17 System.out.println("userName:" + userName);
18 System.out.println("passwd:" + passwd);
19 System.out.println("fileName:" + fileName);
20
21 //能够依据传递来的userName和passwd做进一步处理,比方验证请求是否合法等
23 File file = new File(downloadPath + "\\" + fileName);
24 response.setContentLength((int) file.length());
25 response.setHeader("Accept-Ranges", "bytes");
26
27 int readLength = 0;
28
29 in = new BufferedInputStream(new FileInputStream(file), BUFFER_SIZE);
30 out = new BufferedOutputStream(response.getOutputStream());
31
32 byte[] buffer = new byte[BUFFER_SIZE];
33 while ((readLength=in.read(buffer)) > 0) {
34 byte[] bytes = new byte[readLength];
35 System.arraycopy(buffer, 0, bytes, 0, readLength);
36 out.write(bytes);
37 }
38
39 out.flush();
40
41 response.addHeader("token", "hello 1");
42
43 }catch(Exception e){
44 e.printStackTrace();
45 response.addHeader("token", "hello 2");
46 }finally {
47 if (in != null) {
48 try {
49 in.close();
50 } catch (IOException e) {
51 }
52 }
53 if (out != null) {
54 try {
55 out.close();
56 } catch (IOException e) {
57 }
58 }
59 }
60 }
4 小结
HttpClient最主要的功能就是运行Http方法。一个Http方法的运行涉及到一个或者多个Http请求/Http响应的交互,通常这个过程都会自己主动被HttpClient处理。对用户透明。
用户仅仅须要提供Http请求对象。HttpClient就会将http请求发送给目标server。而且接收server的响应,假设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文件上传下载的更多相关文章
- Struts的文件上传下载
Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...
- Android okHttp网络请求之文件上传下载
前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...
- Selenium2学习-039-WebUI自动化实战实例-文件上传下载
通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...
- 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)
1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...
- 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- ssh框架文件上传下载
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SpringMVC——返回JSON数据&&文件上传下载
--------------------------------------------返回JSON数据------------------------------------------------ ...
- 【FTP】FTP文件上传下载-支持断点续传
Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...
- NetworkComms 文件上传下载和客户端自动升级(非开源)
演示程序下载地址:http://pan.baidu.com/s/1geVfmcr 淘宝地址:https://shop183793329.taobao.com 联系QQ号:3201175853 许可:购 ...
随机推荐
- [Android学习笔记]startActivityForResult和onActivityResult的使用
发开过程中,免不了多个页面之间相互交互通信. Android中使用startActivityForResult方法和onActivityResult配合完成任务 startActivityForRes ...
- SilkTest高级进阶系列7-用PostMessage模拟鼠标
SilkTest可以通过调用Windows API来向控件发送消息,从而进行特定的操作.下面这段code使用PostMessage来向计算器上的清除键发送WM_LBUTTONDOWN和WM_LBUTT ...
- Android ARM汇编语言
简介 ARM是Advanced RISC Machine的首字母缩写,它可以称之为一家嵌入式处理器的提供商,也可以理解为一种处理器的架构,还可以将它作为一套完整的处理器指令集. 原生程序与ARM汇编语 ...
- DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区
DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区 DS Scheduler 0.7 发布,Linux 调度系统
- BZOJ 刷题记录 PART 6
[BZOJ2709]水的二分加验证.可是好像被读入萎到了... [BZOJ3229]强大的算法见此.被机房的一堆大神"推荐".于是被坑了...写了一个下午... [BZOJ3631 ...
- Graphical Shell with WebShell - WebOS Internals
Graphical Shell with WebShell - WebOS Internals Graphical Shell with WebShell From WebOS Internals J ...
- set echo on/off,set term on/off,set feedback off,set heading off命令(转)
1.term命令: 当和SPOOL命令联合使用时,可以取消SQLPLUS输出,查询结果仅仅存在于假脱机文件中 set term on:查询结果既显示于假脱机文件中,又在SQLPLUS中显示: s ...
- 金句: "對比MBA學位,我們更需要PSD學位的人!" Poor, Smart and Deep Desire to… | consilient_lollapalooza on Xanga
金句: "對比MBA學位,我們更需要PSD學位的人!" Poor, Smart and Deep Desire to… | consilient_lollapalooza on X ...
- qt安装遇到的错误
/usr/bin/ld: cannot find -lXrender collect2: ld returned 1 exit status make[1]: *** [../../../../lib ...
- JavaScript模板引擎
JavaScript模板引擎实例应用 在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及 ...