`

HTTP-CLIENT文件上传下载

    博客分类:
  • java
 
阅读更多

copy from https://www.cnblogs.com/Scott007/p/3817285.html

 

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     }
复制代码

 

2.2 服务端处理

     无论客户端是哪种上传方式,服务端的处理都是一样的。在通过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中设置返回给客户端的简单信息。如果返回客户端是一个流的话,流的大小必须提前设置

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

3 文件下载

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

3.1 客户端处理

 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 服务端处理

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

复制代码
 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     }
复制代码

 

分享到:
评论

相关推荐

    前端开源库-ipfs-http-client

    例如,在一个社交网络应用中,用户可以直接上传图片到IPFS,通过`ipfs-http-client`将CID链接存储在区块链上,这样即使原始服务器下线,用户依然可以访问到他们的数据。 在使用`ipfs-http-client`时,开发者需要...

    jersey-core、jersey-client jar包.rar

    在实现跨服务器文件上传时,首先需要配置jersey-client,设置目标服务器的URL、HTTP方法(通常是POST)以及文件的MIME类型。然后,使用jersey-client的API创建一个请求实体,将文件内容附加到请求中。此外,可能还...

    springmvc远程上传文件jersey-client

    总之,通过结合Spring MVC的文件上传能力和Jersey Client的HTTP请求功能,我们可以实现远程文件上传,这对于分布式系统或者需要跨服务器协作的场景非常有用。同时,理解并熟练掌握这两个工具对于提升Java Web开发...

    fastdfs-client-javajar1.27-SNAPSHOT.zip

    3. 使用API:FastDFS提供了一系列的Java API,用于文件的上传、下载、删除等操作。 总的来说,FastDFS客户端Java版是Java开发者与FastDFS服务交互的重要工具,它的使用涉及到项目构建配置、网络通信以及文件操作等...

    fastdfs-client-java-1.27-SNAPSHOT.zip

    3. **文件上传**:通过客户端API将本地文件上传至FastDFS系统,上传过程中,FastDFS会自动进行负载均衡和文件复制,确保高可用性。 4. **文件下载**:根据文件的存储路径,从FastDFS系统中下载文件到本地。 5. **...

    fastdfs-client-java-1.29-SNAPSHOT.jar

    在Java环境中,`fastdfs-client-java`是用于连接FastDFS服务器的客户端库,使得Java应用能够方便地进行文件上传、下载等操作。本文将详细探讨`fastdfs-client-java-1.29-SNAPSHOT.jar`这一核心组件,以及与其相关的`...

    java-ipfs-http-client-master_ipfs_java-ipfs_java_

    在`java-ipfs-http-client-master`压缩包中,包含了这个库的源代码,你可以深入了解其实现细节,包括如何处理HTTP请求、解析响应以及如何封装IPFS的API调用。通过阅读源码,开发者可以学习如何构建与IPFS网络的交互...

    google-http-java-client-1.13.1-beta.zip

    "google-http-java-client-1.13.1-beta.zip" 是一个包含Google HTTP Java客户端库的压缩包,这个库主要用于Java开发者与Google的HTTP API进行交互。它提供了简单且强大的方式来构建网络请求,处理响应,并集成到Java...

    async-http-client-2.0.13.zip

    在实际项目中,我们可以利用Async-HTTP-Client进行数据抓取、API调用、文件上传下载等多种操作,尤其是在移动应用和服务器端,它的异步特性能够显著提高用户体验。 总之,Async-HTTP-Client 2.0.13是Java开发者...

    ssh-tectia-client 6.3.2

    5. **文件传输**:内置SFTP(安全文件传输协议)功能,支持安全的文件和目录的上传、下载、复制、移动和删除操作,确保文件传输的安全性和可靠性。 6. **脚本支持**:对于自动化任务,SSH-Tectia Client支持通过...

    前端开源库-ssh2-sftp-client

    1. **Web应用中的文件上传和下载**:前端开发者可以利用此库在用户界面上实现文件的上传和下载功能,同时确保数据传输的安全。 2. **自动化部署**:在持续集成/持续部署(CI/CD)流程中,前端项目可以利用此库自动将...

    fastdfs-client-java-1.27

    FastDFS客户端Java库1.27版则是针对Java应用设计的接口,使得Java开发者能够方便地与FastDFS服务器进行交互,实现文件上传、下载、查询等操作。本文将深入探讨这个版本的特性、使用方法及其源码分析。 一、FastDFS...

    fastdfs-client-javajar1.29-SNAPSHOT.zip

    3. **文件上传**:通过Java API实现文件上传到FastDFS服务器,包括单文件上传和多文件上传。 4. **文件下载**:获取文件ID后,使用客户端库下载文件,可以指定下载的文件路径和重命名文件。 5. **文件操作**:支持...

    njit-client 1.3

    2. **上传与解压**:将压缩包通过SSH或LuCI界面上传到OpenWRT路由器的文件系统中,然后使用命令行工具如`tar`进行解压。 3. **编译与安装**:由于OpenWRT基于Linux,你需要使用OpenWRT的包管理工具如`opkg`或`make`...

    fastdfs-client-java-1.27.zip

    2. **负载均衡**:通过Tracker服务器对Storage服务器进行动态负载均衡,使得文件上传和下载的请求能够均匀分布到各个节点,减少单个服务器的压力。 3. **文件冗余备份**:支持文件的冗余备份,提供高可用性,保证...

    VMware-Horizon-Client

    5. **文件传输**:用户可以方便地在本地设备和虚拟桌面之间进行文件拷贝,增强了远程工作时的数据交互能力。 6. **性能优化**:Horizon Client采用了一系列技术,如PCoIP(Per-Client Over-IP)协议,以减少延迟,...

    fastdfs-client-java1.26

    1. 文件上传:FastDFS-client-java支持将本地文件上传至FastDFS服务器,支持单文件和批量文件上传,且在上传过程中支持断点续传,确保文件传输的完整性。 2. 文件下载:可以按照文件ID或路径下载服务器上的文件,...

    fastdfs-client-java-master.zip

    1. 文件上传:将本地文件上传到FastDFS服务器,返回文件ID。 2. 文件下载:根据文件ID从FastDFS服务器下载文件到本地。 3. 文件删除:根据文件ID删除存储在FastDFS中的文件。 4. 元数据操作:添加、更新或删除文件的...

    fastdfs-client-java-master

    在Java开发环境中,FastDFS-Client-Java-Master提供了完整的API接口,使得Java应用可以方便地进行文件上传、下载、删除等操作。这个库通常与Maven构建工具配合使用,通过在项目中引入依赖,即可轻松集成到Java项目中...

Global site tag (gtag.js) - Google Analytics