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

来源:互联网 发布:照片电子相册制作软件 编辑:程序博客网 时间:2024/05/18 14:11

一、简单的文件上传
常见的组件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  style="margin-left: 24px" ></div>                <img  alt="请上传照片" style="width:122px; height: 145px;" />        </form>