细述文件的上传和下载

来源:互联网 发布:惠州网络推广哪家好 编辑:程序博客网 时间:2024/06/08 14:45

引言:文件的上传和下载是我们在web开发时候经常要用到的一个模块,今天就这个模块进行一下详细的说明。

  • 文件上传
    • 文件上传分为两个部分,一部分是servlet3.0以前的文件上传方式,主要借助commons-fileupload组件。代码如下:
@WebServlet("/upload")public class UploadServlet extends HttpServlet{    private static final long serialVersionUID = 1L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.getRequestDispatcher("/WEB-INF/views/upload.jsp").forward(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.setCharacterEncoding("UTF-8");        //设置上传路径        File file = new File("G:/upload");        //如果这个文件夹不存在,就创建        if(!file.exists()) {            file.mkdir();        }        //上传临时路径        File tempFile = new File("G:/uploadtemp");        if(!tempFile.exists()) {            tempFile.mkdir();        }        if(ServletFileUpload.isMultipartContent(req)) {            DiskFileItemFactory factory = new DiskFileItemFactory();            //设置缓冲区大小            factory.setSizeThreshold(1024 * 10);            //设置临时文件夹            factory.setRepository(tempFile);            ServletFileUpload fileupload = new ServletFileUpload(factory);                      //设置最大文件大小            fileupload.setFileSizeMax(1024 * 1024 * 10);            try {                List<FileItem> itemList = fileupload.parseRequest(req);                for(FileItem item : itemList) {                    //表单元素分为文件元素和普通元素                    if(item.isFormField()) {                        //普通元素                        String fileName = item.getFieldName();                        String value = item.getString("UTF-8");                        System.out.println("fileName:"  + fileName);                        System.out.println("value: " + value);                    }else{                        //文件元素                        String name = item.getName();                        String fileName = item.getFieldName();                        System.out.println("fileName:"  + fileName);                        System.out.println("name: " + name);                        String newName = UUID.randomUUID().toString() + name.substring(name.lastIndexOf("."));                        InputStream input = item.getInputStream();                        FileOutputStream output = new FileOutputStream(new File(file,newName));                        IOUtils.copy(input, output);                        /*byte[] buffer = new byte[512];                        int len = -1;                        while((len = input.read(buffer))!= -1) {                            output.write(buffer, 0, len);                        }*/                        System.out.println(name + "上传成功");                        output.flush();                        output.close();                        input.close();                    }                }            } catch (FileUploadException e) {                e.printStackTrace();            }        }else{            throw new ServletException("请设置form表单的entype属性");        }    }}
  • 相比servlet3.0以前的很麻烦,且很难读懂的代码而言(其实我自己也不是很明白,只是知道应该这么写而已),servlet3.0+有了全新的文件上传方式,这种代码看起来更加明了清晰。
    注意点:

    1. 添加MultipartConfig注解
@WebServlet("/upload2")@MultipartConfigpublic class UploadServlet2 extends HttpServlet{    private static final long serialVersionUID = 1L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.getRequestDispatcher("/WEB-INF/views/upload2.jsp").forward(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.setCharacterEncoding("UTF-8");        //servlet3.x上传文件可以通过req.getParameter()获取普通表单的值        String desc = req.getParameter("desc");        System.out.println("desc:" + desc);        //获取part对象        Part part = req.getPart("file");        //文件元素的值        String name = part.getName(); //name属性值        String contentType = part.getContentType(); //MIME类型        long size = part.getSize(); //文件大小        String filename = part.getSubmittedFileName();//上传文件名称        //将文件大小改成可读的        String readSize = FileUtils.byteCountToDisplaySize(size);        //上传路径        File file = new File("G:/upload");        if(!file.exists()) {            file.mkdir();        }        //这一部分是给新上传的文件一个永不重复的文件名        String newName = UUID.randomUUID().toString()                 + filename.substring(filename.lastIndexOf("."));        InputStream input = part.getInputStream();        OutputStream output = new FileOutputStream(new File(file,newName));        IOUtils.copy(input, output);            System.out.println(filename + "上传成功");        output.flush();        output.close();        input.close();      }}
  • 下面说一下文件下载,其实原理都是一样的,上传和下载都必须把文件转换为流的形式进行操作,上传的时候,是把文件流读进来,往电脑硬盘里写的时候应该新new 一个输出流,然后用Commons的IOUtil copy一下,下载的时候这个正好是相反的,应该是new 一个输入流,将服务器中的文件读入流中,再通过response对象获取输出流,之后用IoUtil进行copy。具体代码如下:
@WebServlet("/download")public class DownloadServlet extends HttpServlet{    /**     *      */    private static final long serialVersionUID = 1L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String fileName = req.getParameter("file");        String downloadName = req.getParameter("downloadName");//"我的照片.jpg";        File saveDir = new File("G:/upload");        File file = new File(saveDir,fileName);        if(file.exists()){            if(StringUtils.isNotEmpty(downloadName)) {                downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");                //设置MIME类型                resp.setContentType("application/octet-stream");                //resp.addHeader("content-type", "application/octet-stream");                //设置文件名,添加响应头attachment; filename="hello.jpg"                resp.addHeader("Content-Disposition", "attachment; filename=\"" + downloadName + "\"");            }            InputStream input = new FileInputStream(file);            OutputStream output =  resp.getOutputStream();//这是            IOUtils.copy(input, output);            output.flush();            output.close();            input.close();        } else{            resp.sendError(404,"路径错误");        }    }}
原创粉丝点击