zoukankan      html  css  js  c++  java
  • Servlet文件上传和下载的复习

    上传

    使用Servlet完成上传和下载相较于使用Struts框架有点麻烦,毕竟更偏底层了

    项目中主要使用的jar包:

    commons-io-2.2.jar  commons-fileupload-1.3.2.jar

    其他使用的jar有:

    commons-beanutils-1.8.3.jar commons-logging-1.1.1.jar itcast-tools-1.4.2.jar

    页面:

    <body>
    <form action="<c:url value='/uploadServlet3'/>" method="POST" enctype="multipart/form-data">
      照 片:<input type="file" name="zhaopian"/><br/>
    <input type="submit" value="提交"/>
    </form>

    值得注意的是:form要使用post提交,并使用enctype,这和使用Struts的页面要求是一致的

    上传文件四步骤
     1.创建工厂(DiskFileItemFactory)
     2.根据工厂创建解析器(ServletFileUpload)
     3.解析request,得到FileItem集合
     4.遍历FileItem,调用其API完成操作

    我将文件保存在WEB-INF中,这样的话通过浏览器是直接访问不到这个资源的,在WEB-INF中还使用了根据文件名的哈希名称前两个首字母生成目录来存放,对了,这个文件名还用了UUID值+_+文件名的方式避免同名问题,对于部分浏览器可能出现据对路径的问题也进行了处理

    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import cn.itcast.commons.CommonUtils;
    
    public class UploadServlet3 extends HttpServlet {
        
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
        
        public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {
                //前三步
                //DiskFileItemFactory factory=new DiskFileItemFactory();
                //可以使用临时目录(d:/temp需先创建)和设置缓存大小(20kb)
                DiskFileItemFactory factory=new DiskFileItemFactory(20*1024,new File("d:/temp"));
                ServletFileUpload fileUpload=new ServletFileUpload(factory);
                List<FileItem> list = fileUpload.parseRequest(req);
                
                FileItem fi1 = list.get(1);
                //得到文件保存的路径(files目录需创建)
                String root = this.getServletContext().getRealPath("/WEB-INF/files/");
                //处理绝对路径问题
                String fileName=fi1.getName();
                int index=fileName.lastIndexOf("//");
                if(index!=-1){
                    fileName=fileName.substring(index+1);
                }
                
                //处理重名问题
                String saveFileName=CommonUtils.uuid()+"_"+fileName;
                
                //目录打散
                //1.获得文件名的哈希值并转换为十六进制
                int hashCode = fileName.hashCode();
                String hex = Integer.toHexString(hashCode);
                //2.获得十六进制的前两位,生成目录链
                File dirFile=new File(root,hex.charAt(0)+"/"+hex.charAt(1));
                dirFile.mkdirs();
                //3.创建文件并保存
                File desFile=new File(dirFile,saveFileName);
                fi1.write(desFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    
    }

    这里使用了CommonUtils类来生成UUID值,这个类是在itcast-tools-1.4.2.jar(传智播客提供)

    下载

    下载所使用的jar包是:commons-io-2.2.jar

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.URLEncoder;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.io.IOUtils;
    import sun.misc.BASE64Encoder;
    
    public class DownloadServlet extends HttpServlet {
    
        public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            /*
             * 文件下载,两个头一个流
             * 响应头1:Content-Type
             * 响应头2:Content-Disposition
             * 流:下载文件数据
             */
            String fileName="e:/IBelieve.mp3";     //文件所在位置
            String frameName=filenameEncoding("%IBelieve%.mp3", req);  //下载时显示的文件名
            String contentType=this.getServletContext()
                    .getMimeType(fileName);    //通过文件名得到MIME类型
            String contentDisposition="attachment;filename="+frameName;
            //一个流
            FileInputStream inputStream=new FileInputStream(fileName);
            //设置头
            resp.setHeader("Content-Type", contentType);
            resp.setHeader("Content-Disposition", contentDisposition);
            //获取绑定了响应端的流
            ServletOutputStream outputStream=resp.getOutputStream();
            
            IOUtils.copy(inputStream, outputStream);   //将输入流的数据写到输出流
            
            inputStream.close();
            
        }
        
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
        
        //用来对下载文件名进行编码
        public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
            String agent = request.getHeader("User-Agent"); //获取浏览器
            if (agent.contains("Firefox")) {
                BASE64Encoder base64Encoder = new BASE64Encoder();
                filename = "=?utf-8?B?"
                        + base64Encoder.encode(filename.getBytes("utf-8"))
                        + "?=";
            } else if(agent.contains("MSIE")) {
                filename = URLEncoder.encode(filename, "utf-8");
            } else {
                filename = URLEncoder.encode(filename, "utf-8");
            }
            return filename;
        }
    }

    filenameEncoding()方法可以根据浏览器的不同对下载的文件名进行编码,避免乱码

  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/lz2017/p/7090859.html
Copyright © 2011-2022 走看看