目录

  • 开篇
  • 文件的上传
  • 文件的下载:



开篇

文件的上传与下载是非常常见的功能,很多的系统中,或者软件中都经常使用文件的上传和下载;


文件的上传

文件上传的步骤

  1. 首先要有一个form标签,method=post请求
  2. form标签的encTyppe属性值必须为multipart/form-data值
  3. 在form标签中使用input type=file添加上传的文件
  4. 编写服务器代码(Servlet程序)接受,处理上传的数据。

(1)定义一个update.jsp的页面,关键代码如下所示:

<form action=" " method=" post" enctype=" multipart/form-data">
用户名:<input type="text" name="username"><br>
头像:<input type="file" name="photo"><br>
<input type="submit" value="上传" >

</form>
上传的http协议内容介绍:
请求头中:
Content-Type表示提交的数据类型
encTyppe=multipart/form-data表示提交的数据,以多段(每一个表单项一个数
据段)的形式进行拼接,然后以二进制流的形式发送给服务器;

boundary表示每段数据的分隔符,此分隔符由浏览器每次随机生成,是每段数据的分
隔符
谷歌浏览器为了内容显示的美观整洁,没有把上传的内容数据显示出来

多了两个--符号的分界符表示协议的结束

(2)编写Servlet程序来对上传文件进行处理,客户端以流的形式发送,所以Servlet程序也应该以流的形进行接受:

public class UploadServlet extends HttpServlet{
@override
protected void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException{
ServletInputStream inputStream=req.getInputStream();
//将读取到的数据放入buffer的缓冲区
byte[] buffer =new byte[10244000]
int read=inputStream.read(new String(buffer,0,read))

}
}

(3)使用第三方封住好的jar包对收到的数据进行解析(这里使用apatch的commons-fileupload.jar和commons-io.jar进行解析);
导入两个jar包,添加到lib目录;

常用类

说明

ServletFileUpload类

用于解析上传的数据

boolean ServletFileUpLoad.isMultipartContent(HttpServletRequest request)

当前上传的格式是否是多段的格式;

public List[FileItem] parseRequest(HttpServletRequest request)

解析上传的数据

boolean FileItem.isFormField()

判断当前这个表单项,是否是普通表单项,还是上传的文件类型,true表示普通类型的表单项,false表示上传的文件类型;

String FileItem.getFieldName()

获取表单项的name属性值;

String FileItem.getString()

获取当前表单项的值;

String FileItem.getName()

获取上传的文件名

void FileItem.write(file)

将上传的文件写道参数file所指向的硬盘的位置;

public class UploadServlet extends HttpServlet{
@override
protected void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException{
//1、首先判断上传的数据是否是多段数据(只有是多段的数据,才是文件上传的)
if(ServletFileUpload.idMultipartContent(req)){
//创建FileItemFactory工厂实现类
FileItemFaactory fileItemFactory =new DiskFileItemFactory();
//创建用于解析上传数据的工具类
 ServletFileUpload servletFileUpload =new ServletFileUpload(fileItemFactory);
 //解析上传的数据,得到每一个表单项FileItem
 List<FileItem> list =servletFileUpload.parseRequest(req);
//循环判断,每一个表单项,是普通的类型,还是上传的文件
for(FileItem fileItem:list){
  if(fileItem.isFormField()){//普通表单项
  System.out.println("表单项的name属性值"+fileItem.getFieldName());
  //解决中文乱码问题
  System.out.println("表单项的value属性值"+fileItem.getString("UTF-8"));

}
   else{//上传的文件
   System.out.println("表单项的name属性值"+fileItem.getFieldName());
   System.out.println("上传的文件名"+fileItem.getName());
   //将文件进行写入
   fileItem.write(new File("e:\\"+fileItem.getName()));


}
	}


}

文件的下载:

protected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException{
//1.获取要下载的文件名
String downloadFileName="2.jpg";
//2.读取要下载的文件内容(通过servletcontext对象可以读取)
ServletContext servletcontext=getServletContext();
//获取要下载的文件类型
String mimeType =servletContext.getMimeType("文件路径"+downloadFileName)
//在回传前告诉客户端返回的数据类型
resp.setContentType(mimeType)
//告诉客户端收到的数据是用于下载的(使用响应头)
	//Content-Disposition响应头,表示收到的数据怎么处理
	//attachment表示附件,表示下载使用
	//filename表示指定下载的文件名
resp.setHeader("Content-Disposition","attachment;filename="+downloadFileName)
//获取文件的输入流
InputStream resourceAsStream=servletcontext.getResourceAsStream("文件路径"+downloadFileName);
//获取响应的输出流
OutputStream outputStream=resp.getOutputStream();
//读取流中的全部数据。输给客户端
IOUtils.copy(resourceAsStream,outputStream);
}

如果下载的文件名为中文,需要使用URLEncoder对文件名进行中文编码:
(针对于IE浏览器和谷歌浏览器)

resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode("中国.jpg","UTF-8"))

如果是火狐浏览器,则要采用Base64编码:

“attachment;filename==?UTF-8?B?”+new BASE64Encoder().encode("中国.jpg".getbytes("UTF-8"))+"?=")

通过请求头的User-Agent属性来根据不同的浏览器使用不同的编码:
if(req.getHeader("User-Agent").contains("Firefox")) 表示如果是火狐浏览器,则使用Base64编码;
其它情况就使用URLEncode进行UTF-8编码;