上传二个file项
index.jsp:
<!-- 下面那个=号,代表整个输出request.getContextPath()的值 --> <form action="<%= request.getContextPath() %>/upload" method="post" enctype="multipart/form-data"> 文件1:<input type="file" name="file"/><br/> 文件1的说明:<input type="text" name="desc1"/><br/> 文件2:<input type="file" name="file2"/><br/> 文件2的说明:<input type="text" name="desc2"/><br/> <input type="submit" value="提交"/> </form>
其他的相对前面的都没改动~
演示结果:
上传文件最终版:
index.jsp:
<h2>进一步演示文件上传用法</h2> <form action="<%= request.getContextPath() %>/upload2" method="post" enctype="multipart/form-data"> 文件1:<input type="file" name="file"/><br/> 文件1的说明:<input type="text" name="desc1"/><br/> 文件2:<input type="file" name="file2"/><br/> 文件2的说明:<input type="text" name="desc2"/><br/> <input type="submit" value="提交"/> </form>
web.xml:
<servlet> <servlet-name>UploadServlet2</servlet-name> <servlet-class>cn.hncu.servlets.upload.UploadServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet2</servlet-name> <url-pattern>/upload2</url-pattern> </servlet-mapping>
UploadServlet2.java:
package cn.hncu.servlets.upload; import java.io.File; import java.io.IOException; import java.io.PrintWriter; 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 org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet2 extends HttpServlet { //防黑1---在地址栏直接提交的-我们要防住 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().print("不支持GET方式上传!!!"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); final PrintWriter out = response.getWriter();//等会内部类需要用到这个变量,所以定义成final //防黑2--非multipart表单提交 //手动方式 String type = request.getContentType(); if(!type.contains("multipart/form-data")){//如果此字符串包含 s,则返回 true,否则返回 false out.print("不支持普通表单提交"); return; } DiskFileItemFactory fiFactory = new DiskFileItemFactory(); fiFactory.setSizeThreshold(1024*8);//8k,缓存区大小 File file = new File("d:/a"); if(!file.exists()){ file.mkdir(); } fiFactory.setRepository(file);//设置缓存区 /* ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。 使用其 parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。 */ ServletFileUpload upload = new ServletFileUpload(fiFactory); upload.setHeaderEncoding("utf-8");//用于设置文件名的编码,相当于:request.setCharacterEncoding("utf-8"); String path = getServletContext().getRealPath("/imgs"); //文件上传进度功能---设置监听器 upload.setProgressListener(new ProgressListener() { private int pre=0; //参数解析---pBytesRead:已上传字节数 pContentLength:上传的总字节数 pItems:文件序号(从1开始的) @Override public void update(long pBytesRead, long pContentLength, int pItems) { double d = pBytesRead*100.0/pContentLength;//计算百分比 int dd = (int)d; if(pre!=dd){//防范输出一样的百分比 out.print(dd+"%<br/>"); pre=dd; } } }); FileItem fi=null; try { List<FileItem> list = upload.parseRequest(request); for(FileItem fi2:list){ fi=fi2;//相当于传指针,同一个对象 if(fi.isFormField()){//普通表单组件 String str = fi.getString("utf-8"); System.out.println("普通表单组件提交的内容:"+str); }else{//表单中的:file组件 //防黑3--在file组件中不选择文件 if(fi.getSize()==0){ continue; } //文件名 String fileName = fi.getName(); fileName = fileName.substring( fileName.lastIndexOf("\\")+1 );//这里就是文件名(后缀名也在的) String ext = fileName.substring( fileName.lastIndexOf(".") );// .* 后缀名 //文件名不能用中文,必须转换成ascii码的格式,而且文件名不能重复(必须保证唯一),因此采用UUID来实现 String newFileName = UUID.randomUUID().toString().replace("-", "");//去掉'-' newFileName = newFileName+ext; //打散目录(因为对于普通的机器,一个文件夹如果存储的文件个数超过1000个,性能就会急剧下降!!!)、 String dir1 = Integer.toHexString( fileName.hashCode() & 0xf ); String dir2 = Integer.toHexString( (fileName.hashCode() & 0xf0)>>4 );//右移四位 String dir3 = Integer.toHexString( ( fileName.hashCode() & 0xf00 )>>8); File dir = new File(path+"/"+dir1+"/"+dir2+"/"+dir3);//16*16*16个文件夹 if(!dir.exists()){ dir.mkdirs(); } File f = new File(dir+"/"+newFileName); fi.write(f); } } }catch (FileUploadException e) { throw new RuntimeException(e); } catch (Exception e) { throw new RuntimeException(e); } finally{ if(fi!=null){ fi.delete();//清临时文件 } } } }
演示结果:
进行了一个文字型的文件上传进度,没办法啊,现在还没学AJax,做不了同步~~理解理解,后面会学到的。
注意看文件的保存目录!!!!(0-f)16进制的文件名~
我做了三层~