准备上传页面 upload.html
//method必须是post的,get不能上传文件 //enctype="multipart/form-data" 表示提交的数据是二进制文件 <form action="uploadPhoto" method="post" enctype="multipart/form-data"> </from> //提供type="file" 的字段进行上传 <input type="file" name="filepath" />
讲解上传思路
1、输入流
包含普通项(type="text")和上传项(type="file"),中间通过分割线隔开.
通过判断可以知道哪些是上传项、哪些是普通项。
2、当为上传项时
先在服务器上新建一个文件,然后利用IO流,将这些二进制文件写入服务器上的这个文件中
核心API
FileItem
——是一个接口,其实现类是DiskFileItem。
表单中的每个输入项,被封装成一个FileItem对象(即一个Input项对应一个FileItem对象)。
FileItem item = (FileItem) iter.next(); /*1、判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段*/ //普通表单字段则返回true,否则返回false。 boolean isFormField(); /*2、获取浏览器上传的文件的输入流*/ InputStream is = item.getInputStream(); /*3、获得文件上传字段中的文件名*/ String getName() ; /*4、返回表单标签name属性的值*/ String getFieldName() ; /*5、将FileItem对象中保存的数据流内容以一个字符串返回*/ String getString();
其它操作
/*1、使用迭代器Iterator遍历集合中的元素*/ //hasNex()t判断是否有下一个,从空的位置开始遍历 Iterator iter = items.iterator(); /*2、调用getInputStream方法得到数据输入流,从而读取上传数据*/ InputStream is = item.getInputStream(); /*3、根据时间戳创建文件名*/ filename = System.currentTimeMillis() + ".jpg"; /*4、获取当前项目下某个目录文件夹的路径*/ String photoFolder =request.getServletContext().getRealPath("uploaded"); /*5、在某文件夹下创建新文件*/ File f = new File(photoFolder, filename); f.getParentFile().mkdirs(); /*6、复制文件*/ FileOutputStream fos = new FileOutputStream(f); byte b[] = new byte[1024 * 1024]; int length = 0; while (-1 != (length = is.read(b))) { fos.write(b, 0, length); } fos.close();
DiskFileItemFactory
——是创建FileItem对象的工厂。
//1、设置内存缓冲区的大小,默认值为10K。 //当上传文件大于缓冲区大小时,fileupload组件将使用临时文件缓存上传文件。 public void setSizeThreshold(int sizeThreshold);
ServletFileUpload
——负责处理上传的文件数据,将表单中的每个输入项,封装成一个FileItem对象。
——又称“文件上传解析器”。
/*1、解析request对象*/ //并把表单中的每一个输入项包装成一个fileItem 对象 //并返回一个保存了所有FileItem的list集合。 List<FileItem> parseRequest(HttpServletRequest request);
准备 上传功能UploadPhotoServlet的开发
需要用到两个第三方的jar包,commons-io-1.4.jar和commons-fileupload-1.2.2.jar。
InputStream is=null; Category category=new Category(); //(可略) try { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); factory.setSizeThreshold(1024 * 10240); List items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (!item.isFormField()) {/*该字段为上传文件字段*/ is = item.getInputStream(); /*实现文件的上传*/ String imageFolder =request.getServletContext().getRealPath("img/category"); //此处可灵活修改成自己想要的保存目录 String filename = category.getId()+".jpg";//此处可灵活修改成自己想要的命名方式 File f = new File(imageFolder, filename); FileOutputStream fos = new FileOutputStream(f); byte b[] = new byte[1024 * 1024]; int length = 0; while (-1 != (length = is.read(b))) { fos.write(b, 0, length); } fos.flush(); /*下面代码,把图片文件保存成jpg格式(ImageUtil是一个自定义的工具类,可到“常用工具类”中去查看)*/ BufferedImage img = ImageUtil.change2jpg(f); ImageIO.write(img, "jpg", f); }else{//普通字段,(可略) String paramName = item.getFieldName(); String paramValue = item.getString(); paramValue = new String(paramValue.getBytes("ISO-8859-1"), "UTF-8"); //完成一条数据的插入 category.setName(paramValue); new CategoryDAO().add(category); } } } catch (Exception e) { // TODO: handle exception } response.sendRedirect("categoryList"); //(可略) }
这里有两个bug要注意
1、在编辑页面修改了文件图片,返回列表显示页面时,如果发现原先上传的图片还是没有改变,刷新页面即可看到编辑后的文件图片。
2、设置上传文件保存路径在当前项目的img/category下,当时img/category文件夹下为空,列表显示页面有文件图片显示,
可在相关servlet类中System.out.println(file);把文件上传路径打印出来。