zoukankan      html  css  js  c++  java
  • 文件的上传和下载---以图片为例

    上传

    创建JSP页面,添加form表单

    注意点:1.表单需要使用“post”请求

        2.表单的默认属性enctype="application/x-www-form-urlencoded"

        3.上传文件的表单enctype需要设置为 multipart/form-data

        4.当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。

    <form action="${pageContext.request.contextPath }/FileUpLoadServlet" method="post" enctype="multipart/form-data">
    	User:<input type="text" name="name" /><br/>
    	<input type="file" name="photo"/><br/>
    	<input type="file" name="photo1"/><br/>
    	<input type="file" name="photo2"/>
    	<input type="submit" value="提交">
    </form>
    

    导包:一般情况下使用commons-fileupload-1.3.1.jar这个工具来解析多部件请求
               fileupload 依赖 commons-io 所以我们要是Filtupload需要同时导入io包

              

    核心类:
      DiskFileItemFactory
        - 工厂类,用于构建一个解析器实例。
                       
      ServletFileUpload
        - 解析器类,通过该类实例来解析request中的请求信息。
                       
      FileItem
        - 工具会将我们请求中每一个部件,都封装为一个FileItem对象,处理文件上传时,只需要调用该对象的方法

      具体代码:

    //1.创建一个工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    //2.创建ServletFileUpload对象,通过这个对象完成上传功能
    ServletFileUpload fileUpload = new ServletFileUpload(factory);
    //用fileUpload这个对象解析request请求
    List<FileItem> fileList = fileUpload.parseRequest(request);
    

     fileList的方法:

    类型 方法 详解
    boolean isFormField() 当前表单项是否是一个普通表单项,true是普通表单项, false是文件表单项
    String getContentType() 返回的是文件的类型,是MIME值
    String getFieldName() 获取表单项的name属性值
    String getName() 获取上传的文件的名字
    long getSize() 获取文件的大小
    String getString(String encoding) 获取表单项的value属性值,需要接受一个编码作为参数。
    void write(File file)  将表单项中的内容写入到磁盘中

    部分方法代码书写

    long size = item.getSize();
    String contentType = item.getContentType();//文件类型
    String name = item.getName();//图片实际名
    String fieldName = item.getFieldName();//属性名
    
    System.out.println(size+" "+contentType+" "+name+" "+fieldName);
    

     完整代码

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //1.创建一个工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    //2.创建ServletFileUpload对象,通过这个对象完成上传功能
    ServletFileUpload fileUpload = new ServletFileUpload(factory);
    //用fileUpload这个对象解析request请求
       try {
           List<FileItem> fileList = fileUpload.parseRequest(request);
           for(FileItem item:fileList){
           if(item.isFormField()){
                  //代表普通表单项
                  String name = item.getFieldName();
                  String value = item.getString("utf8");
                  System.out.println(name+":"+value);
           }else{
                 //代表上传的文件
                 long size = item.getSize();
                 String contentType = item.getContentType();//文件类型
                 String name = item.getName();//图片实际名
                 String fieldName = item.getFieldName();//属性名
                 System.out.println(size+" "+contentType+" "+name+" "+fieldName);
    
                 item.write(new File("C:\Users\LWJJJJJ\Desktop\123.jpg"));
           }//MIME类---总类型/具体类型
       }
    } catch (Exception e) {
           // TODO Auto-generated catch block
          e.printStackTrace();
        }
    }
    

     细节问题:

      1.部分浏览器会将文件的完整路径作为文件名发送。也就是说路径会产生问题

         但是一般浏览器,如火狐、谷歌、IE7以上都不会,IE6会

         像这类文件名我们需要截取一下字符串,只获取名字这部分,而不需要获取路径部分的信息。

    if(name.contains("\")){
         //如果包含则截取字符串
         name = name.substring(name.lastIndexOf("\")+1);
       //一定要+1,不然会多了一个/ }

      2.上传的文件有可能出现重名,后上传的文件会将先上传的文件覆盖

         解决方法:给文件加一个唯一标识符--UUID

    String prefix = UUID.randomUUID().toString();
    prefix.replace("-", "");
    String fielName=prefix+"_"+name;
    

       3.有些情况需要限制上传文件的大小

    fileUpload.setFileSizeMax(1024*17600);//限制单个文件的大小
    fileUpload.setSizeMax(1024*20000);//限制文件的总大小
    
    //会分别抛出异常
    catch(SizeLimitExceededException e){
         System.out.println("总图片过大");
    }catch(FileSizeLimitExceededException e){
         System.out.println("单张图片过大");
    }
    

       4.当用户上传一个空的文件,依然会将文件保存到硬盘上

         解决方法:在保存文件应该先对文件的大小进行判断,如果size为0,则不处理

    long size = item.getSize();
    //如果不存在,就继续,不必创造文件
    if(size==0){
    	continue;
    }
    

     下载

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	ServletContext servletContext = request.getServletContext();
    	String filename = "风吹麦浪.mp3";
    	String path = servletContext.getRealPath("/WEB-INF/"+filename);
    	File file = new File(path);
    	//创建输入流
    	InputStream in = new FileInputStream(file);
    	//告诉浏览器文件的类型,需要设置一个MIME值
    	//用servletContext.getMimeType()直接获取path的MIME值
    	String type = servletContext.getMimeType(path);
    		
    	response.setContentType(type);
    	filename = new String(filename.getBytes("gbk"),"iso8859-1");
    	//下载文件信息
    	response.setHeader("Content-Disposition", "attachment;filename="+filename);
    	//输出流,到浏览器上
    	ServletOutputStream out = response.getOutputStream();
    	IOUtils.copy(in, out);
    	in.close();
    }
    
  • 相关阅读:
    struts2ModelDriven模型驱动
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    struts2Token Interceptor(处理表单重复提交)
    strutsOGNL标签
    嵌入式关系型SQLite数据库
    SQLite数据库的增删改查
    Pull解析器解析XML文件和生成XML文件
    proguard.cfg 系统找不到指定的文件
    struts2ONGL原理和表达式
    写代码的三重境界 Hanson
  • 原文地址:https://www.cnblogs.com/lwj-0923/p/7388292.html
Copyright © 2011-2022 走看看