上传
创建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();
}