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

觉得写得不错,转载过来分享一下。转载自:http://www.jb51.net/article/100386.htm

下面小编就为大家带来一篇使用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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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下的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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表单进行处理的。  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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下的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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 服务端处理

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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实现文件的上传下载方法全部内容了,希望大家多多支持脚本之家~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值