Java web中上传和下载详解(上)
2013-08-19 16:20
351 查看
Java web中上传和下载详解
文件上传:
先来看一下上传对form表单有什么要求?必须是form表单提交。
表单中的method必须是post,不能是get
表单中的enctype的属性值必须是:multipart/form-data。当不是multipart的时候,就算<input type="file">提交的效果也和普通的text类型一样。
表单中项使用file类型
文件上传对servlet的要求?
因为表单中上传的不再是字符内容,而是字节内容。就算是上传文本文件也是一样的。所以不能使用request.getParameter(String fieldName)方法。
那使用什么呢。这个时候可以使用request.getInputStream();方法获取ServletInputStream对象,它是InputStream类的子类,这个对象对应表单的正文部分,关于正文部分下面会介绍。
关于正文部分介绍。
这个是有可以使用HTTP抓包工具,我使用的是Firebug。在Firefox进行抓包的。如下图所示:
ServletInput中就包含第二张图片的内容。可以通过以下方法得到
public void doPost(HttpServletRequest request,HttpServletResponse response)throw IOException,ServletException{ request.setCharacterEncoding("utf-8"); ServletInputStream in = request.getInputStream; String s = IOUtils.toString(in);//Apache的commons组件中的包 System.out.println(s);//结果如下 }
执行结果如下:和抓包来的没什么区别
------WebKitFormBoundaryH06xO2noLxVFeenm Content-Disposition: form-data; name="username" csdn ------WebKitFormBoundaryH06xO2noLxVFeenm Content-Disposition: form-data; name="filename"; filename="a.txt" Content-Type: text/plain E:\Application\workspace\exam\src\cn\itcast\day20\CountDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo2.java E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo3.java E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo4.java E:\Application\workspace\exam\src\cn\itcast\day20\FileFilterDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\JavaFileList.java E:\Application\workspace\exam\src\cn\itcast\day20\PrintWriterDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\PropertiesDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\SequenceDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\SequenceInputStreamDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\SequenceVideoDemo.java E:\Application\workspace\exam\src\cn\itcast\day20\SplitFileDemo.java ------WebKitFormBoundaryH06xO2noLxVFeenm--
。
上传的任务就是将这些信息解析出来如果是文件部分保存到文件中,不是文件部分该给谁给谁。
4.按照上面的上传文件中ServletInputStream流的格式我自己写了一个,只能上传文本文件的上传方法。(能力有限)
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到流对象 ServletInputStream in = request.getInputStream(); //将流中的对象写入到一个字符串中。可能使用StringBuffer更好 int len = 0; byte buf[] = new byte[1024]; String content = ""; while((len = in.read(buf))!=-1){ content = content + new String(buf, 0, len); } //将内容按行分割 String[] contents = content.split("\n"); //将数组转换成数组 List<String> lists = Arrays.asList(contents); //是否包含这个Content-Type: text/plain。也就是文本文件内容的开始了 System.out.println("执行:"+lists.contains(new String("Content-Type: text/plain"))); //获取开始和结束位置 int start = 0; int end = 0; for (int i=1;i<lists.size();i++) { if(lists.get(0).equals(lists.get(i))){ end = i; } } System.out.println(start+":"+end); //将数组按开始位置和结束位置截取 List<String> fileList = lists.subList(end+4, lists.size()-1); //保存的文件 FileWriter writer = new FileWriter("F:\\a.txt"); //遍历数组如入文件 for (String s : fileList) { writer.write(s); writer.write("\n"); } writer.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); }
使用Apache的commons组件包实现上传(还是这个强大):
快速入门(得到的效果和上面的一样):public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取解析器工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //获得解析器 ServletFileUpload fileUpload = new ServletFileUpload(factory); try { //解析request List<FileItem> items = fileUpload.parseRequest(request); //遍历解析得到的FileItem对象 for(FileItem item : items){ //如果字段名是username if(item.getFieldName().equalsIgnoreCase("username")){ //得到提交过来的值 System.out.println(item.getString()); //如果是这个说明是文件 }else if(item.getFieldName().equalsIgnoreCase("fileName")){ //得到提交过来的值,如果是文本文件能输出,否则是乱码 item.write(new File("F:\\","b.txt")); } } } catch (Exception e) { e.printStackTrace(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
完全体演示:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决中文文件名问题 /** * 也可以是fileUpload.setHeaderEncoding("utf-8");优先级高 */ request.setCharacterEncoding("utf-8"); //获取解析器工厂,在factory中设置 (1024*20,new File("F://temp");如果文件过大 //设置文件超过20kb就缓存,缓存文件是在F盘的temp文件下 DiskFileItemFactory factory = new DiskFileItemFactory(); //获得解析器 ServletFileUpload fileUpload = new ServletFileUpload(factory); //设置上传的全部大小,包括<input type='text'> // fileUpload.setSizeMax(1024*900); //设置上传文件的大小,1024为1kb fileUpload.setFileSizeMax(300*1024); // fileUpload.setHeaderEncoding("utf-8"); try { //解析request List<FileItem> items = fileUpload.parseRequest(request); //遍历解析得到的FileItem对象 for(FileItem item : items){ //如果字段名是username if(item.getFieldName().equalsIgnoreCase("username")){ //得到提交过来的值 System.out.println(item.getString()); //如果是这个说明是文件 }else if(item.getFieldName().equalsIgnoreCase("fileName")){ //得到文件名 String fileName = item.getName(); //防止有些浏览器上传文件的时候,上传文件的带盘符的绝对路径。我们只要文件名就行 int index = fileName.lastIndexOf("\\"); if(index!=-1){ fileName = fileName.substring(index+1); } //获取后缀名.假设我只上传静态图片格式的文件,也就是格式是jpg,bmp,png这三种。其他的都不要 index = fileName.lastIndexOf("."); //说明没有后缀名 if(index==-1){ //一般情况是,通过request.setAttribute("msg","您上传的文件没有后缀名,请重新上传"); //转发到request.getRequestDispatcher("路径").forward(request, response); //return; //这里我就全输出了 System.out.println("上传的文件没有后缀名"); return; } String extension = fileName.substring(index+1); //上传文件如果不是以上面三个后缀名结尾,就输出错误信息 if (!extension.equalsIgnoreCase("bmp") && !extension.equalsIgnoreCase("jpg") && !extension.equalsIgnoreCase("png")) { System.out.println("上传的文件必须是bmp或jpg或png"); return; } //上传文件肯定是多个,命名也是一个问题。使用Apache的commons组件的类 fileName = getuuid()+"."+extension; //上传的文件放到哪,只能放在WEB-INF下面.如果你下面还要放分目录的话。有很多的算法 //有按时间的,用户的,文件名的hash值的等等。看需求 //我来按时间,也就是每天一个文件夹 String timeStamp = new SimpleDateFormat("yyyy.MM.dd").format(new Date()); String savePath = this.getServletContext().getRealPath("/WEB-INF/myupload")+"\\"+timeStamp; File f = new File(savePath); f.mkdirs(); item.write(new File(savePath,fileName));
item.delete();//删除临时文件}}} catch (Exception e) {if(e instanceof FileUploadBase.FileSizeLimitExceededException){System.out.println("上传文件不能大于300kb");return;}else{e.printStackTrace();}}}public static String getuuid() {return UUID.randomUUID().toString().replace("-",
"");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}
如果还要判断上传文件的宽度和高度。只需在后面加上:
File f = new File(savePath); f.mkdirs(); File saveFile = new File(savePath,fileName); item.write(saveFile); item.delete();//删除临时文件 ImageIcon icon = new ImageIcon(saveFile.getAbsolutePath()); Image image = icon.getImage(); image.getHeight(null);//得到图片的高 image.getWidth(null);//得到文件的宽 //如果不满足条件 saveFile.delete();
其他类型的文件也就类似了。
相关文章推荐
- JAVAWEB开发之Struts2详解(三)——Struts2信息国际化、自定义拦截器以及Struts2文件上传和下载详解
- Java web中上传和下载详解(下)
- 【JAVA】Web中文件的上传与下载
- 20160421javaweb之上传下载小案例---网盘
- JavaWeb文件上传与下载功能解析
- JAVA Web 之 struts2文件上传下载演示(二)(转)
- Java乔晓松-文件的上传和下载(Web)
- Java乔晓松-文件的上传和下载(Web) 2
- java web 中一些简单的操作 比如上传、下载等(一)
- JavaWeb_13_文件上传下载_演示fileupload
- JavaWeb 实现文件上传下载(笔记)
- 用java在web环境下上传和下载文件的技巧
- JavaWeb——文件上传和下载
- JavaWEB——文件上传与下载
- JavaWeb之文件上传与下载&邮件技术(十八)
- Java-WEB文件上传下载例程
- JAVAWEB开发之SpringMVC详解(二)——高级开发、数据回显、参数绑定集合、图片上传、json交互、validation校验、异常处理、RESTful支持、拦截器
- java使用webuploader实现跨域上传详解
- Portal-Basic Java Web 应用开发框架:应用篇(四) —— 文件上传和下载
- java web 实现 文件上传及下载