HttpClient上传文件的方式MultipartRequestEntity

HttpClient访问第三方项目接口上传文件的实现方案,并解决中文乱码问题,并且在上传文件的时候传输多个其他参数;

第一种方案,中文参数在url内部,使用URLEncoder类对中文进行encode:


  1. public static void postTwo() throws Exception{  
  2.         HttpClient client = new HttpClient();  
  3.         //登录  
  4.         PostMethod post = new PostMethod("http://127.0.0.1:8080/HelloWorld/post?host=172.16.2.183&port=10086&name=test&pw=test" + URLEncoder.encode("北京""utf-8"));  
  5.         FilePart fp = new FilePart("formFile"new File("D://PTOC_SCENIC_DAY_2015043015.txt"));  
  6.         Part[] parts = {fp};  
  7.           
  8.         MultipartRequestEntity entity = new MultipartRequestEntity(parts, new HttpMethodParams());  
  9.         post.setRequestEntity(entity);  
  10.           
  11.         client.executeMethod(post);  
  12.         //释放连接,以免超过服务器负荷  
  13.         System.out.println("============================");  
  14.         System.out.println(post.getResponseBodyAsString());  
  15.         System.out.println("============================");  
  16.         //释放连接,以免超过服务器负荷  
  17.         post.releaseConnection();  
  18.     }  
第二种方案,使用Part类,该类有两个子类,一个StringPart,一个FilePart,StringPart用于传输普通字符串参数,FilePart用于上传文件:

  1. public static void postThree() throws Exception{  
  2.         HttpClient client = new HttpClient();  
  3.         //登录  
  4.         PostMethod post = new PostMethod("http://127.0.0.1:8080/HelloWorld/post");  
  5.         FilePart fp = new FilePart("formFile""JNDI.txt"new File("D://JNDI配置数据库连接池_获取数据库连接.txt"));  
  6.         fp.setCharSet("utf-8");  
  7.         System.out.println(fp.getCharSet());  
  8.         Part[] parts = { fp, new StringPart("host""172.16.2.183""UTF-8"),  
  9.                 new StringPart("port""10086""UTF-8"),  
  10.                 new StringPart("name""test色鬼""UTF-8"),  
  11.                 new StringPart("pw""test特殊""UTF-8") };  
  12.           
  13.         MultipartRequestEntity entity = new MultipartRequestEntity(parts, new HttpMethodParams());  
  14.         post.setRequestEntity(entity);  
  15.         System.out.println(entity.getContentType());  
  16.           
  17.         client.executeMethod(post);  
  18.         //释放连接,以免超过服务器负荷  
  19.         System.out.println("============================");  
  20.         System.out.println(post.getResponseBodyAsString());  
  21.         System.out.println("============================");  
  22.         //释放连接,以免超过服务器负荷  
  23.         post.releaseConnection();  
  24.     }  

 以上两种方案对应的第三方项目的接口代码如下:


  1. @RequestMapping(value = "/post", method = { RequestMethod.POST })  
  2.     public @ResponseBody Map<String, Object> post(@RequestParam(value = "host") String host,  
  3.             @RequestParam("port") String port,  
  4.             @RequestParam("name") String name,  
  5.             @RequestParam("pw") String pw,  
  6.             @RequestParam("formFile") MultipartFile formFile) {  
  7.         Map<String, Object> map = new HashMap<String, Object>();  
  8.         try{  
  9.             map.put("tag""1");  
  10.             map.put("msg""上传成功!");  
  11.             System.out.println(host + ":" + port + " " + name + " " + pw);  
  12.             String fileName = formFile.getOriginalFilename();  
  13.             FileOutputStream write = new FileOutputStream("D://ww" + fileName);  
  14.             InputStream read = formFile.getInputStream();  
  15.             byte data[] = new byte[1024];  
  16.             int count;  
  17.             while ((count = read.read(data, 01024)) != -1) {  
  18.                 write.write(data, 0, count);  
  19.             }  
  20.             read.close();  
  21.             write.close();  
  22.         }catch (Exception e) {  
  23.             e.printStackTrace();  
  24.             map.put("tag""0");  
  25.             map.put("msg""上传失败:" + e.getMessage());  
  26.         }  
  27.         return map;  
  28.     }  


这两只方案都只能解决普通字符串参数的中文乱码问题,对于上传的文件其文件名中文乱码问题不能使用setCharSet方法设置编码方式解决,至于原因,查看源码就可以知道,StringPart和FilePart类中对中午的处理方式不一样,FilePart在转换文件名时,用的方法是EncodingUtil.getAsciiBytes(),查看这个方法源码为data.getBytes("US-ASCII"),因此中文文件名必定乱码,不管你是否调用了setCharSet("GBK")方法。 解决很简单:out.write(EncodingUtil.getBytes(filename, getCharSet()));想要解决附件文件名中文乱码只能靠修改源码了,FilePart中对中午乱码起至关重要的部分为:


  1. protected void sendDispositionHeader(OutputStream out) throws IOException {  
  2.         LOG.trace("enter sendDispositionHeader(OutputStream out)");  
  3.         super.sendDispositionHeader(out);  
  4.         String filename = this.source.getFileName();  
  5.         if (filename != null) {  
  6.             out.write(FILE_NAME_BYTES);  
  7.             out.write(QUOTE_BYTES);  
  8.             out.write(EncodingUtil.getAsciiBytes(filename));  
  9.             out.write(QUOTE_BYTES);  
  10.         }  
  11.     } 

猜你喜欢

转载自blog.csdn.net/zs520ct/article/details/80484735