您好,欢迎来到九壹网。
搜索
您的当前位置:首页使用HttpClient实现文件的上传下载方法

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

来源:九壹网
使⽤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\ filePost.setParameter(\"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\ \"text/plain\

StringBody password = new StringBody(\"123456\ \"text/plain\

HttpEntity reqEntity = MultipartEntityBuilder.create() // 相当于 .addPart(\"file\

// 相当于 .addPart(\"userName\ .addPart(\"pass\ .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:\\\emp\"));

// 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 items = null; try {

// 解析request请求

items = upload.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); }

if(items!=null){ //解析表单项⽬

Iterator iter = items.iterator(); while (iter.hasNext()) {

FileItem item = iter.next();

//如果是普通表单属性 if (item.isFormField()) {

//相当于input的name属性 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\ }

服务端在处理之后,可以在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\ get.setRequestHeader(\"passwd\

get.setRequestHeader(\"fileName\ 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\ httpGet.addHeader(\"passwd\

httpGet.addHeader(\"fileName\

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\ // default is GET

httpURLConnection.setRequestMethod(\"POST\");

httpURLConnection.setRequestProperty(\"connection\ httpURLConnection.setRequestProperty(\"Charsert\ // 1 min

httpURLConnection.setConnectTimeout(60000); // 1 min

httpURLConnection.setReadTimeout(60000);

httpURLConnection.addRequestProperty(\"userName\

httpURLConnection.addRequestProperty(\"passwd\

httpURLConnection.addRequestProperty(\"fileName\ // 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\

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\

}catch(Exception e){ e.printStackTrace();

response.addHeader(\"token\ }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实现⽂件的上传下载⽅法全部内容了,希望⼤家多多⽀持~

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务