J2EE之 文件上传下载

一、文件上传:
1、关于上传的表单的规定
<!--1 必须是post提交
    2 表单的编码类型必须指定为 enctype="multipart/form-data" -->
<form action="/upload?cmd=upload" method="post" enctype="multipart/form-data">
	用户名:<input type="text" name="username"><br/>
	图像:<input type="file" name="file"><br/>
	<input type="submit" value="提交">
</form>

2.  在服务器端的servlet中就不能够通过request.getParameter("xxx")得到具体的值了

3、要导入包org.apache.commons.fileupload

4、文件上传相关代码

public class UploadServlet extends HttpServlet {
	//设置可上传文件的后缀名
	private String[] fileExts = {"doc","zip","rar","jpg","txt"};
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 
        //检查该请求是否是一个上传表单( 必须是 post请求,和enctype="multipart/form-data")
	Boolean  isMultipart  =	ServletFileUpload.isMultipartContent(request);
	if(isMultipart){
		//创建一个临时文件存放要上传的文件,第一个参数为上传文件大小,第二个参数为存放的临时目录
		DiskFileItemFactory factory = new DiskFileItemFactory(1024*1024*5,new File("C:\\temp1"));
		// 创建一个文件上传的句柄
		ServletFileUpload upload = new ServletFileUpload(factory);

		//设置上传文件的整个大小和上传的单个文件大小
		upload.setSizeMax(1024*1024*50);
		upload.setFileSizeMax(1024*1024*5);

		try {
			//把页面表单中的每一个表单元素解析成一个FileItem
			List<FileItem>   items = upload.parseRequest(request);
			for (FileItem fileItem : items) {
				//如果是一个普通的表单元素(type不是file的表单元素)
				if(fileItem.isFormField()){
					System.out.println(fileItem.getFieldName());  //得到对应表单元素的名字
					System.out.println(fileItem.getString());  //得到表单元素的值
				}else{
					//获取文件的后缀名
					String fileName = fileItem.getName();//得到文件的名字		
					String fileExt = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());

					if(Arrays.binarySearch(fileExts, fileExt)!=-1){
						try {
							//将文件上传到项目的upload目录并命名,getRealPath可以得到该web项目下包含/upload的绝对路径
							fileItem.write(new File(getServletContext().getRealPath("/upload")+"/"
                                                                             +UUID.randomUUID().toString()+"."+fileExt));
						} catch (Exception e) {
							e.printStackTrace();
						}
					}else{
						System.out.println("该文件类型不能够上传");
					}
				}
			}
		} catch (SizeLimitExceededException e) {
			System.out.println("整个请求的大小超过了规定的大小...");
		} catch (FileSizeLimitExceededException e) {
			System.out.println("请求中一个上传文件的大小超过了规定的大小...");
		}catch (FileUploadException e) {
			e.printStackTrace();
		} 
	}	
	}
}


5、文件上传的实例employee表单

第一步:创建employee的domain类,包含所需数据域。注意在其中定义文件上传的相对路径url

创建与其数据域对应的数据库表单employee,引入.properties配置文件链接数据库


第二步:创建Util类DataSourceUtil.java来加载配置文件

import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DataSourceUtil {
	private static DataSource  dataSource;
	static{
		try {
			Properties  properties = new Properties();
			//加载配置文件
			properties.load(DataSourceUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"));
			//创建dataSource
			dataSource = 	BasicDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static  DataSource  getDataSouce(){
		return dataSource;
	}
}

第三步:创建DAO类,接口IEmployeeDAO定义增删改查的操作,EmployeeDAOImpl实现这个接口进行具体操作处理

public class EmployeeDAOImpl implements IEmployeeDAO {
	private  QueryRunner  queryRunner = null;
	public EmployeeDAOImpl() {
		queryRunner = new QueryRunner(DataSourceUtil.getDataSouce());
	}
	@Override
	public void save(Employee employee) {
		//1. 创建连接
		//2. 根据sql的模板创建preparedStatement
		//3. 向preparedStatement设置参数
		//4. 执行sql
		//5. 关闭资源
		
		String sql = "insert into employee values(null,?,?,?,?,?)";
		Object[] params = {employee.getName(),employee.getSex(),employee.getTel(),employee.getFileName(),employee.getUrl()
		};
		execute(sql, params);
	}

	@Override
	public void remove(Long id) {
		String sql = "delete from employee where id = ?";
		Object[]  params = {id};
		execute(sql, params);
	}

	@Override
	public void update(Long id, Employee employee) {
		String sql = "update employee set name=?,sex=?,tel=?,fileName=?,url=? where id=?";
		Object[]  params = {employee.getName(),employee.getSex(),employee.getTel(),employee.getFileName(),employee.getUrl()
			,id};
		execute(sql, params);
	}
	
	public void execute(String sql,Object...params){
		try {	//upadate方法用于sql的insert,delete,update
			queryRunner.update(sql, params);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	
	@Override
	public Employee get(Long id) {
	    try {
	    	 //  new BeanHandler<Employee>(Employee.class)
	    	// new BeanHanlder中传入的泛型参数是指: query方法返回的类型
	    	// new BeanHandler<Employee>(Employee.class) 构造函数中传入的类型是将sql语句执行的结果转换为什么类型的对象
	    	//前提:  sql查询出来的结果的列名要和employee类的属性名字对应
			  return queryRunner.query("select * from employee where id=?", new BeanHandler<Employee>(Employee.class), id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@Override
	public List<Employee> list() {
		try {
			// 前提:  sql查询出来的结果的列名要和employee类的属性名字对应,query方法用于sql的select;返回的是一个Employee对象的List
				return queryRunner.query("select * from employee", new BeanListHandler<Employee>(Employee.class));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	


}

第四步:创建servlet类EmployeeServlet,save方法先设置employee对象的属性值,再把属性值用DAO操作的save方法保存到数据库中。

其中HttpServletRequestWithUpload类是抽取出来的文件上传下载的util类,CFile是一个domain

public class HttpServletRequestWithUpload extends HttpServletRequestWrapper {
	private Map<String, String>  textMap = new HashMap<String, String>();
	private Map<String, FileItem>  fileMap = new HashMap<String, FileItem>();
	private 	Boolean  isMultipart;
	public HttpServletRequestWithUpload(HttpServletRequest request) {
		super(request);
		   isMultipart = 	ServletFileUpload.isMultipartContent(request);
		if(isMultipart){
			FileItemFactory  fileItemFactory = new DiskFileItemFactory(1024*1024*5, new  File("C:/temp1"));
			ServletFileUpload  fileUpload = new ServletFileUpload(fileItemFactory);
			//设置整个请求中的文件大小 , 如果超出将会抛出SizeLimitExceededException
			fileUpload.setSizeMax(1024*1024*20);
			//设置单个文件的大小  //如果超出将会抛出FileSizeLimitExceededException
			fileUpload.setFileSizeMax(1024*1025*5);
			 try {
				List<FileItem>  fileItems =  fileUpload.parseRequest(request);
				for (FileItem fileItem : fileItems) {
					 if(fileItem.isFormField()){    //普通表单元素  ,   通过上传表单提交过来的中文必须通过GET方式处理乱码....  通过		request.setCharacterEncoding("UTF-8"); 是无法处理乱码的
						 textMap.put(fileItem.getFieldName(), new String(fileItem.getString().getBytes("ISO-8859-1"),"UTF-8"));
					 }else{  //上次表单元素
						String AllowFileExt =  getSession().getServletContext().getInitParameter("AllowFileExt");
						String NotAllowFileExt =  getSession().getServletContext().getInitParameter("NotAllowFileExt");
						 if(fileItem.getSize()!=0){
							 String fileExt = FilenameUtils.getExtension(fileItem.getName());
							 //当后缀名不合法的时候抛出异常
							 if(StringUtils.contains(AllowFileExt, fileExt.toLowerCase())|| !StringUtils.contains(NotAllowFileExt, fileExt)){
								 fileMap.put(fileItem.getFieldName(), fileItem);
							 }else{
								 throw new LogicException("不支持该类型文件");
							 }
						 }
					 }
				}
			} catch (FileSizeLimitExceededException e) {
				throw new LogicException("其中的一个文件的大小超出来规定的大小");
			} catch (SizeLimitExceededException e) {
				throw new LogicException("上传的所有文件的总大小超出来规定的大小");
			} catch (FileUploadException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public String getParameter(String name) {
		if(isMultipart){
			return textMap.get(name);
		}
		return super.getParameter(name);
	}


	@Override
	public Map getParameterMap() {
		if(isMultipart){
			return textMap;
		}
		return super.getParameterMap();
	}
	
	
	/**
	 * @param uploadPath  文件要上传的目录
	 * @param fieldName  要上传的表单元素的名字
	 * @return
	 */                 
	public CFile upload(String uploadPath,String fieldName){
			FileItem  fileItem = fileMap.get(fieldName);
			if(fileItem!=null){
				String fileName = FilenameUtils.getName(fileItem.getName());//得到文件的不带路径但是带后缀名的名字
				 				   
				String targetPath = uploadPath+"/"+UUID.randomUUID().toString()+"."+FilenameUtils.getExtension(fileName);
				try {
//					E:\workspace\day22\WebContent/upload/asdfasdfaia98ower.jpg
					fileItem.write(new File(getSession().getServletContext().getRealPath("/")+targetPath));
				} catch (Exception e) {
					e.printStackTrace();
				}
				return new CFile(fileName,targetPath);
			} 
		return null;
	}
	

}


通过上传表单提交的中文必须通过get方式处理乱码

public class EmployeeServlet extends HttpServlet {
	private IEmployeeDAO  employeeDAO ;
	@Override
	public void init() throws ServletException {
		employeeDAO = new EmployeeDAOImpl();
	}
	
	/*
	 *根据cmd找方法执行.. 默认执行list方法 
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	//根据反射获得url中的cmd,如果cmd为null则直接调用list方法
		request.setCharacterEncoding("UTF-8");
		String cmd = request.getParameter("cmd");
		if(StringUtils.isNotBlank(cmd)){
			try {
				Method  method = this.getClass().getMethod(cmd, HttpServletRequest.class,HttpServletResponse.class);
				method.invoke(this, request,response);
			} catch (Exception e) {
				list(request, response);
			}
		}else{
			list(request, response);
		}
	}
	
	public void save(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpServletRequestWithUpload httpServletRequestWithUpload = null;
		try {
			httpServletRequestWithUpload = new HttpServletRequestWithUpload(request);
		} catch (LogicException e) { //如果出现了异常就让error.jsp显示错误信息...
			String message = e.getMessage();
			request.setAttribute("message", message);
			request.getRequestDispatcher("/error.jsp").forward(request, response);
			return;
		}
		if(httpServletRequestWithUpload!=null){
			Employee  employee = new Employee();
			
			employee.setName(httpServletRequestWithUpload.getParameter("name"));
			employee.setSex(httpServletRequestWithUpload.getParameter("sex"));
			employee.setTel(httpServletRequestWithUpload.getParameter("tel"));
			
			
			CFile  cFile =	httpServletRequestWithUpload.upload("/upload", "uploadFile");
			if(cFile!=null){
				employee.setFileName(cFile.getSrcFileName());
				employee.setUrl(cFile.getTargetFilePath());
			}
			employeeDAO.save(employee);
			response.sendRedirect("/employee?cm=list");
		}
	}

	public void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id = request.getParameter("id");
		Employee  employee = employeeDAO.get(Long.parseLong(id));
		request.setAttribute("employee", employee);
		request.getRequestDispatcher("/WEB-INF/view/employee/edit.jsp").forward(request, response);
		
	}
	//在修改的时候,如果说没有选择上传文件,将会保留之前的文件, 如果选择了就会把原来的从系统中删掉,上传选择的文件...
	public void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpServletRequestWithUpload hru = new HttpServletRequestWithUpload(request);
		String id = hru.getParameter("id");
		
		Employee  employee = employeeDAO.get(Long.parseLong(id));
		
		employee.setName(hru.getParameter("name"));
		employee.setSex(hru.getParameter("sex"));
		employee.setTel(hru.getParameter("tel"));
		CFile   cFile = hru.upload("/upload", "uploadFile");
		//说明选择了文件
		if(cFile!=null){
			  String srcUrl = employee.getUrl();
			  deleteFile(srcUrl);
			employee.setUrl(cFile.getTargetFilePath());
			employee.setFileName(cFile.getSrcFileName());
		}
		
		employeeDAO.update(Long.parseLong(id), employee);
		response.sendRedirect("/employee?cmd=list");
	}

	/**
	 * 删除一个文件
	 * @param srcUrl  相对路径
	 */
	public void deleteFile(String srcUrl) {
		File file = new File(getServletContext().getRealPath("/")+srcUrl);
			if(file.exists()){
				file.delete();
			}
	}
	
	
	
	public void remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id = request.getParameter("id");
		//删除的时候可不能够单单删除数据库中的记录,也要删除该记录对应的文件
		Employee  employee = employeeDAO.get(Long.parseLong(id));
		String url = employee.getUrl(); //仅仅是相对路径
		
		employeeDAO.remove(Long.parseLong(id));
		deleteFile(url);
		response.sendRedirect("/employee?cm=list");
		
	}
	public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			List<Employee>  employees =  	employeeDAO.list();
			request.setAttribute("employees", employees);
			request.getRequestDispatcher("/WEB-INF/view/employee/list.jsp").forward(request, response);
	}
	public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/view/employee/edit.jsp").forward(request, response);
	}

}



二、文件下载:

需要设置相应的ContentType为application/x-msdownload

需要根据不同浏览器设置不同的Header的Content-Disposition项

public class DownloadServlet extends HttpServlet {
	private IEmployeeDAO  employeeDAO;
	@Override
	public void init() throws ServletException {
		employeeDAO = new EmployeeDAOImpl();
	}
	/*

	     通过Servlet去读取文件,然后在写到响应的输出流中....

	 */
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("application/x-msdownload");
		
		String id = request.getParameter("id");
		Employee  employee = employeeDAO.get(Long.parseLong(id));
		String user_agent = request.getHeader("User-Agent");
		if(user_agent.contains("IE")){
			response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(employee.getFileName(), "UTF-8"));
		}else if(user_agent.contains("Firefox")){
			response.setHeader("Content-Disposition", "attachment; filename="+new String(employee.getFileName().getBytes("UTF-8"),"ISO-8859-1"));
		}
		
		/*
		 * 权限的判断
		 * 
		 */
		 File  file = new File(getServletContext().getRealPath("/")+employee.getUrl());

		 if(file.exists()){
			 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
			 byte[] b = new byte[1024*5];
			 int num;
			 OutputStream  outputStream = response.getOutputStream();  //得到响应的输出流...
			 while((num=bufferedInputStream.read(b))!=-1){
				 outputStream.write(b, 0, num);
				 outputStream.flush();
			 }
		 }
		 
	}

}



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值