Web项目中文件上传Filter处理
最近遇到一个文件上传的项目,而且在这个项目中遇到的文件上传的次数还是挺多的,所以就写了个Filter过滤器。这一个想法还是从一本书上看到的,所以原则上说并不是在下原创。不过因为补充了一点东西,所以,嘿嘿,不说了。
首先需要写个Filter:
packageyin.filter;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.OutputStream;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.annotation.MultipartConfig;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletRequestWrapper;importorg.apache.commons.fileupload.DiskFileUpload;importorg.apache.commons.fileupload.FileItem;publicclassUploadfilterimplementsFilter{privateStringencoding;@Overridepublicvoiddestroy(){}@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{UploadRequestWrapperuploadRequestWrapper=newUploadRequestWrapper((HttpServletRequest)request);chain.doFilter(uploadRequestWrapper,response);}@Overridepublicvoidinit(FilterConfigconfig)throwsServletException{encoding=config.getServletContext().getInitParameter("encoding");if(encoding==null){encoding="utf-8";}}classUploadRequestWrapperextendsHttpServletRequestWrapper{//文件头类型privatestaticfinalStringMULTIPART_HEADER="Content-type";//是否是上传文件privatebooleanmultipart;//保存提交的数据privateMap<String,Object>params=newHashMap<String,Object>();@SuppressWarnings("deprecation")publicUploadRequestWrapper(HttpServletRequestrequest){super(request);//判断是否是上传文件multipart=request.getHeader(MULTIPART_HEADER)!=null&&request.getHeader(MULTIPART_HEADER).startsWith("multipart/form-data");//如果是上传文件if(multipart){try{DiskFileUploadupload=newDiskFileUpload();//使用apache进行上传//设置编码upload.setHeaderEncoding(encoding);//解析上传的数据List<FileItem>fileItems=upload.parseRequest(request);//遍历for(Iterator<FileItem>it=fileItems.iterator();it.hasNext();){//获取当前的FileItemFileItemitem=(FileItem)it.next();//如果是文本域if(item.isFormField()){params.put(item.getFieldName(),item.getString(encoding));}else{//替换特殊字符Stringfilename=item.getName().replace("\\","/");filename=filename.substring(filename.lastIndexOf("/")+1);//保存到系统临时文件夹中java.io.Filefile=newFile(System.getProperty("java.io.tmpdir"),filename);//新建文件输出流OutputStreamops=newFileOutputStream(file);//输出到文件流中ops.write(item.get());//关闭文件流ops.close();//将值放到Map中params.put(item.getFieldName(),file);}}}catch(Exceptione){e.printStackTrace();}}}@OverridepublicObjectgetAttribute(Stringname){//如果是上传文件,则从Map中取值,支持直接获取文件对象if(multipart&¶ms.containsKey(name)){returnparams.get(name);}returnsuper.getAttribute(name);}@OverridepublicStringgetParameter(Stringname){//如果是上传文件,则从Map中取值,if(multipart&¶ms.containsKey(name)){returnparams.get(name).toString();}returnsuper.getParameter(name);}}}
好了,Filter写完了,那么就修改配置文件web.xml吧,如下:
<filter><filter-name>Uploadfilter</filter-name><filter-class>yin.filter.Uploadfilter</filter-class></filter><filter-mapping><filter-name>Uploadfilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
以上只是文件上传的Filter,那么该怎样使用了。放心,在下会说滴:
我们现在先写一个简单的上传的jsp文件,
<body><!--包含上传文件的表单--><formaction="upload"method="post"enctype="multipart/form-data">用户名:<inputtype="text"value=""name="uname"><br>密 码:<inputtype="password"value=""name="psw"><br>头 像:<inputtype="file"name="file"><br><inputtype="submit"value="注册"></form></body>
由于样式什么的没有调整,难看点也是无所谓的吧!
然后在servlet中使用:
protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");//读取表单内容Stringname=request.getParameter("uname");Stringpsw=request.getParameter("psw");FileheadPic=(File)request.getAttribute("file");FileWriterWrapperwrite=newFileWriterWrapper(request,headPic);}
大家有没有发现,这样选取表单中的内容是比较方便的,那么然后
FileWriterWrapperwrite=newFileWriterWrapper(request,headPic);
这一行代码就是将读取到的文件写入到硬盘中了,
packageyin.usual;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjavax.servlet.ServletContext;importjavax.servlet.http.HttpServletRequest;publicclassFileWriterWrapper{publicFileWriterWrapper(){//TODOAuto-generatedconstructorstub}//文件写入的方法publicFileWriterWrapper(HttpServletRequestrequest,Filefile){try{//读取上下文配置,获取路径ServletContextcontext=request.getServletContext();Stringfilename=context.getInitParameter("filename");//获取文件保存路径filename=context.getRealPath(filename);//如果路径不存在,则创建if(!newFile(filename).isDirectory()){System.out.println("文件不存在,正在创建。。。");newFile(filename).mkdirs();}//获取文件名Stringpicname=file.getName().replace("/","\\");picname=picname.substring(picname.lastIndexOf("\\")+1,picname.length());//获取文件保存位置Stringpath=filename+"\\"+picname;System.out.println("文件保存在:"+path);FileInputStreamfis=newFileInputStream(file);FileOutputStreamfos=newFileOutputStream(path);byte[]bs=newbyte[1024*1024*4];intlen=0;while((len=fis.read(bs))!=-1){fos.write(bs,0,len);}//关闭文件fis.close();fos.close();System.out.println("文件写入成功");}catch(IOExceptione){System.out.println("文件写入失败");e.printStackTrace();}}}
接下来,大家看看配置:
<context-param><param-name>filename</param-name><param-value>/imgs</param-value></context-param>
看到这,不知道大家有没有一个疑问,如果表单中的上传文件有多个,那么怎么办?如果这样就需要修改
FileWriterWrapper
类了,可以将获取上下文配置中的路径放在Servlet中,这样就可以了,具体操作在下就不书写了。。
以上内容如有错误,欢迎指出。。。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。