上传
创建JSP页面,添加form表单
注意点:1.表单需要使用“post”请求
2.表单的默认属性enctype="application/x-www-form-urlencoded"
3.上传文件的表单enctype需要设置为 multipart/form-data
4.当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。
<form action="${pageContext.request.contextPath }/FileUpLoadServlet" method="post" enctype="multipart/form-data"> User:<input type="text" name="name" /><br/> <input type="file" name="photo"/><br/> <input type="file" name="photo1"/><br/> <input type="file" name="photo2"/> <input type="submit" value="提交"> </form>
导包:一般情况下使用commons-fileupload-1.3.1.jar这个工具来解析多部件请求
fileupload 依赖 commons-io 所以我们要是Filtupload需要同时导入io包
核心类:
DiskFileItemFactory
- 工厂类,用于构建一个解析器实例。
ServletFileUpload
- 解析器类,通过该类实例来解析request中的请求信息。
FileItem
DiskFileItemFactory
- 工厂类,用于构建一个解析器实例。
ServletFileUpload
- 解析器类,通过该类实例来解析request中的请求信息。
FileItem
- 工具会将我们请求中每一个部件,都封装为一个FileItem对象,处理文件上传时,只需要调用该对象的方法
具体代码:
//1.创建一个工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2.创建ServletFileUpload对象,通过这个对象完成上传功能 ServletFileUpload fileUpload = new ServletFileUpload(factory); //用fileUpload这个对象解析request请求 List<FileItem> fileList = fileUpload.parseRequest(request);
fileList的方法:
类型 | 方法 | 详解 |
boolean | isFormField() | 当前表单项是否是一个普通表单项,true是普通表单项, false是文件表单项 |
String | getContentType() | 返回的是文件的类型,是MIME值 |
String | getFieldName() | 获取表单项的name属性值 |
String | getName() | 获取上传的文件的名字 |
long | getSize() | 获取文件的大小 |
String | getString(String encoding) | 获取表单项的value属性值,需要接受一个编码作为参数。 |
void | write(File file) | 将表单项中的内容写入到磁盘中 |
部分方法代码书写
long size = item.getSize(); String contentType = item.getContentType();//文件类型 String name = item.getName();//图片实际名 String fieldName = item.getFieldName();//属性名 System.out.println(size+" "+contentType+" "+name+" "+fieldName);
完整代码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建一个工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2.创建ServletFileUpload对象,通过这个对象完成上传功能 ServletFileUpload fileUpload = new ServletFileUpload(factory); //用fileUpload这个对象解析request请求 try { List<FileItem> fileList = fileUpload.parseRequest(request); for(FileItem item:fileList){ if(item.isFormField()){ //代表普通表单项 String name = item.getFieldName(); String value = item.getString("utf8"); System.out.println(name+":"+value); }else{ //代表上传的文件 long size = item.getSize(); String contentType = item.getContentType();//文件类型 String name = item.getName();//图片实际名 String fieldName = item.getFieldName();//属性名 System.out.println(size+" "+contentType+" "+name+" "+fieldName); item.write(new File("C:\\Users\\LWJJJJJ\\Desktop\\123.jpg")); }//MIME类---总类型/具体类型 } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
细节问题:
1.部分浏览器会将文件的完整路径作为文件名发送。也就是说路径会产生问题
但是一般浏览器,如火狐、谷歌、IE7以上都不会,IE6会
像这类文件名我们需要截取一下字符串,只获取名字这部分,而不需要获取路径部分的信息。
if(name.contains("\\")){ //如果包含则截取字符串 name = name.substring(name.lastIndexOf("\\")+1);
//一定要+1,不然会多了一个/ }
2.上传的文件有可能出现重名,后上传的文件会将先上传的文件覆盖
解决方法:给文件加一个唯一标识符--UUID
String prefix = UUID.randomUUID().toString(); prefix.replace("-", ""); String fielName=prefix+"_"+name;
3.有些情况需要限制上传文件的大小
fileUpload.setFileSizeMax(1024*17600);//限制单个文件的大小 fileUpload.setSizeMax(1024*20000);//限制文件的总大小 //会分别抛出异常 catch(SizeLimitExceededException e){ System.out.println("总图片过大"); }catch(FileSizeLimitExceededException e){ System.out.println("单张图片过大"); }
4.当用户上传一个空的文件,依然会将文件保存到硬盘上
解决方法:在保存文件应该先对文件的大小进行判断,如果size为0,则不处理
long size = item.getSize(); //如果不存在,就继续,不必创造文件 if(size==0){ continue; }
下载
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext servletContext = request.getServletContext(); String filename = "风吹麦浪.mp3"; String path = servletContext.getRealPath("/WEB-INF/"+filename); File file = new File(path); //创建输入流 InputStream in = new FileInputStream(file); //告诉浏览器文件的类型,需要设置一个MIME值 //用servletContext.getMimeType()直接获取path的MIME值 String type = servletContext.getMimeType(path); response.setContentType(type); filename = new String(filename.getBytes("gbk"),"iso8859-1"); //下载文件信息 response.setHeader("Content-Disposition", "attachment;filename="+filename); //输出流,到浏览器上 ServletOutputStream out = response.getOutputStream(); IOUtils.copy(in, out); in.close(); }