使用Servlet3.0实现文件上传 必须满足2个条件: 1. 添加@MultipartConfig注解。 注解的属性: 属性名 类型 是否可选 描述 fileSizeThreshold int 是 当数据量大于该值时,内容将被写入文件 location String 是 存放临时生成的文件地址 maxFileSize long 是 允许上传的文件最大值。默认值-1,表示没有限制 maxRequestSize long 是 针对该multipart/form-data请求的最大数量,默认值-1,表示没有限制 2. 使用2个重要方法 Part getPart(String name):name请求的文件名。 Collection<Part> getParts():获取请求文件中的所有文件。 实例 上传jsp页面 <form action="FirstServlet" enctype="multipart/form-data" method="post"> <ul> <li> <input type="file" name="file1" id="file1"> </li> <li><input type="submit" value="提交"/></li> </ul> </form> FirstSservlet代码 注意:使用Servlet3.0在开发时上传location属性指定的临时文件路径会报路径无效的异常(the temporary upload (路径地址) is not valid),只要在指定路径里添加缺少的文件夹就可以。 @WebServlet("/FirstServlet") @MultipartConfig(location="temp") public class FirstServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public FirstServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //设置响应page指令的contentType属性值 response.setContentType("text/html;charset=UTF-8"); //获得PrintWriter对象 PrintWriter pw=response.getWriter(); //获取服务器的地址 String path=this.getServletContext().getRealPath("/"); //获得用户上传的文件 Part p=request.getPart("file1"); //处理上传的为图像文件 if(p.getContentType().contains("image")){ //创建ApplicationPart对象 ApplicationPart ap=(ApplicationPart)p; //获得文件名字 String fname1=ap.getSubmittedFileName(); //对上传文件名进行截取 int path_idx=fname1.lastIndexOf("\")+1; //获取文名 String fname2=fname1.substring(path_idx, fname1.length()); p.write(path+"/upload/"+fname2); pw.write("文件上传成功"); }else{ pw.write("文件上传失败"); } RequestDispatcher dispatcher=request.getRequestDispatcher("Deal.jsp"); //执行转发 dispatcher.forward(request, response); doGet(request, response); } } 使用Commons-FileUpload组件实现文件上传 1. 创建上传对象 创建一个工厂对象 DiskFileItemFactory factory=new DiskFileItemFactory (); 创建一个新的文件上传对象 ServletFileUpload upload=new ServletFileUpload(factory); 2. 解析上传请求 通过parseRequest()方法获取全部表单项。 Public List parseRequest(HttpServletRequest request) throws FileUploadException 通过isFormField()方法判断表单项是文件域还是普通表单域。如果返回true说明是普通表单域。 Public Boolean isFormField() 通过FileItem类的getName()方法实现获取文件上传名称。 getSize()方法获得文件上传的大小。 getContentType()方法获得上传文件的类型。 上传文件实例 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String ctname; //获得文件上传的真实地址 String fileDir=request.getRealPath("upload/"); String mesg="文件上传成功"; String address=""; //判断是否上传文件 if(ServletFileUpload.isMultipartContent(request)){ //创建一个工厂对象 DiskFileItemFactory factory=new DiskFileItemFactory(); //设置内存中允许存储的字节 factory.setSizeThreshold(20*1024); //设置存放临时文件的路径 factory.setRepository(factory.getRepository()); //创建一个上传文件的对象 ServletFileUpload upload=new ServletFileUpload(factory); //设置上传文件大小 int size=4*1024*1024; //保存上传文件的集合对象 List list=null; try { //获得上传文件列表 list=upload.parseRequest(request); } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } //创建迭代器 Iterator iter=list.iterator(); //循环迭代 while(iter.hasNext()){ //创建FileItem对象,获得每一个上传文件 FileItem flie=(FileItem)iter.next(); //判断是文件域或普通表单域 if(!flie.isFormField()){ //获得文件名称 String name=flie.getName(); //判断文件大小是否超过设定文件大小 if(flie.getSize()>size){ mesg="文件过大,无法上传"; } //获取上传文件大小 String ctsize=new Long(flie.getSize()).toString(); //判断文件是否存在 if((name==null || name.equals("")) && ctsize.equals("0")){ mesg="文件为空。"; continue;//文件为空跳出本次循环 } //创建上传文件的名称 ctname=name.substring(name.lastIndexOf("\")+1,name.length()); address=fileDir+"\"+ctname; //创建File对象,根据文件地址创建一个空文件 File file=new File(address); try { //向创建的文件中写入数据 flie.write(file); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } request.setAttribute("msg", mesg); RequestDispatcher dispatcher=request.getRequestDispatcher("Deal.jsp"); //执行转发 dispatcher.forward(request, response); doGet(request, response); } 使用Commons-FileUpload组件实现文件下载 1. 使用文件File类获取需要下载的文件 File(String path) File file=new File(“D:\11\text.txt”); File file=new File(“D:\11”,”text.txt”) 2. 创建字节输入流 FileInputStream in=new FileInputStream(File file); 3. 创建字节输出流 OutputStream os=request.getOutputStream(); 实例 如果使用表单的话可以指定调用:doPost()或doGet()方法。 但如果使用a标签,a标签是默认调用doGet()方法。所以使用a标签调用Servlet时必须砸doGet()方法中写后天逻辑。 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //获得path的参数值 String path="D:\Users\Administrator\workspace\HelloWorld\upload\IMG_20161014_095008.jpg"; //request.getParameter("path"); //将Path的字符集修改为UTF-8 path=new String(path.getBytes("ISO-8859-1"),"UTF-8"); //创建File对象 File file=new File(path); //创建文件字节输入流 FileInputStream in=new FileInputStream(file); //创建文件字节输出流,通过response获取OutputStream对象 OutputStream os=response.getOutputStream(); //设置应答头文件Content-Disposition属性,值为ttachment;filename=文件路径名 response.setHeader("Content-Disposition", "attachment;filename=" +new String(file.getName().getBytes("GBK"),"ISO-8859-1")); //设置应答头文件信息文件大小 response.setHeader("Content-Length", file.length()+""); //设置应答文件的编码 response.setCharacterEncoding("UTF-8"); //设置文件为文件输出流 response.setContentType("application/octet-stream"); //声明数据变量 int data=0; while((data=in.read())!=-1){ //向指定目录中输出文件 os.write(data); } //关闭文件输入流和文件输出流 in.close(); os.close(); RequestDispatcher dispatcher=request.getRequestDispatcher("login.jsp"); //执行转发 dispatcher.forward(request, response); doGet(request, response); }