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,通过`ipfs-http-client`将CID链接存储在区块链上,这样即使原始服务器下线,用户依然可以访问到他们的数据。 在使用`ipfs-http-client`时,开发者需要...
在实现跨服务器文件上传时,首先需要配置jersey-client,设置目标服务器的URL、HTTP方法(通常是POST)以及文件的MIME类型。然后,使用jersey-client的API创建一个请求实体,将文件内容附加到请求中。此外,可能还...
总之,通过结合Spring MVC的文件上传能力和Jersey Client的HTTP请求功能,我们可以实现远程文件上传,这对于分布式系统或者需要跨服务器协作的场景非常有用。同时,理解并熟练掌握这两个工具对于提升Java Web开发...
3. 使用API:FastDFS提供了一系列的Java API,用于文件的上传、下载、删除等操作。 总的来说,FastDFS客户端Java版是Java开发者与FastDFS服务交互的重要工具,它的使用涉及到项目构建配置、网络通信以及文件操作等...
3. **文件上传**:通过客户端API将本地文件上传至FastDFS系统,上传过程中,FastDFS会自动进行负载均衡和文件复制,确保高可用性。 4. **文件下载**:根据文件的存储路径,从FastDFS系统中下载文件到本地。 5. **...
在Java环境中,`fastdfs-client-java`是用于连接FastDFS服务器的客户端库,使得Java应用能够方便地进行文件上传、下载等操作。本文将详细探讨`fastdfs-client-java-1.29-SNAPSHOT.jar`这一核心组件,以及与其相关的`...
在`java-ipfs-http-client-master`压缩包中,包含了这个库的源代码,你可以深入了解其实现细节,包括如何处理HTTP请求、解析响应以及如何封装IPFS的API调用。通过阅读源码,开发者可以学习如何构建与IPFS网络的交互...
"google-http-java-client-1.13.1-beta.zip" 是一个包含Google HTTP Java客户端库的压缩包,这个库主要用于Java开发者与Google的HTTP API进行交互。它提供了简单且强大的方式来构建网络请求,处理响应,并集成到Java...
在实际项目中,我们可以利用Async-HTTP-Client进行数据抓取、API调用、文件上传下载等多种操作,尤其是在移动应用和服务器端,它的异步特性能够显著提高用户体验。 总之,Async-HTTP-Client 2.0.13是Java开发者...
5. **文件传输**:内置SFTP(安全文件传输协议)功能,支持安全的文件和目录的上传、下载、复制、移动和删除操作,确保文件传输的安全性和可靠性。 6. **脚本支持**:对于自动化任务,SSH-Tectia Client支持通过...
1. **Web应用中的文件上传和下载**:前端开发者可以利用此库在用户界面上实现文件的上传和下载功能,同时确保数据传输的安全。 2. **自动化部署**:在持续集成/持续部署(CI/CD)流程中,前端项目可以利用此库自动将...
FastDFS客户端Java库1.27版则是针对Java应用设计的接口,使得Java开发者能够方便地与FastDFS服务器进行交互,实现文件上传、下载、查询等操作。本文将深入探讨这个版本的特性、使用方法及其源码分析。 一、FastDFS...
3. **文件上传**:通过Java API实现文件上传到FastDFS服务器,包括单文件上传和多文件上传。 4. **文件下载**:获取文件ID后,使用客户端库下载文件,可以指定下载的文件路径和重命名文件。 5. **文件操作**:支持...
2. **上传与解压**:将压缩包通过SSH或LuCI界面上传到OpenWRT路由器的文件系统中,然后使用命令行工具如`tar`进行解压。 3. **编译与安装**:由于OpenWRT基于Linux,你需要使用OpenWRT的包管理工具如`opkg`或`make`...
2. **负载均衡**:通过Tracker服务器对Storage服务器进行动态负载均衡,使得文件上传和下载的请求能够均匀分布到各个节点,减少单个服务器的压力。 3. **文件冗余备份**:支持文件的冗余备份,提供高可用性,保证...
5. **文件传输**:用户可以方便地在本地设备和虚拟桌面之间进行文件拷贝,增强了远程工作时的数据交互能力。 6. **性能优化**:Horizon Client采用了一系列技术,如PCoIP(Per-Client Over-IP)协议,以减少延迟,...
1. 文件上传:FastDFS-client-java支持将本地文件上传至FastDFS服务器,支持单文件和批量文件上传,且在上传过程中支持断点续传,确保文件传输的完整性。 2. 文件下载:可以按照文件ID或路径下载服务器上的文件,...
1. 文件上传:将本地文件上传到FastDFS服务器,返回文件ID。 2. 文件下载:根据文件ID从FastDFS服务器下载文件到本地。 3. 文件删除:根据文件ID删除存储在FastDFS中的文件。 4. 元数据操作:添加、更新或删除文件的...
在Java开发环境中,FastDFS-Client-Java-Master提供了完整的API接口,使得Java应用可以方便地进行文件上传、下载、删除等操作。这个库通常与Maven构建工具配合使用,通过在项目中引入依赖,即可轻松集成到Java项目中...