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>
如果上传文件,我们必须将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 }
通过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 }
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 }
到这里位置,java中上传文件以及向第三方传输文件都实现啦。