• Java基础——Servlet(八)文件上传下载


    一、简单的文件上传
    常见的组件Smartupload , Apache 的 commons FileUpload
    Smartupload上传的步骤:

    1.初始化上传上下文

    2.准备上传

    3.保存文件   

        <%
            if(request.getParameter("flag")!=null){
                   SmartUpload su=new SmartUpload();
                   su.initialize(pageContext);
                   su.upload();
                   su.save("/upload_files");
                   
                   out.print("上传成功");
               }
        %>
        <form action="file_up.jsp?flag=ok"  method="post" enctype="multipart/form-data" > //一定要用post
            <input type="file"  name="file1" />
            <input type="submit" value="上传">
        </form>

    注意:

    1) 表单的 enctype 属性 一定要是 multipart/form-data, method 一定要是post

    2) 要确保服务器上有 upload_files 这个文件夹 (当然,文件夹的名称是任意的)

    二、多文件上传

    <%
            if(request.getParameter("flag")!=null){
                   SmartUpload su=new SmartUpload();
                   su.initialize(pageContext);
                   su.upload();  //别忘了
                   su.save("/upload_files");
                    
                   SmartRequest req=su.getRequest(); //一定要这样取得 request 对象
                   
                   String name=req.getParameter("userName");
                   out.write(name); 
                   
                   SmartFiles files= su.getFiles();
                   int fileCount=files.getCount();
                   out.println("<h1>上传文件信息</h1>");
                   out.println("<hr>");
                   
                   for(int i=0;i<fileCount;i++){
                       SmartFile f = files.getFile(i);
                       out.println("表单项名称:"+f.getFieldName()+"<br>");
                       out.println("上传文件的名称"+f.getFileName()+"<br>");
                       out.println("文件的扩展名:"+f.getFileExt()+"<br>");
                       out.println("文件的大小:"+f.getSize()+"<hr>");
                   }
               }
         %>
       <form action="multi_file_up.jsp?flag=ok"  method="post"  enctype="multipart/form-data" >
            <input type="file"  name="file1" /> <br>
            <input type="file"  name="file2" /> <br>
            <input type="file"  name="file3" /> <br>
            <input type="file"  name="file4" /> <br>
    账号:    <input type="text" name="userName" />
    密码: <input type="text" name="password" />
            <input type="submit" value="上传">
        </form>

    三、使用 Servlet 上传文件

    SmartUpload smart=new SmartUpload();
            //它的参数:
            //Servlet servlet
            //ServletRequest request
            //ServletResponse response
            //String errpageUrl
            //boolean needSession
            //int buffer
            //boolean autoflush 
            PageContext pagecontext=JspFactory.getDefaultFactory().getPageContext(this, request, response, "", true, 8192, true); 
            smart.initialize(pagecontext);
            
            try {
                smart.upload();
                //smart.save("/upload_files");  //由于后面是一个个存的,这个save就可以不要了
                SmartFiles files=smart.getFiles();
                
                for(int i=0;i<files.getCount();i++){
                    SmartFile f=files.getFile(i);
                    String ip=request.getRemoteAddr();
                    String fileName=f.getFileName();  //文件名
                    //String fileExt =f.getFileExt();  //扩展名
                    
                    String fullName=ip+"-"+fileName;
                    
                    //request.getServletContext().getRealPath("/");
                    
                    f.saveAs("/upload_files"+java.io.File.separator+ fullName);
                }
                
                SmartRequest req=smart.getRequest();
                String userName=req.getParameter("userName");
                String password=req.getParameter("password");
                
                System.out.println(userName+":"+password);
                
            } catch (SmartUploadException e) {
                e.printStackTrace();
            }

    四、文件上传与数据库操作

    try {
                    SmartUpload smart = new SmartUpload();
                    PageContext pageContext = null;
                    pageContext = JspFactory.getDefaultFactory().getPageContext(this,
                            request, response, "", true, 8192, true);
                    smart.initialize(pageContext);
                    smart.upload();
                    SmartFile f=smart.getFiles().getFile(0);
        
                    // 1 取得上传的商品的信息
                    SmartRequest req = smart.getRequest(); 
                    String goodsName = req.getParameter("goodsName");
                    float price = Float.parseFloat(req.getParameter("price"));
                    String des = req.getParameter("des");
                    String picture=f.getFileName();  //注意图片管理方面的问题,比如覆盖,删除等
                    
                    GoodsInfo goods=new GoodsInfo();
                    goods.setGoodsName(goodsName);
                    goods.setPrice(price);
                    goods.setDes(des);
                    goods.setPicture(picture);
                    
                    _dao.addGoods(goods);
                    
                    // 2 上传图片
                    f.saveAs("/goods_pic"+java.io.File.separator+picture);
                    
                    request.setAttribute("goods", goods);
                    request.setAttribute("msg", "商品添加成功");
                    request.getRequestDispatcher("/goods/goods_add.jsp").forward(request, response);
                }
        
                catch (Exception ex) {
                    ex.printStackTrace();
                }
    <form action="GoodsServlet" method="post" enctype="multipart/form-data">
             名称:<input type="text" name="goodsName" value="${goods.goodsName }" />  <br>
             价格:<input type="text" name="price" /> <br>
             描述:<input type="text" name="des" /> <br>
             图片:<input type="file" name="picture" /> <br>
             <input type="submit" value="提交" />
             <img src="${pageContext.request.contextPath }/goods_pic/${goods.picture }" >
             ${msg }
           </form>

    五、文件的下载

    //Servlet中 
                 SmartUpload smart=new SmartUpload();
                    PageContext pageContext=JspFactory.getDefaultFactory().getPageContext(this, request, response, "", true, 8192, true);
                    smart.initialize(pageContext);
                    smart.setContentDisposition(null); // 用来指定下载数据的mine类型,传null 组件会自动的添加默认类型
            
                    try {
                        smart.downloadFile("/goods_pic/lengtu.jpg");
                    } catch (SmartUploadException e) {
                        e.printStackTrace();
                    }
    //jsp中 
    <a href="FileDownloadServlet" >下载</a>

    六、附:文件上传请求消息的结构

    //在jsp中的配置
       <form action="FilieUpServlet" method="post" enctype="multipart/form-data"> 
           <input type="text" name="userName" />
           <input type="text" name="password" />
           <input type="file" name="photo" />
           <input type="submit" value="提交 "/>
       </form>
       
    //在Servlet中
        public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
                    
            ServletInputStream inputStream=request.getInputStream();
            String filePath=getServletContext().getRealPath("/upload-files")+"/XXX.bmp";  //随给被上传的文件起个名字
            FileOutputStream outStream=new FileOutputStream(filePath);
                
            byte[] buff=new byte[1024];
            int len=0;
            while((len=inputStream.read(buff,0,buff.length))!=-1){
                outStream.write(buff,0,len);    
            }
                inputStream.close();
                outStream.close();
                System.out.println("成功");
        }

    说明 :上例中,form 的enctype 是默认的,在存文件的时候,也没有使用它传上的来的名称(传上来的名称是C:/pictture/....这样的)

    操作以后,可以在upload-files 下 发现有 XXX.bmp 文件,用记事本打开,发现内容如下

    userName=zhangsan&password=123&photo=C%3A%5Cpicture%5Cxiaoxin.bmp

    上面的代码,由于没有获取实体的长度,只好先定义一个勺用来循环读取,可以看出:对于 application/x-wwww-form-urlencoded 编码的 form表单,所有字段URL参数的形式组合成了一行,并对其中的参数值都进行了URL编码,要想从上面的数据流中提取出各个字段的值,必须对读取到的内容进行拆分,然后再进行url解码,request.getParameter() 等方法可以直接读取上面的字段元素信息,所以Servlet程序中一般不用getInputStream或getReader方式来读取application/x-www-form-urlencoded 编码的表单字段信息。 如果要上传文件,form 元素的enctype 必须设置为 multipart/form-data,并且method必须为POST。

    注意:request.getContentLength() 可以得到上传内容的长度,但要注意:并不能保证一次read方法的调用,就能读取到输入流中的所有内容,因为read方法在读取到指定个字节后或读取完网卡缓冲区中的内容后就返回,但网络传输的速度通常比cpu读网卡的速度慢,所以read方法可能只读到部分数据就返回了。实验表明,就算只上传一个图片文件,上传以后,这个图片文件也是不能用的.因为它里面还是有类似----7df1244802dc之类的内容,和普通图片的格式不对。

    七、如何把图象存在数据库

    1) 在GoodsInfo 这个实体类中加一个字段  private byte []  photo; //代表照片

    2) 数据库中加一个 blob类型的字段 名字叫 photo,用来装载图片数据

    3) Servlet中

    public void doPost(HttpServletRequest request, HttpServletResponse response)
                                        throws ServletException, IOException {
                            
                                    try{
                                        SmartUpload smart = new SmartUpload();
                                        PageContext pageContext = null;
                                        pageContext = JspFactory.getDefaultFactory().getPageContext(this,    request, response, "", true, 8192, true);
            
                                        smart.initialize(pageContext);
                                        smart.upload();
                                        SmartFile f = smart.getFiles().getFile(0);
                                        
                                        //取得上传的商品的信息
                                        SmartRequest req = smart.getRequest();
                                        String goodsName = req.getParameter("goodsName");
                                        float price = Float.parseFloat(req.getParameter("price"));
                                        String des = req.getParameter("des");
                                        String picture = f.getFileName(); 
                            
                                        GoodsInfo goods = new GoodsInfo();
                                        goods.setGoodsName(goodsName);
                                        goods.setPrice(price);
                                        goods.setDes(des);
                                        goods.setPicture(picture);
                                        
                                        byte [] buff=new byte[f.getSize()];  //这里是关键
                                            
                                        //将文件,转成字节数组,这里是关键
                                        for(int i=0;i<f.getSize();i++){
                                            buff[i]=f.getBinaryData(i);
                                        }
                            
                                        goods.setPhoto(buff);  //关键
                                          
                                        _dao.addGoods(goods);
                                    
                                    }
                                    catch(Exception ex){
                                        ex.printStackTrace();
                                    }
                                    
                                }

    4) test_photo.jsp 中 : 

    <img src="${pageContext.request.contextPath }/goods/photo.jsp" />

    5) photo.jsp 中:

    <%
                                GoodsInfo goods=new GoodsDao().getGoodsById(8);
                                
                                response.setContentType("image/jpg");
                                
                                ByteArrayOutputStream imageStream=new ByteArrayOutputStream();
                                imageStream.write(goods.getPhoto());
                                
                                ServletOutputStream streamOut=response.getOutputStream();
                                
                                imageStream.writeTo(streamOut); 
                                imageStream.close();
                         
                                 out.clear();
                                out=pageContext.pushBody();
                                
                            /*由于jsp container在处理完成请求后会调用releasePageContet方法释放所用的PageContext object,
                                并且同时调用getWriter方法,由于getWriter方法与在jsp页面中使用流相关的getOutputStream方法冲突,
                                所以会造成这种异常,解决办法是:只需要在jsp页面的最后加上两条语句:  
                                out.clear();out=pageContext.pushBody();即可(其中out,pageContext均为jsp内置对象! */
                        %>

    八、不用插件的文件下载

    //例一,最简单的
                == Servlet1 ==
                    response.setContentType("application/x-msdownload");
                    response.setHeader("Content-Disposition" , "attachment;filename=xxx");
                    
                    ServletOutputStream stream= response.getOutputStream();
                    stream.write("ha ha ha this is file".getBytes());
                    stream.close();
    //例二 下载一幅服务器上的图象
              == Servlet12 ==
                response.setContentType("application/x-msdownload");
                    response.setHeader("Content-Disposition" , "attachment;filename=xxx");
                    
                    String filePath=this.getServletContext().getRealPath("/")+"/goods_pic/"+"lengtu.jpg"; 
                    FileInputStream fis=new FileInputStream(filePath);
                    
                    ServletOutputStream outStream= response.getOutputStream();
                    
                    byte[] buff=new byte[1024];
                    int len=0;
                    while((len=fis.read(buff))!=-1){
                        outStream.write(buff,0,len);
                    }
                    
                    fis.close();
                    outStream.close();

    附:上传图片时的预览功能

    function setImagePreview(docObj, localImagId, imgObjPreview, width, height) {
            if (docObj.files && docObj.files[0]) { //火狐下,直接设img属性        
                imgObjPreview.style.display = 'block';
                imgObjPreview.style.width = width;
                imgObjPreview.style.height = height;
                //火狐7以上版本不能用上面的getAsDataURL()方式获取,需要一下方式        
                imgObjPreview.src = window.URL.createObjectURL(docObj.files[0]);
            } else { //IE下,使用滤镜      
                docObj.select();
                var imgSrc = document.selection.createRange().text;
                //必须设置初始大小        
                localImagId.style.width = width;
                localImagId.style.height = height;
                //图片异常的捕捉,防止用户修改后缀来伪造图片        
                try {
                    localImagId.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
                    localImagId.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
                } catch (e) {
                    alert("您上传的图片格式不正确,请重新选择!");
                    return false;
                }
                imgObjPreview.style.display = 'none';
                document.selection.empty();
            }
        }
        
            <form action="GoodsPhotoServlet" method="post" enctype="multipart/form-data">
              名称:<input type="text" name="goodsName" value="${goods.goodsName }" />
              价格:<input type="text" name="price" /> 
              描述:<inputtype="text" name="des" /> <br> 
              图片:<input type="file"name="picture" onchange="setImagePreview(this,localImag,preview,'100px','125px');" /> 
                <input type="submit" value="提交" /> 
                    
                    <div id="localImag" style="margin-left: 24px" ></div>
                    <img id="preview" alt="请上传照片" style="122px; height: 145px;" />
            </form>
  • 相关阅读:
    POJ 2987:Firing(最大权闭合图)
    BZOJ 1001:[BeiJing2006]狼抓兔子(最小割)
    HDU 1007:Quoit Design(分治求最近点对)
    POJ 1986:Distance Queries(倍增求LCA)
    HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)
    BZOJ-1011 遥远的行星
    BZOJ-1044 木棍分割
    BZOJ-1042 硬币购物
    BZOJ-1050 旅行
    BZOJ-1037 生日聚会
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/7492446.html
Copyright © 2020-2023  润新知