zoukankan      html  css  js  c++  java
  • multipart/form-data 文件上传表单中 传递参数无法获取的原因!

    1.什么是multipart/form-data

    首先我们需要明白在html中的enctype属性,
    enctype:规定了form表单在发送到服务器时候编码方式。他有如下的三个值。

    • ①application/x-www-form-urlencoded。默认的编码方式。
      但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
    • ②multipart/form-data 。
      指定传输数据为二进制类型,比如图片、mp3、文件。
    • ③text/plain。
      纯文体的传输。
      空格转换为 “+” 加号,但不对特殊字符编码。

    2.明确在enctype参数为application/x-www-form-urlencoded的时候post和get请求参数和请求体是什么形式的

    get请求

    请求头:

    GET  /www.xxx.com?name=%22hello+world%22&**file=temp.png**&submit=submit HTTP/1.1
    

    因为get请求没有请求体,所有他的所有参数都是在url的后边添加。type=file的表单项只能获取到文件的名字,并不能获取文件的内容。

    post请求

    请求头:

    POST /www.baidu.com HTTP/1.1
    

    请求体:

    name=%22hello+world%22&file=temp.png&submit=submit
    

    总结

    • (1)我们可以发现不管是post请求和get请求,他们的参数存在的形式都是不变的,通过key=value的形式存在。
    • (2)表单项type=filed只能获取获取文件的名字不能获取文件的内容。

    3. 明确在enctype参数为multipart/form-data的时候post和get请求参数和请求体是什么形式的

    get请求
    请求头:

    GET/www.xxx.com?name=%22hello+world%22&file=temp.png&submit=submit HTTP/1.1
    

    get请求

    get请求和multipart/form-data结合无效,因为文件上传需要请求体。

    post请求:

    请求头:

    POST /www.xxx.com HTTP/1.1
    

    请求体:

    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
    Content-Disposition: form-data; name="name"
    
    "hello world"
    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
    Content-Disposition: form-data; name="file"; filename="temp.png"
    Content-Type: image/png
    
    .PNG
    .
    ...
    IHDR...
    ..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7.	pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`.
    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
    Content-Disposition: form-data; name="submit"
    
    submit
    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
    

    通过观察发现这个的请求体就发生了变化。这种请求体被称之为多部件请求体。
    什么是多部件请求体:就是把每一个表单项分割为一个部件。
    因为表单项分为普通表单项和文件表单项,所以说部件也有区别。

    • 普通表单项:
      一个请求头:Content-Disposition: form-data; name=”name”
      一个请求体:里面就是我们表单的值”hello world”

    • 文件表单项:
      两个请求头:

    Content-Disposition: form-data; name="file"; filename="temp.png"
    Content-Type: image/png
    

    一个请求体:

    .PNG
    .
    ...
    IHDR...
    ..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7.	pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`.
    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw
    Content-Disposition: form-data; name="submit"
    
    submit
    ------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
    

    总结:参数获取不到主要是因为在使用multipart/form-data属性之后请求体发生了变化。不是key=value的形式出现所以说获取不到。
    解决办法:
    (1)我们可以通过js代码来些修改,把我们的参数追加在url的后边。

    <form id="upload" name="upload" action="fileftp.jsp" method="post" ENCTYPE="multipart/form-data">
        <input type="hidden" name="otherName" id="otherName" value="abcdefg"/>  
        <td nowrap>
            <input type="file" id="file1" name="file1" value="" size="40" class="sbttn"/>
            <input type="submit" value="上传" class="sbttn"/>
        </td>   
    </form>
    
    <script language="javascript">      
    function formSubmit(){
        var action="fileftp.jsp";       
        action+="?otherName="+document.upload.otherName.value;
        document.upload.action=action;      
        document.upload.submit();
    }
    </script>
    

    (2)通过修改服务器端代码。前提是利用jar包。
    commons-fileupload-1.2.2.jar和commons-io-1.4.jar

    //创建工厂
    DiskFileItemFactory factoy=new DiskFileItemFactory();
    //创建解析器
    ServletFileUpload sfu=new ServletFileUpload(factoy);
    //解析request
    try {
        List<FileItem> list=sfu.parseRequest(request);
    
        for (FileItem fileItem : list) {
    
            fileItem.getFieldName();
            System.out.println(fileItem.getString());
        }
    
    } catch (FileUploadException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    package cn.zll.bookstore.adminbook.servlet;
    
    import java.awt.Image;
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.swing.ImageIcon;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadBase;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    import cn.zll.bookstore.adminbook.service.service;
    import cn.zll.bookstore.book.domain.Book;
    
    public class UploadServlet extends HttpServlet {
    
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            service s=new service();
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
    
            //文件上传的三部曲
            //创建工厂
            DiskFileItemFactory factoy=new DiskFileItemFactory();
            //创建解析器
            ServletFileUpload sfu=new ServletFileUpload(factoy);
            //设置上传文件的大小
            sfu.setFileSizeMax(20*1024);
            //解析request
            try {
                List<FileItem> list=sfu.parseRequest(request);
                Book b=new Book();
                b.setBid(UUID.randomUUID().toString().replace("-", ""));
                String bname=list.get(0).getString("utf-8");
                b.setBname(bname);
                System.out.println(bname);
                String price=list.get(2).getString("utf-8");
                b.setPrice(price);
                String author=list.get(3).getString("utf-8");
                b.setAuthor(author);
                String cid=list.get(4).getString("utf-8");
                b.setCid(cid);
                System.out.println(bname+price+author+cid);
    //          图书名称:<input style=" 150px; height: 20px;" type="text" name="bname"/><br/>
    //          图书图片:<input style=" 223px; height: 20px;" type="file" name="image"/><br/>
    //          图书单价:<input style=" 150px; height: 20px;" type="text" name="price"/><br/>
    //          图书作者:<input style=" 150px; height: 20px;" type="text" name="author"/><br/>
    //          图书分类:<select style=" 150px; height: 20px;" name="cid">
    //      
    //          
                //设置图片保存的目录
                String path=this.getServletContext().getRealPath("/book_img");
                //得到文件名称
                String fileName=UUID.randomUUID().toString().replace("-", "")+"_"+list.get(1).getName();
                //校验图片的格式
                if(!fileName.toLowerCase().endsWith("jpg")){
                    System.out.println("图片格式不是jpg");
                    request.setAttribute("msg", "你的图片格式不是jpg格式");
                    request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
                    return;
                }
                //使用目录和文件名称创建目标文件
                File f=new File(path,fileName);
                //保存文件
                list.get(1).write(f);
                //校验图片的尺寸
                Image image=new ImageIcon(f.getAbsolutePath()).getImage();
                if(image.getWidth(null)>200 || image.getHeight(null)>200){
                    f.delete();
                    request.setAttribute("msg", "图片的尺寸太大");
                    request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
    
                }
                //设置book的属性
                b.setImage("book_img/"+fileName);
                s.add(b);
                request.setAttribute("msg", "添加成功");
                request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
                System.out.println("fileName:"+fileName);
                System.out.println(path);
            } catch (FileUploadException e) {
                if(e instanceof FileUploadBase.FileSizeLimitExceededException){
    
                    System.out.println("你上传的文件大于15K");
                    request.setAttribute("msg", "你的图片大于15k");
                    request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
                    return;
                }
    
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
    
        }
    
    }
    
  • 相关阅读:
    FPN/lua-sdk-for-UPYUN
    结合keepalived实现nginx反向代理群集高可用
    Tengine + Lua + GraphicsMagick 实现图片自动裁剪/缩放
    cloudflare的新waf,用Lua实现的
    tengine+lua实现时时在线图片缩放,剪切。
    构建基于Nginx的文件服务器思路与实现
    Nginx+Lua+Redis整合实现高性能API接口
    使用nginx+lua实现自己的logserver | 星期八的博客 web & game
    让nginx支持文件上传的几种模式
    利用nginx+lua+memcache实现灰度发布
  • 原文地址:https://www.cnblogs.com/qiqi715/p/9369170.html
Copyright © 2011-2022 走看看