细述文件的上传和下载

引言:文件的上传和下载是我们在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")
@MultipartConfig
public 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,"路径错误");
        }


    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值