HttpClient构造文件上传

在项目中我们有时候需要使用到其他第三方的api,而有些api要求我们上传文件,search一下,下面将结果记录一下喽!

含义 ENCTYPE="multipart/form-data" 说明: 
通过 http 协议上传文件 rfc1867协议概述,jsp 应用举例,客户端发送内容构造 

1、概述在最初的 http 协议中,没有上传文件方面的功能。 rfc1867 (http://www.ietf.org/rfc/rfc1867.txt) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。

2、上传文件实例,jsp例子:

1 <form action="gerry/publish/file" enctype="multipart/form-data" method="post">
2 file:<input type="file" name="file"/><br/>
3 <input type="submit" value="submit"/>
4 </form>
View Code

如果上传文件,我们必须将enctype设置成"multipart/form-data",表示我们上传的是一个二进制数据流。

3、Servlet中解析这个请求

 1         boolean isMultipart = ServletFileUpload.isMultipartContent(req);
 2         if (isMultipart) {
 3             // 构造一个文件上传处理对象
 4             FileItemFactory factory = new DiskFileItemFactory();
 5             ServletFileUpload upload = new ServletFileUpload(factory);
 6 
 7             Iterator items;
 8             try {
 9                 // 解析表单中提交的所有文件内容
10                 items = upload.parseRequest(req).iterator();
11                 while (items.hasNext()) {
12                     FileItem item = (FileItem) items.next();
13                     System.out.println(item.getFieldName());
14                     System.out.println(item.isFormField());
15                     System.out.println(item.getString());
16 
17                     if (!item.isFormField()) {
18                         // 取出上传文件的文件名称
19                         String name = item.getName();
20                         // 取得上传文件以后的存储路径
21                         String fileName = name.substring(name.lastIndexOf('\') + 1, name.length());
22                         // 上传文件以后的存储路径
23                         String path = req.getRealPath("file") + File.separatorChar + fileName;
24 
25                         // 上传文件
26                         File uploaderFile = new File(path);
27                         item.write(uploaderFile);
28                     }
29                 }
30             } catch (Exception e) {
31                 resp.getOutputStream().write(("throw exception " + e.getMessage()).getBytes());
32             }
33         } else {
34             resp.getOutputStream().write("is not this file upload".getBytes());
35         }
View Code

通过ServletFileUpload的parseRequest方法可以将文件流和非文件流全部解析出来。不用考虑HttpServletRequest中的数据流格式。

4、Spring中解析这个请求

在Spring中我们可以直接通过MultipartFile来获取请求中的文件流信息。

 1 @RequestMapping(value = "/gerry/publish/file")
 2     @ResponseBody
 3     public String upload1(MultipartFile file) {
 4         String originalFileName = file.getOriginalFilename();
 5         String fileName = file.getName();
 6         System.out.println(originalFileName);
 7         System.out.println(fileName);
 8         System.out.println(file.getContentType());
 9         try {
10             MyHttpClient.addPic(file.getBytes());
11         } catch (Exception e) {
12             return "failure, the exception msg is: " + e.getMessage();
13         }
14         return "success";
15     }
View Code

5、代码中构造HttpClient请求,传输文件

 1 /**
 2      * 传输文件流bs
 3      * 
 4      * @param bs
 5      *            要传输的文件流
 6      */
 7     public static void addPic(byte[] bs) {
 8         HttpClient httpClient = new DefaultHttpClient();
 9         HttpPost httpPost = new HttpPost(url);
10         MultipartEntity entity = new MultipartEntity();
11         entity.addPart("pic", new ByteArrayBody(bs, "pic"));
12         try {
13             // 添加其他的参数,可以是多个/零个
14             entity.addPart("name", new StringBody("liuming92")); 
15         } catch (UnsupportedEncodingException e1) {
16             throw new RuntimeException(e1);
17         }
18         httpPost.setEntity(entity);
19         try {
20             HttpResponse httpResponse = httpClient.execute(httpPost);
21             if (httpResponse != null) {
22                 String result = EntityUtils.toString(httpResponse.getEntity());
23                 System.out.println(result);
24             }
25         } catch (IOException e) {
26             throw new RuntimeException(e);
27         }
28     }
View Code

到这里位置,java中上传文件以及向第三方传输文件都实现啦。

原文地址:https://www.cnblogs.com/liuming1992/p/4204188.html