Java web中上传文件

来源:互联网 发布:ise软件和vivado软件 编辑:程序博客网 时间:2024/05/18 03:32

Java web中上传文件

  1. 先来看一下上传对form表单有什么要求?
    1. 必须是form表单提交。
    2. 表单中的method必须是post,不能是get
    3. 表单中的enctype的属性值必须是:multipart/form-data。当不是multipart的时候,就算<input type="file">提交的效果也和普通的text类型一样。
    4. 表单中项使用file类型
  2. 文件上传对servlet的要求?
    1. 因为表单中上传的不再是字符内容,而是字节内容。就算是上传文本文件也是一样的。所以不能使用request.getParameter(String fieldName)方法。
    2. 那使用什么呢。这个时候可以使用request.getInputStream();方法获取ServletInputStream对象,它是InputStream类的子类,这个对象对应表单的正文部分,关于正文部分下面会介绍。
  3. 关于正文部分介绍。
    1. 这个是有可以使用HTTP抓包工具,我使用的是Firebug。在Firefox进行抓包的。如下图所示:

    2. ServletInput中就包含第二张图片的内容。可以通过以下方法得到
[java] view plain copy
  1.   
[java] view plain copy
  1.   
[java] view plain copy
  1. public void doPost(HttpServletRequest request,HttpServletResponse response)throw IOException,ServletException{  
  2.     request.setCharacterEncoding("utf-8");  
  3.     ServletInputStream in = request.getInputStream;  
  4.     String s = IOUtils.toString(in);//Apache的commons组件中的包  
  5.     System.out.println(s);//结果如下  
  6. }  
[java] view plain copy
  1.   
执行结果如下:
和抓包来的没什么区别
[plain] view plain copy
  1. ------WebKitFormBoundaryH06xO2noLxVFeenm  
  2. Content-Disposition: form-data; name="username"  
  3. csdn  
  4. ------WebKitFormBoundaryH06xO2noLxVFeenm  
  5. Content-Disposition: form-data; name="filename"; filename="a.txt"  
  6. Content-Type: text/plain  
  7. E:\Application\workspace\exam\src\cn\itcast\day20\CountDemo.java  
  8. E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo.java  
  9. E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo2.java  
  10. E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo3.java  
  11. E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo4.java  
  12. E:\Application\workspace\exam\src\cn\itcast\day20\FileFilterDemo.java  
  13. E:\Application\workspace\exam\src\cn\itcast\day20\JavaFileList.java  
  14. E:\Application\workspace\exam\src\cn\itcast\day20\PrintWriterDemo.java  
  15. E:\Application\workspace\exam\src\cn\itcast\day20\PropertiesDemo.java  
  16. E:\Application\workspace\exam\src\cn\itcast\day20\SequenceDemo.java  
  17. E:\Application\workspace\exam\src\cn\itcast\day20\SequenceInputStreamDemo.java  
  18. E:\Application\workspace\exam\src\cn\itcast\day20\SequenceVideoDemo.java  
  19. E:\Application\workspace\exam\src\cn\itcast\day20\SplitFileDemo.java  
  20. ------WebKitFormBoundaryH06xO2noLxVFeenm--  

上传的任务就是将这些信息解析出来如果是文件部分保存到文件中,不是文件部分该给谁给谁。


4.按照上面的上传文件中ServletInputStream流的格式我自己写了一个,只能上传文本文件的上传方法。(能力有限)
[javascript] view plain copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.         throws ServletException, IOException {  
  3.     //得到流对象  
  4.     ServletInputStream in = request.getInputStream();  
  5.     //将流中的对象写入到一个字符串中。可能使用StringBuffer更好  
  6.     int len = 0;  
  7.     byte buf[] = new byte[1024];  
  8.     String content = "";  
  9.     while((len = in.read(buf))!=-1){  
  10.          content = content + new String(buf, 0, len);  
  11.     }  
  12.     //将内容按行分割  
  13.     String[] contents = content.split("\n");  
  14.     //将数组转换成数组  
  15.     List<String> lists = Arrays.asList(contents);  
  16.     //是否包含这个Content-Type: text/plain。也就是文本文件内容的开始了  
  17.     System.out.println("执行:"+lists.contains(new String("Content-Type: text/plain")));  
  18.     //获取开始和结束位置  
  19.     int start = 0;  
  20.     int end = 0;  
  21.     for (int i=1;i<lists.size();i++) {  
  22.         if(lists.get(0).equals(lists.get(i))){  
  23.              end = i;  
  24.         }  
  25.     }  
  26.       
  27.     System.out.println(start+":"+end);  
  28.     //将数组按开始位置和结束位置截取  
  29.     List<String> fileList = lists.subList(end+4, lists.size()-1);  
  30.     //保存的文件  
  31.     FileWriter writer = new FileWriter("F:\\a.txt");  
  32.     //遍历数组如入文件  
  33.     for (String s : fileList) {  
  34.         writer.write(s);  
  35.         writer.write("\n");  
  36.     }  
  37.     writer.close();  
  38. }  
  39.   
  40. public void doPost(HttpServletRequest request, HttpServletResponse response)  
  41.         throws ServletException, IOException {  
  42.     doGet(request,response);  
  43. }  


使用Apache的commons组件包实现上传(还是这个强大):



  1. 快速入门(得到的效果和上面的一样):
    1. [java] view plain copy
      1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
      2.             throws ServletException, IOException {  
      3.         //获取解析器工厂  
      4.         DiskFileItemFactory factory = new DiskFileItemFactory();  
      5.         //获得解析器  
      6.         ServletFileUpload fileUpload = new ServletFileUpload(factory);  
      7.         try {  
      8.             //解析request  
      9.             List<FileItem> items = fileUpload.parseRequest(request);  
      10.             //遍历解析得到的FileItem对象  
      11.             for(FileItem item : items){  
      12.                 //如果字段名是username  
      13.                 if(item.getFieldName().equalsIgnoreCase("username")){  
      14.                     //得到提交过来的值  
      15.                     System.out.println(item.getString());  
      16.                     //如果是这个说明是文件  
      17.                 }else if(item.getFieldName().equalsIgnoreCase("fileName")){  
      18.                     //得到提交过来的值,如果是文本文件能输出,否则是乱码  
      19.                     item.write(new File("F:\\","b.txt"));  
      20.                 }  
      21.             }  
      22.               
      23.         } catch (Exception e) {  
      24.             e.printStackTrace();  
      25.         }  
      26.     }  
      27.   
      28.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
      29.             throws ServletException, IOException {  
      30.         doGet(request, response);  
      31.     }  


  2. 完全体演示:
    1. [java] view plain copy
      1.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
      2.             throws ServletException, IOException {  
      3.         //解决中文文件名问题  
      4.         /** 
      5.          * 也可以是fileUpload.setHeaderEncoding("utf-8");优先级高 
      6.          */  
      7.         request.setCharacterEncoding("utf-8");  
      8.           
      9.         //获取解析器工厂,在factory中设置 (1024*20,new File("F://temp");如果文件过大  
      10.         //设置文件超过20kb就缓存,缓存文件是在F盘的temp文件下  
      11.           
      12.         DiskFileItemFactory factory = new DiskFileItemFactory();  
      13.         //获得解析器  
      14.         ServletFileUpload fileUpload = new ServletFileUpload(factory);  
      15.         //设置上传的全部大小,包括<input type='text'>  
      16. //      fileUpload.setSizeMax(1024*900);  
      17.           
      18.         //设置上传文件的大小,1024为1kb  
      19.         fileUpload.setFileSizeMax(300*1024);  
      20.           
      21. //      fileUpload.setHeaderEncoding("utf-8");  
      22.           
      23.         try {  
      24.             //解析request  
      25.             List<FileItem> items = fileUpload.parseRequest(request);  
      26.             //遍历解析得到的FileItem对象  
      27.             for(FileItem item : items){  
      28.                 //如果字段名是username  
      29.                 if(item.getFieldName().equalsIgnoreCase("username")){  
      30.                     //得到提交过来的值  
      31.                     System.out.println(item.getString());  
      32.                     //如果是这个说明是文件  
      33.                 }else if(item.getFieldName().equalsIgnoreCase("fileName")){  
      34.                     //得到文件名  
      35.                     String fileName = item.getName();  
      36.                     //防止有些浏览器上传文件的时候,上传文件的带盘符的绝对路径。我们只要文件名就行  
      37.                     int index = fileName.lastIndexOf("\\");  
      38.                     if(index!=-1){  
      39.                         fileName = fileName.substring(index+1);  
      40.                     }  
      41.                     //获取后缀名.假设我只上传静态图片格式的文件,也就是格式是jpg,bmp,png这三种。其他的都不要  
      42.                       
      43.                     index = fileName.lastIndexOf(".");  
      44.                     //说明没有后缀名  
      45.                     if(index==-1){  
      46.                         //一般情况是,通过request.setAttribute("msg","您上传的文件没有后缀名,请重新上传");  
      47.                         //转发到request.getRequestDispatcher("路径").forward(request, response);  
      48.                         //return;  
      49.                           
      50.                         //这里我就全输出了  
      51.                         System.out.println("上传的文件没有后缀名");  
      52.                         return;  
      53.                     }  
      54.                       
      55.                     String extension = fileName.substring(index+1);  
      56.                     //上传文件如果不是以上面三个后缀名结尾,就输出错误信息  
      57.                     if (!extension.equalsIgnoreCase("bmp")  
      58.                             && !extension.equalsIgnoreCase("jpg")  
      59.                             && !extension.equalsIgnoreCase("png")) {  
      60.                           
      61.                         System.out.println("上传的文件必须是bmp或jpg或png");  
      62.                         return;  
      63.                     }  
      64.                     //上传文件肯定是多个,命名也是一个问题。使用Apache的commons组件的类  
      65.                     fileName = getuuid()+"."+extension;  
      66.                       
      67.                       
      68.                     //上传的文件放到哪,只能放在WEB-INF下面.如果你下面还要放分目录的话。有很多的算法  
      69.                     //有按时间的,用户的,文件名的hash值的等等。看需求  
      70.                     //我来按时间,也就是每天一个文件夹  
      71.                     String timeStamp = new SimpleDateFormat("yyyy.MM.dd").format(new Date());  
      72.                     String savePath = this.getServletContext().getRealPath("/WEB-INF/myupload")+"\\"+timeStamp;  
      73.                     File f = new File(savePath);  
      74.                     f.mkdirs();  
      75.                     item.write(new File(savePath,fileName));<pre name="code" class="java"><span style="white-space:pre">                    </span>item.delete();//删除临时文件</pre> }}} catch (Exception e) {if(e instanceof FileUploadBase.FileSizeLimitExceededException){System.out.println("上传文件不能大于300kb");return;}else{e.printStackTrace();}}}public static String getuuid() {return UUID.randomUUID().toString().replace("-",  
      76.  "");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}  
      77. <pre></pre>  
      78. <pre></pre>  
    2. 如果还要判断上传文件的宽度和高度。只需在后面加上:
      [java] view plain copy
      1. <span style="white-space:pre">                  </span>File f = new File(savePath);  
      2.                     f.mkdirs();  
      3.                     File saveFile = new File(savePath,fileName);  
      4.                     item.write(saveFile);  
      5.                     item.delete();//删除临时文件  
      6.                       
      7.                     ImageIcon icon = new ImageIcon(saveFile.getAbsolutePath());  
      8.                     Image image = icon.getImage();  
      9.                     image.getHeight(null);//得到图片的高  
      10.                     image.getWidth(null);//得到文件的宽  
      11.                       
      12.                     //如果不满足条件  
      13.                     saveFile.delete();  

其他类型的文件也就类似了。
0 0
原创粉丝点击