web开发中文件上传(3)


 
实例代码及注解
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        List types=Arrays.asList(".jpg",".gif",".avi",".txt");    //这个用法
        try{
            DiskFileItemFactory factory=new DiskFileItemFactory();     //创建解析工厂
            factory. setSizeThreshold(1024*1024);     //指定内存缓冲区大小
/            /指定临时文件存储位置    this.getServletContext().getRealPath这个位置是哪里?
            factory. setRepository( new File(this.getServletContext().getRealPath("/temp")));
            ServletFileUpload upload=new ServletFileUpload(factory);     //创建解析器

            //定义监听器,根据解析器,生成进度条,实现 ProgressListener接口并实现其方法
            upload. setProgressListener(new ProgressListener() {
                public void update(long pBytesRead, long pContentLength, int pItems) {
                        System.out.println("当前已解析:"+ pBytesRead);     //用进度条插件生成pBytesRead
                    }
            });
            upload .setFileSizeMax(1024*1024*5);         //设置文件大小限制
            if(!upload. isMultipartContent(request)){     //判断是否是multipart/form-data。 若不是,则按传统方式处
            request.getParameter("username");
            return;
        }
//以下解决文件上传乱码,但不能解决普通字段乱码。设置request.setCharacterEncoding("UTF-8")也不行,
         upload. setHeaderEncoding ("UTF-8"); //*****************
         List list=upload. parseRequest(request);  //调用解析器解析request.得到保存了所有上传数据的list
             for(FileItem fileitem:list){     //迭代list集合,获得封装了每个输入项数据的fileItem
                    if(fileitem. isFormField()){    / /判断item的类型,如果是普通字段,则直接获取数据,
                    String name=fileitem.getFieldName();
                     String inputValue= fileitem.getString("UTF-8");       //解决普通字段乱码,也可用以以两行代码
                                       /*  String inputValue=fileitem.getString();
                                    inputValue=new String(inputValue.getBytes("iso8859-1"),"UTF-8");*/
            }else{     // 如果为上传文件,则调用流获取数据写到本地硬盘
                String filename=fileitem.getName().substring( fileitem.getName().lastIndexOf("\\")+1);
                //通过文件名对文件是否存在做判断,判断用户是否有上传文件过来。
                if(filename==null||filename.trim().equals("")){
                continue;      // 注意continue用法;
            }
    String ext=filename. substring(filename. lastIndexOf("."));    //获取扩展名并判断
        if(!types. contains(ext)){
        request.setAttribute("message", "本系统不支持"+ext+"这种类型");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
        return;
    }
            System.out.println("fileitem.getName="+fileitem.getName());
            System.out.println("fileitem.getFieldName="+fileitem.getFieldName());
            System.out.println(fileitem.getName().lastIndexOf("\\")+1);

  //这句是错的 InputStream in=new InputStream( fileitem );但这句对 FileInputStream in=new FileInputStream(file);
InputStream in=fileitem.getInputStream();    

        //读取输入流
        byte[] buffer=new byte[1024];
        int len=0;
        String uuidFileName=generateFileName(filename);
        String savepath=generateSavePath(this.getServletContext().getRealPath("/WEB-INF/upload"), uuidFileName); //注意上传文件存放于外界无法访问的位置,
        System.out.println(this.getServletContext().getRealPath("/WEB-INF/upload"));
        FileOutputStream out= new FileOutputStream(savepath+ File.separator+uuidFileName); //File.separator与"\\"作用相同,但不受平台影响。

        while((len=in.read(buffer))>0){
            out.write(buffer, 0, len);
        }
            in.close();
            out.close();
            fileitem.delete();     //最后一定要记得,删除临时文件
        }
    }
        //两次catch,及catch中转发,这个技巧
} catch ( FileUploadBase.FileSizeLimitExceededException e) {
 //注意:视频课程中,上传文件代码是当作方法,写在工具类中,但这个异常 FileUploadBase.FileSizeLimitExceededException 的代码却并为放在工具类中跳转到jsp,而是抛到调用层(serlvet层)再跳转jsp,不知这样做有什么好处?? 
        request.setAttribute("message", "文件大小不能超5M");
        request.getRequestDispatcher("/message.jsp").forward(request, response);   
        return;
} catch(Exception e){
        throw new RuntimeException(e);
}
        request.setAttribute("message", "上传成功");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
}
 
//为避免同一文件夹中文件太多,将文件保存路径按文件名hashcode后四位生成。
public String generateSavePath(String path,String uuidFileName){
    int hashcode=uuidFileName .hashCode();
    int dir1=hashcode&15;
    int dir2=(hashcode>>4)&0xf;
    String savepath=path+File.separator+dir1+File.separator+dir2;
    File file=new File(savepath);
    if(! file.exists()){
    file. mkdirs(); //mkdir与mkdirs有何区别?
    }
        return savepath;
}
 
//为避免文件同名,系统生成全球唯一的文件名。
public String generateFileName(String filename){
    return  UUID.randomUUID().toString()+"_"+filename;
}

//还有部分说明内容,参阅QQ笔记
??this.getServletContext().getRealPath("/WEB-INF/upload")+"\\"+filename这句话到底会返回一个什么样的路径呢?

你可能感兴趣的:(JAVA)