web端基于java的文件上传下载

来源:互联网 发布:人工智能编程入门 编辑:程序博客网 时间:2024/05/18 03:23

web端的文件上传和下载

在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。

  对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件

的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上

传组件。这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,

struts上传的功能就是基于这个实现的。common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。

对于此包可以自己搜索,资源很多。

1.上传文件逻辑

下面写下逻辑层的代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

HttpSession session = request.getSession(); 
String fileExtName = null;
String realSavePath = null;
    String saveFilename = null;
    int  filesize = 0;
/*得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全*/
String savePath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
/*上传时生成的临时文件保存目录*/
String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/temp");
File tmpFile = new File(tempPath);
if (!tmpFile.exists()) {
/*创建临时目录*/
tmpFile.mkdir();
}
   try{
                /*使用Apache文件上传组件处理文件上传步骤:
                1、创建一个DiskFileItemFactory工厂*/
                DiskFileItemFactory factory = new DiskFileItemFactory();
                /*设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。*/
                factory.setSizeThreshold(1024*100);
                /*设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
                设置上传时生成的临时文件的保存目录*/
                factory.setRepository(tmpFile);
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setProgressListener(new ProgressListener(){
                    public void update(long pBytesRead, long pContentLength, int arg2) {
                        System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                        /**
                        
                         */
                    }
                });
                /**
                解决上传文件名的中文乱码
                 */
                upload.setHeaderEncoding("UTF-8"); 
                request.setCharacterEncoding("UTF-8");
                /**
                3、判断提交上来的数据是否是上传表单的数据       
                设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
                 */               
                upload.setFileSizeMax(1024*1024*100);
                /**设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB*/
                upload.setSizeMax(1024*1024*1000);
                /**4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项*/
                List<FileItem> list = upload.parseRequest(request);
                for(FileItem item:list){
                filesize=(int) list.get(0).getSize();
                 /**  filesize=parse(int)list.size();*/
                    /**如果fileitem中封装的是普通输入项的数据*/
                    if(item.isFormField()){
                        String name = item.getFieldName();
                        /**解决普通输入项的数据的中文乱码问题*/                       
                        String value = item.getString("UTF-8");
                        System.out.println(name + "=" + value);
                    }else{
                        String filename = item.getName();
                        if(filename==null || filename.trim().equals("")){
                            continue;
                        }
                       /**注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                       处理获取到的上传文件的文件名的路径部分,只保留文件名部分*/
                        filename = filename.substring(filename.lastIndexOf("\\")+1);
                        /**得到上传文件的扩展名*/
                        fileExtName = filename.substring(filename.lastIndexOf(".")+1);
                        /**如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
                        获取item中的上传文件的输入流*/
                        InputStream in = item.getInputStream();
                        /**得到文件保存的名称*/
                        saveFilename = makeFileName(fileExtName);
                        /**得到文件的保存目录*/
                      realSavePath = makePath(saveFilename, savePath);
                        /**创建一个文件输出流*/
                        FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFilename);
                        /**创建一个缓冲区*/
                        byte buffer[] = new byte[1024];
                       /**判断输入流中的数据是否已经读完的标识*/
                        int len = 0;
                       /** 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据*/
                        while((len=in.read(buffer))>0){
                      /**使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中*/
                            out.write(buffer, 0, len);
                        }
                        
                        in.close();
                        
                        out.close();
             
                    }
                }
            }catch (Exception e) {
        e.printStackTrace();
    }

    return "**路径**";

}

 /**防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名*/
private String makeFileName(String fileExtName){  
Calendar c = Calendar.getInstance(); 
SimpleDateFormat   df1   =   new   SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
String CurDatetime = df1.format(c.getTime());
String DOCID = CurDatetime + String.valueOf(Math.random()).substring(2, 4);
DOCID = DOCID.replace(":", "").replace(" ", "").replace("-", "");
return DOCID+"."+fileExtName;
   }
   




/**
    * 为防止一个目录下面出现太多文件,要使用hash算法打散存储
   */ 
   private String makePath(String filename,String savePath){
       /**得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址*/      
    int hashcode = filename.hashCode();
       int dir1 = hashcode&0xf;  //0--15
       int dir2 = (hashcode&0xf0)>>4;  //0-15
       /**构造新的保存目录*/
       String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5      
       File file = new File(dir);
       /**如果目录不存在*/
       if(!file.exists()){
           file.mkdirs();
       }
       return dir;
}

以上就是上传文件的主要逻辑代码,楼楼是是以Spring+Springmvc+Mybatis为框架进行搭建的项目工程。所以里面有一些

属于框架的东西。

2.下载文件逻辑

下面是下载的逻辑代码:

/**下载附件*/
@RequestMapping("/DownFile")
public String  DownFile(HttpServletRequest request,HttpServletResponse response,String upautor)
throws ServletException, IOException{
/**得到要下载的文件*/
       String fileName = request.getParameter("upautor");  
       String realpath=request.getParameter("realpath");
       String filetype =request.getParameter("filetype");
       fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
       String picgif="gif";
       String picjpg="jpg";
       String picpng="png";        
       String picbmp="bmp"; 
       String redrect=null;
       /**图片的格式有(具体分析):   
        * gig  tif rgb dib eps jpe pcx 
       得到要下载的文件*/
       File file = new File(realpath + "\\" + fileName);
      /**处理文件名*/
       String realname = fileName.substring(fileName.indexOf("_")+1);
      /**设置响应头,控制浏览器下载该文件*/
       /**判断附件格式,如果为图片则显示,否则下载*/
       if(filetype.equals(picgif)||filetype.equals(picjpg)||filetype.equals(picpng)||filetype.equals(picbmp)){   
        response.setContentType(filetype);
        response.setContentLength((int)file.length());
        response.setHeader("Content-Disposition", "inline; filename="
        + URLEncoder.encode(realname, "UTF-8"));
        InputStream in = new FileInputStream(file);
        OutputStream out = response.getOutputStream();
        long statistic = 0;
    byte buffer[] = new byte[8192];
    do {
    int bytesRead = in.read(buffer);
    if (bytesRead == -1)
    break;
    out.write(buffer, 0, bytesRead);
    statistic = statistic + bytesRead;
    out.flush();
    } while (true);
    in.close();
    out.close();
       
        redrect="redirect:/upload/showFile";
       }else
       {
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
        /**读取要下载的文件,保存到文件输入流*/
       FileInputStream in = new FileInputStream(realpath + "\\" + fileName);
       /**创建输出流*/
       OutputStream out = response.getOutputStream();
       /**创建缓冲区*/
       byte[] buffer = new byte[1024];
       int len = 0;
       /**循环将输入流中的内容读取到缓冲区当中*/
       while((len=in.read(buffer))>0){
        response.setContentType("image/jpg");
       response.setContentLength(buffer.length);
          /**输出缓冲区的内容到浏览器,实现文件下载*/
           out.write(buffer, 0, len);
       }
       
       in.close();
       out.close();
       }
       return "**路径**";
}

通过以上可以在web工程中实现文件的上传和下载,项目中是以图片为例,并为其设置了格式的限制,修改对应需要自适应。


0 0