一、文件的上传
- 要有一个form标签,method=post
- form标签的encType属性值必须为multipart/form-data值
- 在form标签中使用input type=file添加上传的文件
- 编写服务器代码接收、处理上传的数据
<form action="/upload" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"><br> 头像:<input type="file" name="photo"><br> <input type="submit" value="上传"> </form>
multipart/form-data表示提交的数据以多段(每一个表单项一个数据段)的形式进行拼接。然后以二进制流的形式发送给服务器。
2.接收
接收时要以流的形式进行接收:
public class upload_Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("文件传过来了");
ServletInputStream inputStream=request.getInputStream();
byte[] buffer=new byte[1024000];
int read=inputStream.read(buffer);
System.out.println(new String(buffer,0,read));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
3.commons-fileupload
commons-fileupload.jar需要依赖.commons-fileupload.jar,两个包都需要引入。
commons-fileupload 工具包主要是我们用来操作文件上传的助手,里面封装了对流操作的全过程,简化了实现文件上传的代码复杂度,只需合理的运用类中的方法就可以达到文件上传的效果。
common-fileupload 包中三大核心类
1)DiskFileItemFactory类
作用:磁盘文件工厂类,它还可以设置缓冲区大小以及设置临时保存位置。
setSizeThreshold( int sizeThreshold )
// 设置缓冲区大小,默认sizeThreshold的大小为:10240(10KB)。
setRepository( File repository );
// 设置临时文件的保存位置,如果不设置,repository为系统的临时目录。
DiskFileItemFactory();
// 构造方法,缓冲区大小为默认sizeThreshold和临时文件为目录为默认repository的磁盘文件工厂类。
DiskFileItemFactory( int SizeThreshold , File repository );
// 构造方法,指定缓冲区大小和指定临时文件的磁盘文件工厂类。
2)ServletFileUpload类
作用:文件上传类,实现上传的一些实用方法的集合。
public List<FileItem> parseRequest( HttpSevletRequest request );
// 解析request对象,获取表单中的所有数据信息,并返回一个List<FileItem>集合,
// 其中每个FileItem就是一个表单数据项信息。
boolean isMultipartContext( HttpServletRequest request );
// 根据请求对象来判断是普通表单,还是文件上传表单,如果是文件上传表单,则返回true,否则false。
setFileSizeMax( long fileSizeMax );
// 设置单个文件的上传的大小上限。
setSizeMax( long sizeMax );
// 设置总文件上传的大小上限。
setHeaderEncoding( Charset charset);
// 解决上传文件中的文件名中文乱码的问题。
ServletFileUpload( DiskFileItemFactory factory );
// 构造方法,指定磁盘文件工厂类,并使用factory指定的缓冲区大小和临时文件。
3)FileItem类
作用:表单数据项类,保存了表单数据项的所有信息,
isFormField();
// 判断是否为普通数据项。
String getFieldName();
// 获取该表单数据项的名称。即:<input>标签中的name属性。
String getString( String encoding );
// 以指定的编码格式解析该表单数据项的值。即:<input>标签中的value属性。
String getName();
// 获取上传文件中的文件名。
getInputStream();
// 获取上传文件的内容的输入流,使用文件复制就能完成文件的上传。
delete();
// 删除临时文件。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.判断上传的数据是否是多段数据
if(ServletFileUpload.isMultipartContent(request)){
//2.创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory=new DiskFileItemFactory();//磁盘上传对象
//3.创建用于解析上传数据的工具类servletfileupload类
ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);//文件上传对象
try {//4.解析上传的数据,得到每一个表单项fileitem
List<FileItem> list=servletFileUpload.parseRequest(request);
//5.循环判断,每一个表单项时普通类型还是上传的文件
for (FileItem fileItem:list){
if (fileItem.isFormField()){
//6.处理普通表单项
System.out.println("表单项的name属性值:"+fileItem.getFieldName());
System.out.println("表单项的value属性值:"+fileItem.getString("UTF-8"));
}else{
//7.处理上传的文件
System.out.println("上传文件的name属性值:"+fileItem.getFieldName());
System.out.println("上传的文件名:"+fileItem.getName());
try {//8.保存文件到磁盘
// 获取 当前项目下的 /files 目录的绝对位置
String path = this.getServletContext().getRealPath("/files");
File file = new File(path); // 创建 file对象
// 创建 /files 目录
if (!file.exists()) {
file.mkdir();
}
//fileItem.write(new File("E:\\"+fileItem.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}
二、文件下载
服务器要:
- 获取要下载的文件名
- 读取要下载的文件内容
- 通过响应头告诉客户端返回的数据类型
- 把要下载的文件内容回传给客户端
- 通过响应头告诉客户端收到的数据是用于下载使用
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取要下载的文件名
String filename="book.jpg";
//2.读取要下载的文件内容(通过ServletContext读取)
ServletContext servletContext=getServletContext();
//获取要下载的文件类型
String mimetype=servletContext.getMimeType("/file/"+filename);
System.out.println("要下载的文件类型"+mimetype);
//4.回传前告诉客户端返回的数据类型
response.setContentType(mimetype);
//5.告诉客户端收到的数据是用于下载使用
response.setHeader("Content-Disposition","attachment;filename="+filename);
//Content-Disposition响应头表示收到的数据怎么处理
//attachment表示附件,表示下载使用
//filename=文件名
//文件名含有中文,要重新编码。url编码可以在IE和谷歌中用。火狐用base64解决。
//response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("中国.jpg","UTF-8"));
//request.getHeader("User-Agent").contains("Firefox")判断浏览器种类
InputStream resourceAsStream=servletContext.getResourceAsStream("/file/"+filename);
//获取响应的输出流
OutputStream outputStream=response.getOutputStream();
//3.把下载的文件内容回传给客户端
//读取输入流中全部数据,复制给输出流,输出给客户端
org.apache.commons.io.IOUtils.copy(resourceAsStream,outputStream);
//4.
//5.
}