目录
- 开篇
- 文件的上传
- 文件的下载:
开篇
文件的上传与下载是非常常见的功能,很多的系统中,或者软件中都经常使用文件的上传和下载;
文件的上传
文件上传的步骤
- 首先要有一个form标签,method=post请求
- form标签的encTyppe属性值必须为multipart/form-data值
- 在form标签中使用input type=file添加上传的文件
- 编写服务器代码(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编码;