• 文件上传该注意的问题


    文件上传该注意的基本问题:


    (1)必须使用POST表单;


    (2)表单的enctype必须是multipart/form-data;


    (3)需要在表单中添加file表单字段,即<input type=”file”…/>;


    (4)request.getParameter(String)方法失效,因为request.getParameter(String)方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容;


    (5)可以使用request的getInputStream()方法获取ServletInputStream对象,它是InputStream的子类,这个ServletInputStream对象对应整个表单的正文部分(从第一个分隔线开始,到最后),这说明我们需要的解析流中的数据。当然解析它是很麻烦的一件事情。


    (6)确定我们需要使用fileupload来对request.getInputStream()的内容进行解析!commons-fileupload是由apache的commons组件提供的上传组件,它最主要的工作就是帮我们解析request.getInputStream()。

    fileupload组件需要的JAR包有:
    ------commons-fileupload.jar,核心包;
    ------commons-io.jar,依赖包。

    fileupload的核心类有:DiskFileItemFactory,ServletFileUpload,FileItem。


    ————————————————————————————————————————————————

    ————————————————————————————————————————————————


    文件上传该注意的细节问题:


    (7)把上传的文件放到WEB-INF目录下;如果没有把用户上传的文件存放到WEB-INF目录下,那么用户就可以通过浏览器直接访问上传的文件,这是非常危险的。


    (8)上传文件名称可能是完整路径;使用不同浏览器测试,其中IE6就会返回上传文件的完整路径,就是需要处理这一问题。处理这一问题也很简单,无论是否为完整路径,我们都去截取最后一个“\”后面的内容就可以了。


    (9)中文乱码问题;
    上传文件名称中包含中文:
    当上传的谁的名称中包含中文时,需要设置编码,commons-fileupload组件为我们提供了两种设置编码的方式:
    ------request.setCharacterEncoding(String):这种方式是我们最为熟悉的方式了;
    ------fileUpload.setHeaderEncdoing(String):这种方式的优先级高与前一种。
    上传文件的文件内容包含中文:
    通常我们不需关心上传文件的内容,因为我们会把上传文件保存到硬盘上!也就是说,文件原来是什么样子,到服务器这边还是什么样子!
    但是如果你有这样的需求,非要在控制台显示上传的文件内容,那么你可以使用fileItem.getString(“utf-8”)来处理编码。


    (10)上传文件同名问题;使用uuid来解决,在每个文件前加uuid;


    (11)一个目录不能存放过多的文件;


    (12)限制单个上传文件的大小;使用ServletFileUpload类的setFileSizeMax(long)就可以了。参数就是上传文件的上限字节数,例如servletFileUpload.setFileSizeMax(1024*10)表示上限为10KB。


    (13)上传文件的总大小限制;使用ServletFileUpload类的setSizeMax(long)方法即可;


    (14)设置缓存大小与临时目录;

    DiskFileItemFactory dfif = new DiskFileItemFactory(1024*20, new File("F:\temp"));
    ServletFileUpload fileUpload = new ServletFileUpload(dfif);

    fileupload会判断文件大小是否超出20KB,如果是那么就把文件保存到临时目录temp上,如果没有超出,那么就保存在内存中。


    ————————————————————————————————————————————————

    ————————————————————————————————————————————————


    文件上传实例:


    相关jar包:


    jsp页面:



    上传代码:

    	public String add() throws UnsupportedEncodingException {
    		HttpServletRequest request = ServletActionContext.getRequest();
    		HttpServletResponse response = ServletActionContext.getResponse();
    		
    		//request.setCharacterEncoding("utf-8");
    		
    		DiskFileItemFactory factory = new DiskFileItemFactory();
    		ServletFileUpload sfu = new ServletFileUpload(factory);
    		sfu.setFileSizeMax(2048 * 2048);
    
    		try {
    			List<FileItem> fileItemList = sfu.parseRequest(request);
    			Map<String, String> map = new HashMap<String, String>();
    			for (FileItem fileItem : fileItemList) {
    				if (fileItem.isFormField()) {
    					map.put(fileItem.getFieldName(),
    							fileItem.getString("UTF-8"));
    				}
    			}
    			post = CommonUtils.toBean(map, Post.class);
    			post.setPid(CommonUtils.uuid());
    			User user = (User) request.getSession().getAttribute("sessionUser");
    			post.setUser(user);
    			post.setPtime(new Date());
    
    			// 得到保存的目录
    			String savepath = ServletActionContext.getServletContext()
    					.getRealPath("/post_img");
    			// 得到文件名称:给原来文件名称添加uuid前缀!避免文件名冲突
    			String filename = CommonUtils.uuid() + "_"
    					+ fileItemList.get(3).getName();
    
    			/*
    			 * 校验文件的扩展名
    			 */
    			if (!filename.toLowerCase().endsWith("jpg")) {
    				request.setAttribute("msg", "您上传的图片不是JPG扩展名!");
    				return "posting";
    			}
    
    			// 使用目录和文件名称创建目标文件
    			File destFile = new File(savepath, filename);
    			// 保存上传文件到目标文件位置
    			fileItemList.get(3).write(destFile);
    			post.setPimg("post_img/" + filename);
    			postService.add(post);
    		} catch (Exception e) {
    			if (e instanceof FileUploadBase.FileSizeLimitExceededException) {
    				request.setAttribute("msg", "您上传的文件超出了1024KB");
    				return "posting";
    			}
    		}
    
    		return findByStatus();
    	}

  • 相关阅读:
    线程间的通信
    不用加减乘除做加法
    关键字throw(something)限制
    C++ 中的“ !” 运算
    n个骰子的点数
    State 模式
    Strategy 模式
    构造函数为什么不能是虚函数 ( 转载自C/C++程序员之家)
    n个骰子的点数
    和为S的两个数字
  • 原文地址:https://www.cnblogs.com/Arry10/p/7731790.html
Copyright © 2020-2023  润新知