1.文件的上传
介绍
- 要有一个form标签,method=post请求。
- form标签的encType属性值必须是multipart/form-data值。
- 在form标签中使用input type=file添加上传的文件。
- 编写服务器代码接收并处理上传的数据。
HTTP协议的说明
属性 | 说明 |
---|
Context-type | 表示提交的数据类型 |
multipart/form-data | 表示提交的数据,以多段的形式进行拼接,然后以二进制流的形式发送给服务器 |
boundary | 表示每段数据的分隔符 |
常用的类
- ServletFileUpload类————用于解析上传的数据。
- FileItem类————表示每一个表单项。
- boolean ServletFileUpload.isMultipartContext(HttpServletRequest request);————判断当前上传的数据格式是否是多段格式。
- public List parseRequest(HttpServletRequest request)————解析上传的数据。
- boolean FileItem.isFormField()————判断当前表单项是普通的表单项还是上传的数据类型,true表示普通类型的表单项,false表示上传的数据类型。
- String FileItem.getFieldName()————获取表单项的name属性值。
- String FileItem.getString()————获取表单项的值。
- String FileItem.getName()————获取上传的文件名。
- void FileItem.write(file)————将上传的文件写到参数file所指向的硬盘位置。
fileupload类库的使用
- 上传文件的表单:
<form action="http://localhost:8080/09_EL_JSTL/uploadServlet1" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br>
头像:<input type="file" name="photo"/><br>
<input type="submit" value="上传">
</form>
- 解析上传的数据的代码:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(req)){
FileItemFactory fileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
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("/Users/zhanglei/Desktop" + fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
2.文件的下载
常用的API说明
- response.getOutputStream()————获取响应的输出流
- servletContext.getResponseAsStream————读取下载的文件内容
- servletContext.getMimeType()————获取下载的文件类型
- response.setContextType()————在回传前通过响应头告诉客户端返回的数据类型
- response.serHeader(“Content-Disposition”,“attachment;fileName=1.jpg”);————告诉浏览器需要下载的文件。
- attachment表示下载的文件,即附件;
- fileName表示下载的文件名。
附件中文名乱码问题的解决方案
URLEncoder解决IE和谷歌浏览器的附件中文名乱码问题
- 因为IE和谷歌浏览器收到含有编码的字符串之后会以UTF-8字符集进行解码显示,所以我们需要使用URLEncoder类先对中文名进行UTF-8的编码操作。
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
resp.setHeader("Content-Disposition", str);
BASE64编解码解决火狐浏览器的附件中文名乱码问题
- 需要把请求头Content-Disposition:attachment;fileName=中文名编码成为:Content-Disposition:attachment;fileName==?charset?B?xxxxx?=。
String str = "attachment; fileName=" + "=?utf-8?B?"+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
resp.setHeader("Content-Disposition", str); }
解决两种不同的编解码方式
- 通过判断请求头中User-Agent这个请求头传递过来的浏览器信息就可以知道什么浏览器。
String ua = req.getHeader("User-Agent");
if (ua.contains("Firefox")) {
String str = "attachment; fileName=" + "=?utf-8?B?"+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
resp.setHeader("Content-Disposition", str); }
else {
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
resp.setHeader("Content-Disposition", str);
}
文件下载示例代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String downloadFileName = "1.jpg";
ServletContext servletContext = getServletContext();
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
ServletOutputStream outputStream = resp.getOutputStream();
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
System.out.println("下载的文件类型是:" + mimeType);
resp.setContentType("mimeType");
String ua = req.getHeader("User-Agent");
if (ua.contains("Firefox")) {
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
resp.setHeader("Content-Disposition", str); }
else {
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
resp.setHeader("Content-Disposition", str);
}
resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode("图片1.jpg", "UTF-8"));
IOUtils.copy(resourceAsStream, outputStream);
}
}