在许多Web站点应用中都需要为用户提供通过浏览器上传文档资料的功能,例如,上传个人相片、共享资料等。在DRP中,就有这个一个功能,需要将对应的物料图片上传并显示。
对于上传功能,其实在浏览器端提供了很好的支持,只需在Web服务器端获取浏览器上传文件并保存。为了简化和帮助Web开发人员接收浏览器上传的文件,一些公司和组织专门开发了文件上传组件,比如说commons-fileupload,现在就看看这个功能是怎么实现的。
需求:对应的物料图片上传并显示
引入jar包:
首先要引入两个jar包,一个是commons-fileupload.jar包,另一个是commons-io-2.2.jar包。
浏览器端如何支持:
采用post提交;
更改form的enctype属性为:enctype="multipart/form-data",即:
<form name="itemForm" target="_self" id="itemForm" method="post" action="servlet/item/FileUploadServlet" enctype="multipart/form-data"> <span style="white-space:pre"> </span><input name="btn_upload" class="button1" type="submit" id="btn_upload" value="上传"><span style="white-space:pre"> </span> </form>关于将上传的图片保存在什么地方的问题,我觉得这两种方法挺好:
第一种:图片保存到本地磁盘。图片的名称对应物料编号。
第二种:图片保存到本地磁盘,同时在数据库中保存此图片名。
两种方法大同小异,详细介绍第二种方法。
实例:
图片保存到本地磁盘,同时在数据库中保存此图片名。
item_upload.jsp中
<% <span style="white-space:pre"> </span>Item item=(Item)request.getAttribute("item"); //获取request中的值 %>
<form name="itemForm" target="_self" id="itemForm" method="post" action="servlet/item/FileUploadServlet" enctype="multipart/form-data"> <input type="hidden" id="itemNo" name="itemNo" value=<%=item.getItemNo() %>> <div align="center"> <table width="95%" border="0" cellspacing="2" cellpadding="2"> <tr> <td> </td> </tr> </table> <table width="95%" border="0" cellspacing="0" cellpadding="0" height="8"> <tr> <td width="522" class="p1" height="2" nowrap> <img src="images/mark_arrow_03.gif" width="14" height="14"> <b>基础数据管理>>物料维护>>上传物料图片</b> </td> </tr> </table> <hr width="97%" align="center" size=0> <table width="95%" border="0" cellpadding="0" cellspacing="0"> <tr> <td height="29"> <div align="right"> 物料代码: </div> </td> <td> <%=item.getItemNo() %> </td> </tr> <tr> <td height="74"> <div align="right"> 图片: </div> </td> <span style="white-space:pre"> </span><td> <img src="Upload/<%=item.getFileName() %>" width="85" height="49"> </td> </tr> <tr> <td width="22%" height="29"> <div align="right"> <font color="#FF0000">*</font>选择图片: </div> </td> <td width="78%"> <input name="fileName" type="file" class="text1" size="40" maxlength="40"> </td> </tr> </table> <hr width="97%" align="center" size=0> <div align="center"> <input name="btn_upload" class="button1" type="submit" id="btn_upload" value="上传"> <input name="btnBack" class="button1" type="button" id="btnBack" value="返回" onClick="history.go(-1)"> </div> </div> </form>在Servlet中完成文件上传及将图片写到相应目录并在数据库中保存此图片名称:
public class FileUploadServlet extends HttpServlet { File uploadPath=null; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取物料信息 ItemManager itemManager=new ItemManagerImpl(); String itemNo=request.getParameter("itemNo"); Item item=itemManager.findItemById(itemNo);//查询该物料所有信息 request.setAttribute("item",item); request.getRequestDispatcher("/basedata/item_upload.jsp").forward(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //String uploadPath="C:\\Users\\ZhuDan\\Desktop\\Drp\\DRP系统\\apache-tomcat-7.0.6\\webapps\\drp3.9\\Upload"; boolean isMultipart = ServletFileUpload.isMultipartContent(request); ItemManager itemManager=new ItemManagerImpl(); String itemNo=""; String fileName=""; if(isMultipart==true){ try{ FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request);//得到所有的文件 Iterator<FileItem> itr = items.iterator(); while(itr.hasNext()){//依次处理每个文件 FileItem item=(FileItem)itr.next();//获取每个文件的所有信息 //是普通的表单类型 if(item.isFormField()){ if("itemNo".equals(item.getFieldName())){ itemNo=item.getString(); } } fileName=item.getName();//获得文件名,包括路径 D:\生活\照片\Friends\蹄蹄\高饶珊.jpg if(fileName!=null){ File fullFile=new File(item.getName()); //要存入文件夹的路径 File savedFile=new File(uploadPath,fullFile.getName()); //截取字符串 如:C:\WINDOWS\Debug\PASSWD.LOG fileName = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length()); if(itemNo!=null && fileName!=null){ itemManager.uploadItemImage(itemNo, fileName); } //存入文件夹 item.write(savedFile); // File fullFile=new File(itemNo); // File savedFile=new File(uploadPath,fullFile.getName()+".jpg"); } } // System.out.print("upload succeed"); } catch(Exception e){ e.printStackTrace(); } finally{ response.sendRedirect("QueryServlet"); } } } public void init() throws ServletException{ uploadPath=new File(getServletContext().getRealPath("Upload"));//获取用于保存图片的Upload文件夹的路径 if(!uploadPath.exists()){ //如果不存在Upload文件夹,则创建 uploadPath.mkdir(); } } }界面效果如下:
数据库中字段:
对应的本地文件夹(tomcat)中:
总结:
原理如下: FileUpload组件将页面提交的所有元素(普通form表单域,如input和文件域file)都看作一样的FileItem,这样上传页面提交的 request请求也就是一个FileItem的有序组合,FileUpload组件可以解析该request,并返回一个一个的FileItem。而对 每一个FileItem,FileUpload组件可以判断出它是普通form表单域还是文件file域,从而根据不同的类型,采取不同的操作--如果是表单域,就读出其值,如果是文件域,就保存文件到服务器硬盘上或者内存中。