注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

_

_

 
 
 

日志

 
 

不借助第三方包写个java文件上传的工具类 (自己造轮子系列1)  

2011-08-16 22:40:26|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

作者
正文

  • ouyangfei0426
  • 等级: 初级会员
  • ouyangfei0426的博客
  • 性别: 不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活
  • 文章: 12
  • 积分: 40
  • 来自: 大连
  • 不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

   发表时间:2011-04-24  

< > 猎头职位: 上海: 上海:天会皓闻诚聘资深Java架构师

相关文章:


推荐群组: GT-Grid
更多相关推荐

最近闲来无事,突然对文件上传感兴趣起来,不由的想着自己不借助第三方包写个java文件上传的工具类,经过对http协议的一番研究,总算有点小成果。

      这是页面表单代码片段:

Html代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. <form action="gb/test.do" method="post" enctype="multipart/form-data">
  2. <h1>Hello World!</h1>
  3. &nbsp;&nbsp;name:<input type="text" name="name" value="" /><br>
  4. &nbsp;&nbsp;address:<input type="text" name="address" value="" /><br>
  5. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age:<input type="text" name="age" value="" /><br>
  6. photo1:<input type="file" name="f1"><br>
  7. photo2:<input type="file" name="f2"><br>
  8. 验证码:<input type="text" name="image"><img src="RandomImageServlet">
  9. <input type="submit">
  10. </form>
        <form action="gb/test.do" method="post" enctype="multipart/form-data">         <h1>Hello World!</h1>         &nbsp;&nbsp;name:<input type="text" name="name" value="" /><br>         &nbsp;&nbsp;address:<input type="text" name="address" value="" /><br>         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age:<input type="text" name="age" value="" /><br>         photo1:<input type="file" name="f1"><br>         photo2:<input type="file" name="f2"><br>         验证码:<input type="text" name="image"><img src="RandomImageServlet">         <input type="submit">         </form>

在页面填写完数据后,提交表单,通过httpwatch我们可以看到如下数据:

Txt代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. POST /testWeb/gb/test.do HTTP/1.1
  2. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*  
  3. Referer: http://localhost:8084/testWeb/  
  4. Accept-Language: zh-cn  
  5. Content-Type: multipart/form-data; boundary=---------------------------7db1e4183026c  
  6. Accept-Encoding: gzip, deflate  
  7. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.3; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)  
  8. Host: localhost:8084
  9. Content-Length: 7647320
  10. Connection: Keep-Alive  
  11. Cache-Control: no-cache  
  12. Cookie: JSESSIONID=FEF31749D9D8CBE22C2A49C7A6799A15  
  13. -----------------------------7db1e4183026c  
  14. Content-Disposition: form-data; name="name"
  15. 灏忓己  
  16. -----------------------------7db1e4183026c  
  17. Content-Disposition: form-data; name="address"
  18. 杈藉畞澶ц繛  
  19. -----------------------------7db1e4183026c  
  20. Content-Disposition: form-data; name="age"
  21. 23
  22. -----------------------------7db1e4183026c  
  23. Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\mark\妗岄潰\JavaEE_CN.chm"
  24. Content-Type: application/octet-stream  
  25. ITSF   `      鳋  
  26. 3  ?|獅?? 犐"骒?|獅?? 犐"骒`              x       T?     汤     ?      籵             ITSP   T     
  27.             ;       :   ????<      j?].!?濝 犐"骒T   ????????????PMGL>       ????   /   /#IDXHDR樳? /#ITBITS      /#STRINGS橍臥嚽/#SYSTEM ??/#TOPICS樳?冔/#URLSTR樻猶帤_/#URLTBL樸?備X  /#WINDOWS栰?丩/$FIftiMain桏?佽孶 /$OBJINST桏??/$WWAssociativeLinks/   /$WWAssociativeLinks/Property桏?/$WWKeywordLinks/   /$WWKeywordLinks/BTree栰?壚L/$WWKeywordLinks/Data桍扥亼l/$WWKeywordL掜o 簔螓6礩?晢彌?瘓戠7?@T怶御<删2w搋?50*xN樾sa捏?洙{)藽缃镎菻Z粺拺??I荷o柦雛?檀}mxJ暾???瑩巧坮汎煘    絴?                            `...  
  28. -----------------------------7db1e4183026c  
  29. Content-Disposition: form-data; name="f2"; filename="C:\Documents and Settings\mark\妗岄潰\pietty0327.exe"
  30. Content-Type: application/octet-stream  
  31. MZ       ??         @                                     ? ???L?This program cannot be run in DOS mode.  
  32. $       ?垵頽嫖頽嫖頽嫖齠徫靚嫖隻單靚嫖隻槲鬾嫖隻刮nn嫖mf刮飊嫖齠晃靚嫖mf晃黱嫖M?坞n嫖頽缥猳嫖隻呂猲嫖e肝飊嫖頽嫖靚嫖隻嘉飊嫖Rich頽嫖                PE  L S醐B           
  33. ?      ? P?  ?  ?   @                      ?    I/                               芎  
  34. ?   ? ?                                                     ?庿xn?{+0c7$(~m兩姅躆?鵈Tn琏籡E (e...  
  35. -----------------------------7db1e4183026c  
  36. Content-Disposition: form-data; name="image"
  37. 7hti  
  38. -----------------------------7db1e4183026c-- 
POST /testWeb/gb/test.do HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */* Referer: http://localhost:8084/testWeb/ Accept-Language: zh-cn Content-Type: multipart/form-data; boundary=---------------------------7db1e4183026c Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.3; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) Host: localhost:8084 Content-Length: 7647320 Connection: Keep-Alive Cache-Control: no-cache Cookie: JSESSIONID=FEF31749D9D8CBE22C2A49C7A6799A15  -----------------------------7db1e4183026c Content-Disposition: form-data; name="name"  灏忓己 -----------------------------7db1e4183026c Content-Disposition: form-data; name="address"  杈藉畞澶ц繛 -----------------------------7db1e4183026c Content-Disposition: form-data; name="age"  23 -----------------------------7db1e4183026c Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\mark\妗岄潰\JavaEE_CN.chm" Content-Type: application/octet-stream  ITSF   `      鳋 3  ?|獅?? 犐"骒?|獅?? 犐"骒`              x       T?     汤     ?      籵             ITSP   T                ;       :   ????<      j?].!?濝 犐"骒T   ????????????PMGL>       ????   /   /#IDXHDR樳? /#ITBITS    /#STRINGS橍臥嚽/#SYSTEM ??/#TOPICS樳?冔/#URLSTR樻猶帤_/#URLTBL樸?備X /#WINDOWS栰?丩/$FIftiMain桏?佽孶 /$OBJINST桏??/$WWAssociativeLinks/   /$WWAssociativeLinks/Property桏?/$WWKeywordLinks/   /$WWKeywordLinks/BTree栰?壚L/$WWKeywordLinks/Data桍扥亼l/$WWKeywordL掜o 簔螓6礩?晢彌?瘓戠7?@T怶御<删2w搋?50*xN樾sa捏?洙{)藽缃镎菻Z粺拺??I荷o柦雛?檀}mxJ暾???瑩巧坮汎煘 絴?                            `... -----------------------------7db1e4183026c Content-Disposition: form-data; name="f2"; filename="C:\Documents and Settings\mark\妗岄潰\pietty0327.exe" Content-Type: application/octet-stream  MZ       ??         @                                     ? ???L?This program cannot be run in DOS mode.  $       ?垵頽嫖頽嫖頽嫖齠徫靚嫖隻單靚嫖隻槲鬾嫖隻刮nn嫖mf刮飊嫖齠晃靚嫖mf晃黱嫖M?坞n嫖頽缥猳嫖隻呂猲嫖e肝飊嫖頽嫖靚嫖隻嘉飊嫖Rich頽嫖                PE  L S醐B           ?      ? P?  ?  ?   @                      ?    I/                               芎  ?   ? ?                                                     ?庿xn?{+0c7$(~m兩姅躆?鵈Tn琏籡E (e... -----------------------------7db1e4183026c Content-Disposition: form-data; name="image"  7hti -----------------------------7db1e4183026c--

其中我们仔细观看上面的数据

Txt代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. Content-Type: multipart/form-data; boundary=---------------------------7db1e4183026c 
Content-Type: multipart/form-data; boundary=---------------------------7db1e4183026c

这里有个值boundary,这个单词意为分界之意,不难理解,它的值“

Txt代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. ---------------------------7db1e4183026c 
---------------------------7db1e4183026c

”是个分界符,用于把表单数据分为不同的段,但是如果仔细观察,你会发现正文里的分界符的长度比这个值多了2个字节长度,也就是多 了两个“-”,而且正文中的分界符每个分界符结尾都有一个回车换行符,占两个字节,这里还要注意的是最后一个边界符——终结符,比前面的边界符多了两个 “-”,但是,这里要注意的是

       终结符!=边界符+“--”;

      而是

      终结符=边界符-回车换行符+“--”+回车换行符!

这里估计很多人刚开始都是会处理错误的。

      此外我们还发现上传文件的数据段是这样的:

Txt代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\mark\妗岄潰\JavaEE_CN.chm"
  2. Content-Type: application/octet-stream 
Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\mark\妗岄潰\JavaEE_CN.chm" Content-Type: application/octet-stream

    而只是普通的文本框输入的数据的话,它并没有filename=“...”,而且也没有下面的Content-Type这行数据:

Txt代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. Content-Disposition: form-data; name="address"
Content-Disposition: form-data; name="address"

    而我们的任务就是要处理这个数据流,把参数名,跟参数值从数据流里提取出来,下面是处理数据流的java代码:

Java代码 复制代码 收藏代码不借助第三方包写个java文件上传的工具类 (自己造轮子系列1) - redtea - 熠彩网络,熠彩生活

  1. import java.io.FileNotFoundException;  
  2. import java.io.FileOutputStream;  
  3. import java.io.IOException;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.util.HashMap;  
  6. import javax.servlet.ServletInputStream;  
  7. import org.apache.commons.logging.Log;  
  8. import org.apache.commons.logging.LogFactory;  
  9. /**
  10. *
  11. * @author mark
  12. */
  13. public class UploadFile {  
  14. private static Log log = LogFactory.getLog(UploadFile.class);  
  15. /**
  16.      * 上传文件组件,调用该方法的servlet在使用该方法前必须先调用request.setCharacterEncoding()方法,设置编码格式。该编码格式须与页面编码格式一致。
  17.      * @param sis 数据流
  18.      * @param encoding 编码方式。必须与jsp页面编码方式一样,否则会有乱码。
  19.      * @param length 数据流长度
  20.      * @param upLoadPath 文件保存路径
  21.      * @throws FileNotFoundException
  22.      * @throws IOException
  23.      */
  24. public static HashMap uploadFile(ServletInputStream sis, String encoding, int length, String upLoadPath) throws IOException {  
  25.         HashMap paramMap = new HashMap();  
  26. boolean isFirst = true;  
  27.         String boundary = null;//分界符
  28. byte[] tmpBytes = new byte[4096];//tmpBytes用于存储每行读取到的字节。
  29. int[] readBytesLength = new int[1];//数组readBytesLength中的元素i[0],用于保存readLine()方法中读取的实际字节数。
  30. int readStreamlength = 0;//readStreamlength用于记录已经读取的流的长度。
  31.         String tmpString = null;  
  32.         tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);  
  33.         readStreamlength = readStreamlength + readBytesLength[0];  
  34. while (readStreamlength < length) {  
  35. if (isFirst) {  
  36.                 boundary = tmpString;  
  37.                 isFirst = false;  
  38.             }  
  39. if (tmpString.equals(boundary)) {  
  40.                 String contentDisposition = readLine(tmpBytes, readBytesLength, sis, encoding);  
  41.                 readStreamlength = readStreamlength + readBytesLength[0];  
  42.                 String contentType = readLine(tmpBytes, readBytesLength, sis, encoding);  
  43.                 readStreamlength = readStreamlength + readBytesLength[0];  
  44. //当时上传文件时content-Type不会是null
  45. if (contentType != null && contentType.trim().length() != 0) {  
  46.                     String paramName = getPramName(contentDisposition);  
  47.                     String fileName = getFileName(getFilePath(contentDisposition));  
  48.                     paramMap.put(paramName, fileName);  
  49. //跳过空格行
  50.                     readLine(tmpBytes, readBytesLength, sis, encoding);  
  51.                     readStreamlength = readStreamlength + readBytesLength[0];  
  52. /*
  53.                      * 文件名不为空,则上传了文件。
  54.                      */
  55. if (fileName != null && fileName.trim().length() != 0) {  
  56.                         fileName = upLoadPath + fileName;  
  57. //开始读取数据
  58. byte[] cash = new byte[4096];  
  59. int flag = 0;  
  60.                         FileOutputStream fos = new FileOutputStream(fileName);  
  61.                         tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);  
  62.                         readStreamlength = readStreamlength + readBytesLength[0];  
  63. /*
  64.                          *分界符跟结束符虽然看上去只是结束符比分界符多了“--”,其实不是,
  65.                          *分界符是“-----------------------------45931489520280”后面有2个看不见的回车换行符,即0D 0A
  66.                          *而结束符是“-----------------------------45931489520280--”后面再跟2个看不见的回车换行符,即0D 0A
  67.                          *
  68.                          */
  69. while (tmpString.indexOf(boundary.substring(0, boundary.length() - 2)) == -1) {  
  70. for (int j = 0; j < readBytesLength[0]; j++) {  
  71.                                 cash[j] = tmpBytes[j];  
  72.                             }  
  73.                             flag = readBytesLength[0];  
  74.                             tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);  
  75.                             readStreamlength = readStreamlength + readBytesLength[0];  
  76. if (tmpString.indexOf(boundary.substring(0, boundary.length() - 2)) == -1) {  
  77.                                 fos.write(cash, 0, flag);  
  78.                                 fos.flush();  
  79.                             } else {  
  80.                                 fos.write(cash, 0, flag - 2);  
  81.                                 fos.flush();  
  82.                             }  
  83.                         }  
  84.                         fos.close();  
  85.                     } else {  
  86. //跳过空格行
  87.                         readLine(tmpBytes, readBytesLength, sis, encoding);  
  88.                         readStreamlength = readStreamlength + readBytesLength[0];  
  89. //读取分界符或者结束符
  90.                         tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);  
  91.                         readStreamlength = readStreamlength + readBytesLength[0];  
  92.                     }  
  93.                 } //当不是长传文件时
  94. else {  
  95.                     String paramName = getPramName(contentDisposition);  
  96.                     String value = readLine(tmpBytes, readBytesLength, sis, encoding);  
  97. //去掉回车换行符(最后两个字节)
  98. byte[] valueByte=value.getBytes(encoding);  
  99.                     value =new String(valueByte, 0, valueByte.length-2, encoding);  
  100.                     readStreamlength = readStreamlength + readBytesLength[0];  
  101.                     paramMap.put(paramName, value);  
  102.                     tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);  
  103.                     readStreamlength = readStreamlength + readBytesLength[0];  
  104.                 }  
  105.             }  
  106.         }  
  107.         sis.close();  
  108. return paramMap;  
  109.     }  
  110. /**
  111.      * 从流中读取一行数据。
  112.      * @param bytes 字节数组,用于保存从流中读取到的字节。
  113.      * @param index 一个整型数组,只有一个元素,即index[0],用于保存从流中实际读取的字节数。
  114.      * @param sis 数据流
  115.      * @param encoding 组建字符串时所用的编码
  116.      * @return 将读取到的字节经特定编码方式组成的字符串。
  117.      */
  118. private static String readLine(byte[] bytes, int[] index, ServletInputStream sis, String encoding) {  
  119. try {  
  120.             index[0] = sis.readLine(bytes, 0, bytes.length);//readLine()方法把读取的内容保存到bytes数组的第0到第bytes.length处,返回值是实际读取的 字节数。
  121. if (index[0] < 0) {  
  122. return null;  
  123.             }  
  124.         } catch (IOException e) {  
  125.             log.error("read line ioexception");  
  126. return null;  
  127.         }  
  128. if (encoding == null) {  
  129. return new String(bytes, 0, index[0]);  
  130.         } else {  
  131. try {  
  132. return new String(bytes, 0, index[0], encoding);  
  133.             } catch (UnsupportedEncodingException ex) {  
  134.                 log.error("Unsupported Encoding");  
  135. return null;  
  136.             }  
  137.         }  
  138.     }  
  139. private static String getPramName(String contentDisposition) {  
  140.         String s = contentDisposition.substring(contentDisposition.indexOf("name=\"") + 6);  
  141.         s = s.substring(0, s.indexOf('\"'));  
  142. return s;  
  143.     }  
  144. private static String getFilePath(String contentDisposition) {  
  145.         String s = contentDisposition.substring(contentDisposition.indexOf("filename=\"") + 10);  
  146.         s = s.substring(0, s.indexOf('\"'));  
  147. return s;  
  148.     }  
  149. private static String getFileName(String filePath) {  
  150.         String rtn = null;  
  151. if (filePath != null) {  
  152. int index = filePath.lastIndexOf("/");//根据name中包不包含/来判断浏览器的类型。
  153. if (index != -1)//包含/,则此时可以判断文件由火狐浏览器上传
  154.             {  
  155.                 rtn = filePath.substring(index + 1);//获得文件名
  156.             } else//不包含/,可以判断文件由ie浏览器上传。
  157.             {  
  158.                 index = filePath.lastIndexOf("\\");  
  159. if (index != -1) {  
  160.                     rtn = filePath.substring(index + 1);//获得文件名
  161.                 } else {  
  162.                     rtn = filePath;  
  163.                 }  
  164.             }  
  165.         }  
  166. return rtn;  
  167.     }  
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import javax.servlet.ServletInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;  /**  *  * @author mark  */ public class UploadFile {      private static Log log = LogFactory.getLog(UploadFile.class);      /**      * 上传文件组件,调用该方法的servlet在使用该方法前必须先调用request.setCharacterEncoding()方法,设置编码格式。该编码格式须与页面编码格式一致。      * @param sis 数据流      * @param encoding 编码方式。必须与jsp页面编码方式一样,否则会有乱码。      * @param length 数据流长度      * @param upLoadPath 文件保存路径      * @throws FileNotFoundException      * @throws IOException      */     public static HashMap uploadFile(ServletInputStream sis, String encoding, int length, String upLoadPath) throws IOException {         HashMap paramMap = new HashMap();          boolean isFirst = true;         String boundary = null;//分界符         byte[] tmpBytes = new byte[4096];//tmpBytes用于存储每行读取到的字节。         int[] readBytesLength = new int[1];//数组readBytesLength中的元素i[0],用于保存readLine()方法中读取的实际字节数。         int readStreamlength = 0;//readStreamlength用于记录已经读取的流的长度。         String tmpString = null;          tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);         readStreamlength = readStreamlength + readBytesLength[0];         while (readStreamlength < length) {             if (isFirst) {                 boundary = tmpString;                 isFirst = false;             }             if (tmpString.equals(boundary)) {                 String contentDisposition = readLine(tmpBytes, readBytesLength, sis, encoding);                 readStreamlength = readStreamlength + readBytesLength[0];                 String contentType = readLine(tmpBytes, readBytesLength, sis, encoding);                 readStreamlength = readStreamlength + readBytesLength[0];                 //当时上传文件时content-Type不会是null                 if (contentType != null && contentType.trim().length() != 0) {                     String paramName = getPramName(contentDisposition);                     String fileName = getFileName(getFilePath(contentDisposition));                      paramMap.put(paramName, fileName);                      //跳过空格行                     readLine(tmpBytes, readBytesLength, sis, encoding);                     readStreamlength = readStreamlength + readBytesLength[0];                      /*                      * 文件名不为空,则上传了文件。                      */                     if (fileName != null && fileName.trim().length() != 0) {                         fileName = upLoadPath + fileName;                          //开始读取数据                         byte[] cash = new byte[4096];                         int flag = 0;                         FileOutputStream fos = new FileOutputStream(fileName);                         tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);                         readStreamlength = readStreamlength + readBytesLength[0];                         /*                          *分界符跟结束符虽然看上去只是结束符比分界符多了“--”,其实不是,                          *分界符是“-----------------------------45931489520280”后面有2个看不见的回车换行符,即0D 0A                          *而结束符是“-----------------------------45931489520280--”后面再跟2个看不见的回车换行符,即0D 0A                          *                          */                         while (tmpString.indexOf(boundary.substring(0, boundary.length() - 2)) == -1) {                             for (int j = 0; j < readBytesLength[0]; j++) {                                 cash[j] = tmpBytes[j];                             }                             flag = readBytesLength[0];                             tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);                             readStreamlength = readStreamlength + readBytesLength[0];                             if (tmpString.indexOf(boundary.substring(0, boundary.length() - 2)) == -1) {                                 fos.write(cash, 0, flag);                                 fos.flush();                             } else {                                 fos.write(cash, 0, flag - 2);                                 fos.flush();                             }                         }                         fos.close();                     } else {                         //跳过空格行                         readLine(tmpBytes, readBytesLength, sis, encoding);                         readStreamlength = readStreamlength + readBytesLength[0];                          //读取分界符或者结束符                         tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);                         readStreamlength = readStreamlength + readBytesLength[0];                     }                 } //当不是长传文件时                 else {                     String paramName = getPramName(contentDisposition);                     String value = readLine(tmpBytes, readBytesLength, sis, encoding);                     //去掉回车换行符(最后两个字节)                     byte[] valueByte=value.getBytes(encoding);                     value =new String(valueByte, 0, valueByte.length-2, encoding);                                          readStreamlength = readStreamlength + readBytesLength[0];                     paramMap.put(paramName, value);                     tmpString = readLine(tmpBytes, readBytesLength, sis, encoding);                     readStreamlength = readStreamlength + readBytesLength[0];                 }             }          }         sis.close();         return paramMap;     }      /**      * 从流中读取一行数据。      * @param bytes 字节数组,用于保存从流中读取到的字节。      * @param index 一个整型数组,只有一个元素,即index[0],用于保存从流中实际读取的字节数。      * @param sis 数据流      * @param encoding 组建字符串时所用的编码      * @return 将读取到的字节经特定编码方式组成的字符串。      */     private static String readLine(byte[] bytes, int[] index, ServletInputStream sis, String encoding) {         try {             index[0] = sis.readLine(bytes, 0, bytes.length);//readLine()方法把读取的内容保存到bytes数组的第0到第bytes.length处,返回值是实际读取的 字节数。             if (index[0] < 0) {                 return null;             }         } catch (IOException e) {             log.error("read line ioexception");             return null;         }         if (encoding == null) {             return new String(bytes, 0, index[0]);         } else {             try {                 return new String(bytes, 0, index[0], encoding);             } catch (UnsupportedEncodingException ex) {                 log.error("Unsupported Encoding");                 return null;             }         }      }      private static String getPramName(String contentDisposition) {         String s = contentDisposition.substring(contentDisposition.indexOf("name=\"") + 6);         s = s.substring(0, s.indexOf('\"'));         return s;     }      private static String getFilePath(String contentDisposition) {         String s = contentDisposition.substring(contentDisposition.indexOf("filename=\"") + 10);         s = s.substring(0, s.indexOf('\"'));         return s;     }      private static String getFileName(String filePath) {         String rtn = null;         if (filePath != null) {             int index = filePath.lastIndexOf("/");//根据name中包不包含/来判断浏览器的类型。             if (index != -1)//包含/,则此时可以判断文件由火狐浏览器上传             {                 rtn = filePath.substring(index + 1);//获得文件名             } else//不包含/,可以判断文件由ie浏览器上传。             {                 index = filePath.lastIndexOf("\\");                 if (index != -1) {                     rtn = filePath.substring(index + 1);//获得文件名                 } else {                     rtn = filePath;                 }             }         }         return rtn;     } }

声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。

  评论这张
 
阅读(1001)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017