• 文件上传和下载


     1. 文件上传

    浏览器在上传的过程中是将文件以 二进制的流  的形式提交到服务器端.

    1 准备一个form表单,里面有一个上传,form表单的类型必需是multipart/form-data

    2 准备一个上传的Servlet,到后台接收传过来的普通表单数据 与 文件(二进制)

    3 导入相应的FileUpload jar(commons-fileupload-1.2.2.jar ,commons-io-1.4.jar)

    重要:上传时,我们表单的请求类型必需设置成multipart/form-data   . 上传的method必需是POST

    完成文件上传重要方法:fileItem.write(File file);

    FileItemd对象就是从request中获得数据对象,通过调用它的write把其中的数据写入到磁盘文件(File file

    常见问题及其解决方案:

      1. 上传文件对象封装----CFile对象 ,可以解决 多个文件上传 及其对应属性的属性很多问题。

      2. FileUtil.java 工具类   虽然可以完成上传   但是 拿不到普通表单字段值文件上传后,我们拿到不到上传的文件的数据。

        解决办法:准备两个容器(就是集合),然后一个容器装普通表单,另一个容器装上传的文件数据。把这个容器交给工具类,工具类拿到相应的数据后将数据放回到容器中。

    1. 项目整体架构:

    2. register.jsp代码

    <body>
    	<form action="UploadServlet" method="post" enctype="multipart/form-data">
    		用户名:<input type="text" name="username"/><br>
    		密码:<input type="password" name="password"/><br>
    		头像1:<input type="file" name="headImg1"/><br>
    		头像2:<input type="file" name="headImg2"/><br>
    		<input type="submit" value="提交"/>
    	</form>
    </body>
    

      

    3. UploadServlet.java代码

    package com.gs.controller;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    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.FileItemFactory;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.FilenameUtils;
    
    import com.gs.domain.CFile;
    import com.gs.tools.FileUtil;
    
    @WebServlet("/UploadServlet")
    public class UploadServlet extends HttpServlet {                 
    	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		try {
    			Map<String, String> fieldMap = new HashMap();
    			Map<String,CFile> filesMap = new HashMap();
    			FileUtil.upload(request, fieldMap, filesMap);
    			//拿数据
    			System.out.println(fieldMap);
    			System.out.println(filesMap);
    		} catch (Exception e) {
    			request.setAttribute("message","类型不匹配");
    			request.getRequestDispatcher("register.jsp").forward(request, response);
    		}
    	}
    }
    

      

    4. CFile.java代码

    package com.gs.domain;
    
    public class CFile {
    	private String filename;
    	private String filepath;
    	public String getFilename() {
    		return filename;
    	}
    	public void setFilename(String filename) {
    		this.filename = filename;
    	}
    	public String getFilepath() {
    		return filepath;
    	}
    	public void setFilepath(String filepath) {
    		this.filepath = filepath;
    	}
    	@Override
    	public String toString() {
    		return "CFile [filename=" + filename + ", filepath=" + filepath + "]";
    	}
    }
    

      

    5. FileUtil.java 工具类代码

    package com.gs.tools;
    
    import java.io.File;
    import java.net.URLDecoder;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.FilenameUtils;
    
    import com.gs.domain.CFile;
    
    public class FileUtil {
    	//准备只支持的图片类型
    	private static final String[] IMG_TYPE = {"jpg","png","gif","bmp"};
    	public static void upload(HttpServletRequest request, Map<String,String> fieldMap,
    			Map<String,CFile> filesMap) {
    		//判断是否有一个文件上传的请求
    		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    		if(isMultipart){
    			//为基于磁盘的文件项创建工厂,并创建一个新的文件上传对象
    			DiskFileItemFactory  factory = new DiskFileItemFactory();
    			ServletFileUpload upload = new ServletFileUpload(factory);
    			upload.setFileSizeMax(1024*1024*2);//单个文件最大2M
    			upload.setSizeMax(1024*1024*5); //所有文件的请求的大小 5M
    			
    			try {
    				//拿到每一项表单控件组成的 FileItem类型的集合
    				List<FileItem> items = upload.parseRequest(request);
    				for (FileItem fileItem : items) {
    					System.out.println(fileItem);
    					//如果是一般表单,用一般表单的处理方式
    					if(fileItem.isFormField()) {
    						//表单控件name的名称
    						String filedName = fileItem.getFieldName();
    						//表单控件name名称对应的值
    						String value = fileItem.getString("UTF-8");
    						//value = new String(value.getBytes("ISO-8859-1"),"utf-8");//也可以解决乱码问题
    						fieldMap.put(filedName, value);//将键值对添加到集合内
    					}else{//如果是文件上传的控件
    						//获取文件名,使用工具类:FilenameUtils解决ie浏览器拿文件全路径名的问题
    						String name = FilenameUtils.getName(fileItem.getName());
    						//获取后缀名
    						String ext = FilenameUtils.getExtension(name);
    						
    						//验证后缀名是否满足图片类型
    						if(Arrays.asList(IMG_TYPE).contains(ext)) {
    							String randomUUID = UUID.randomUUID().toString();
    						
    							//(通过upload文件夹)获取项目下的存储资源的路径
    							// F:workspace.metadata...文件上传\upload
    							String path = request.getServletContext().getRealPath("/upload");
    							path = path.substring(0, path.indexOf(".metadata"));
    	
    							String pa = request.getContextPath(); //项目的上下文路径,这里获取的是乱码
    							pa = URLDecoder.decode(pa,"utf-8");//解码
    							System.out.println(pa);
    							
    							path=path.replace('/', '\')+pa+"\WebContent\upload";
    							System.out.println(path);
    				
    							//创建文件对象
    							File file = new File(path, randomUUID+"."+ext);
    							//将二进制流写入文件对象中
    							fileItem.write(file);
    							
    							CFile cfile = new CFile();
    							cfile.setFilename(randomUUID+"."+ext);
    							cfile.setFilepath(file.getAbsolutePath());
    							filesMap.put(randomUUID+"."+ext,cfile);
    						}else {
    							throw new RuntimeException("文件类型不符合");
    						}
    					}
    				}
    			}catch (RuntimeException e) {
    				throw e;
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

      

    2. 文件下载

    文件下载可以有两种方法:

        1.  超连接直接下载功能 

        2. 使用java代码经过servlet来进行下载

    1. download.jsp代码

    <body>
    	<p style="color:red"> 超连接直接下载功能 </p>
    	<a href="download/俄罗斯方块.html" download="俄罗斯方块">俄罗斯方块.html</a><br />
    	<a href="download/金玟岐 - 岁月神偷.mp3" download="岁月神偷">金玟岐 - 岁月神偷.mp3</a><br />
    	<a href="download/fun.mp4" download="fun视频">fun.mp4</a><br />
    	<a href="download/2.jpg" download="二次元图片">2.jpg</a><br />
    	
    	<p style="color:red"> 使用java代码经过servlet来进行下载 </p>
    	<a href="DownloadServlet?filename=俄罗斯方块.html">俄罗斯方块.html</a><br />
    	<a href="DownloadServlet?filename=金玟岐 - 岁月神偷.mp3">金玟岐 - 岁月神偷.mp3</a><br />
    	<a href="DownloadServlet?filename=fun.mp4">fun.mp4</a><br />
    	<a href="DownloadServlet?filename=2.jpg">2.jpg</a><br />
    </body>
    

      

    2. DownloadServlet.java代码

    package com.gs.controller;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/DownloadServlet")
    public class DownloadServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		String pa = request.getContextPath(); //项目的上下文路径,这里获取的是乱码
    		pa = URLDecoder.decode(pa,"utf-8");//解码
    		
    		String filename = request.getParameter("filename");
    		String path = request.getServletContext().getRealPath("/download");
    		path = path.substring(0, path.indexOf(".metadata"));
    		System.out.println(path); //F:workspace
    		
    		path=path.replace('/', '\')+pa+"\WebContent\download";
    		System.out.println(path); //F:workspace/文件上传和下载WebContentdownload
    		
    		
    		//将指定路径的文件绑定成File对象
    		File file = new File(path,filename);
    		//设置浏览器不能直接打开文件
    		response.setContentType("application/x-msdownload");
    		
    		//解决浏览器下载文件没有后缀名和文件名问题
    		String userAgent = request.getHeader("User-Agent");
    		if(userAgent.contains("MSIE")) {
    			//IE浏览器
    			filename = URLEncoder.encode(filename,"UTF-8");
    		}else {
    			//其他浏览器
    			filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");
    		}
    		
    		response.setHeader("Content-Disposition","attachment;filename="+filename);
    		//将文件以流的形式输出到页面中下载
    		Files.copy(Paths.get(file.getAbsolutePath()), response.getOutputStream());
    	}
    }
    

      

    页面显示:

        

  • 相关阅读:
    AGC023C Painting Machines
    LG3834 可持久化线段树1
    又是一天
    ARC103F Distance Sums
    CF1053E Euler tour
    UOJ22 外星人
    洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)
    洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
    CF49E Common ancestor(dp+dp+dp)
    洛谷4051 JSOI2007 字符加密(SA)
  • 原文地址:https://www.cnblogs.com/gshao/p/10389389.html
Copyright © 2020-2023  润新知