zoukankan      html  css  js  c++  java
  • Servlet Java Web开发(7)上传下载

    上传

    先看一个例子:

    有两个表单项,对应form的代码

    <form action="<c:url value='/Upload1Servlet'/>" method="post" enctype="multipart/form-data">
      用户名;<input type="text" name="username"/><br/>
      照 片:<input type="file" name="zhaoPian"/><br/>
      <input type="submit" value="上传"/>
    </form>

    注意方法post,enctype和type="file"

    下面这个上传协议内容说明了简单文本的上传。

    POST /day22_1/Upload1Servlet HTTP/1.1
    Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
    Referer: http://pc-201706241553:8080/day22_1/form1.jsp
    Accept-Language: zh-CN
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/7.0)
    Content-Type: multipart/form-data; boundary=---------------------------7e22e5382051c
    UA-CPU: AMD64
    Accept-Encoding: gzip, deflate
    Host: pc-201706241553:8080
    Content-Length: 469
    Connection: Keep-Alive
    Cache-Control: no-cache
    Cookie: JSESSIONID=474036FE3AE8CF0AE6DF94DD1F566561
    
    -----------------------------7e22e5382051c
    Content-Disposition: form-data; name="username"
    
    helloworld
    -----------------------------7e22e5382051c
    Content-Disposition: form-data; name="zhaoPian"; filename="myfilename.txt"
    Content-Type: text/plain
    
    The content of the file.
    the legion has returned.
    and the king has returned.
    The lord of the rings shall never exist.
    That is the end of the sentence....
    //End..
    -----------------------------7e22e5382051c--
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 0
    Date: Mon, 06 Aug 2018 00:44:56 GMT

    说明:在请求头之后,连续两个0X0D,0X0A,然后

    -----------------------------7e22e5382051c

    将上传可以分为两个部分,也即是用户界面中的2个表单项

    1.文本框中 username的内容

    2.文件相关内容,文件名,文件类型,文件内容

     Servlet对上传文件的处理

    1.打印上传的文本

    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
    ServletInputStream in = request.getInputStream();
    String s = IOUtils.toString(in);//该方法使用了commons-io.jar
    System.out.println(s);

    2.使用commons-fileupload.jar

    关键API:

    获取ServletFileUpload :ServletFileUpload sfu=new ServletFileUpload(new DiskFileItemFactory());

    获取表单项列表List<FileItem> mylist=sfu.parseRequest(request);

    其中mylist.get(0)是上面所述的普通表单项,username,

    FileItem fil2=mylist.get(1)就是文件表单项,对于上传的文件,可以getContentType,getSize,getName,

    最关键,保存文件,新建一个File f=new File("C;/xx.txt");

    使用FileItem 的write方法保存,fil2.write(f);

    request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload sfu = new ServletFileUpload(factory);
            try {
                List<FileItem> fileItemList = sfu.parseRequest(request);
                FileItem fi1 = fileItemList.get(0);
                FileItem fi2 = fileItemList.get(1);
                System.out.println("普通表单项演示:" + fi1.getFieldName() + 
                        "=" + fi1.getString("UTF-8"));
                System.out.println("文件表单项演示:");
                System.out.println("Content-Type: " + fi2.getContentType());
                System.out.println("size: " + fi2.getSize());
                System.out.println("filename: " + fi2.getName());
                File destFile = new File("c:/baibing.jpg");
                fi2.write(destFile);
            } catch (FileUploadException e) {
                throw new RuntimeException(e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

    3.相关细节。

    a,文件保存到WEB-INF目录下,比如uploads文件夹。

    b.防止乱码request.setCharacterEncoding("utf-8");

    c.限制上传文件大小

    //在sfu.parseRequest(request);之前调用
    sfu.setFileSizeMax(100 * 1024);//限制单个文件大小为100K
    sfu.setSizeMax(1024 * 1024);//限制整个表单大小为1M

     如果上传文件超过size,抛出异常。FileUploadException

    d.上传超大文件

    此时不使用c中设置文件大小,为了防止内存被撑爆,应该设置缓存,一边读一边往硬盘里写。

    DiskFileItemFactory的一个构造函数可以实现该功能,参数1为缓存大小,参数2为临时文件目录。

    DiskFileItemFactory factory = new DiskFileItemFactory(20*1024, new File("F:/f/temp"));

    下载

    下载关键API

    //指定文件名
    String filename1="G:/myfile.mp4";
    //使用commons-io
    IOUtils.copy(new FileInputStream(filename1), resp.getOutputStream());

    让浏览器弹出下载框,指定文件名。

    可使用

    response.addHeader("content-disposition", "attachment;filename=" + filename); 

    一个完整的例子

    public class Download1Servlet extends HttpServlet {
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            
            String filename = "C:/流光飞舞.mp3";
            
            // 为了使下载框中显示中文文件名称不出乱码!
    //        String framename = new String("流光%飞舞.mp3".getBytes("GBK"), "ISO-8859-1");
            String framename = filenameEncoding("流光%飞舞.mp3", req);
            
            String contentType = this.getServletContext()
                    .getMimeType(filename);//通过文件名称获取MIME类型
            String contentDisposition = "attachment;filename=" + framename;
            // 一个流
            FileInputStream input = new FileInputStream(filename);
            
            //设置头
            resp.setHeader("Content-Type", contentType);
            resp.setHeader("Content-Disposition", contentDisposition);
            
            // 获取绑定了响应端的流
            ServletOutputStream output = resp.getOutputStream();
            
            IOUtils.copy(input, output);//把输入流中的数据写入到输出流中。
            
            input.close();
        }
        
        // 用来对下载的文件名称进行编码的!
        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;
        }
    }
  • 相关阅读:
    马士兵_聊天系统_知识储备库
    最近一些情况
    JAVA坦克大战项目练习日4
    JAVA坦克大战项目练习日3
    JAVA坦克大战项目练习日2
    JAVA坦克大战项目练习日1
    课后实战String的一些细节
    Java从入门到精通之数组篇
    58_自定义标签打包以及使用自定义标签教程
    javaWeb安全篇(1)——防盗链技术的实现
  • 原文地址:https://www.cnblogs.com/legion/p/9398474.html
Copyright © 2011-2022 走看看