JavaWeb学习(19): 文件的上传和下载
饭前点心:
众所周知,在网页上进行上传和下载东西是我们最常见的操作。
上传文件步骤:
1、引入2个jar
apache: commons-fileupload.jar组件
commons-fileupload.jar依赖 commons-io.jar
2、前台jsp:
<input type="file" name="spicture"/>
表单提交方式必须为post
在表单中必须增加一个属性 entype="multipart/form-data"
3、后台Servlet
在代码中有详细的注释。
上传时应注意的问题:
上传的目录 upload :
1.如果修改代码,则在tomcat重新启动时 会被删除
原因:当修改代码的时候,tomcat会重新编译一份class 并且重新部署(重新创建各种目录)
2.如果不修改代码,则不会删除
原因: 没有修改代码,class仍然是之前的class
因此,为了防止 上传目录丢失: a.虚拟路径 b.直接更换上传目录 到非tomcat目录
下载文件步骤:
1、不需要依赖任何jar
2、步骤:
a.请求(地址a form),请求Servlet
b.Servlet通过文件的地址 将文件转为输入流 读到Servlet中
c.通过输出流 将 刚才已经转为输入流的文件 输出给用户
下载时应注意的问题:
下载文件 需要设置2个 响应头:
response.addHeader("content-Type","application/octet-stream" );//MIME类型:二进制文件(任意文件)
response.addHeader("content-Disposition","attachement;filename="+fileName );//fileName包含了文件后缀:abc.txt
下载时统一不同浏览器的编码:
未统一时:
统一后:
不同浏览器设置统一编码的方式有所不同,在代码中会有详细的解释。
Code:
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 上传文件 -->
<form action="UpAndDownServlet" method = "post" enctype="multipart/form-data">
学号: <input type = "text" name = "sno"> <br>
姓名: <input type = "text" name = "sname"> <br>
上传文件: <input type = "file" name = "spicture"> <br>
<input type = "submit" value = "上传"> <br>
</form>
<!-- 下载文件 -->
<a href="DownloadServlet?filename=MIME.png">MIME</a>
</body>
</html>
UpAndDownServlet.java(上传文件的 Servlet)
package org.rj.servlet;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/UpAndDownServlet")
public class UpAndDownServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 统一请求时编码
request.setCharacterEncoding("utf-8");
// 统一响应时编码
response.setCharacterEncoding("utf-8");
// 统一前台显示代码
response.setContentType("text/html; charset=UTF-8");
// 判断前台是否有 multipart/form-data 属性
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart) {
// FileItemFactory 是一个接口,需要通过实现类进行实现
FileItemFactory factory = new DiskFileItemFactory();
// 需要有参数,参数是一个 FileItemFactory 对象(这是个接口)
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// 通过parseRequest解析form中的所有请求字段,并保存到 items集合中(即前台传递的sno sname
// spicture此时就保存在了items中)
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
// 迭代器进行遍历
while(iter.hasNext()) {
// 获取当前信息(返回值是 FileItem)
FileItem item = iter.next();
String itemName = item.getFieldName();
if(item.isFormField()) {
if(itemName.equals("sno")) {
// int sno = Integer.parseInt(item.getString("utf-8"));
}else if(itemName.equals("sname")) {
// String name = item.getString("utf-8");
}else {
System.out.println("其他字段。。。");
}
} else {
// 获取文件名
String fileName = item.getName();
// 上传路径(一般是服务器路径,但是有缺点)
String path = request.getSession().getServletContext().getRealPath("upload");
File file = new File(path,fileName);
// 上传文件
item.write(file);
System.out.println("上传成功!");
return ;
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
DownloadServlet.java(下载文件的Servlet):
package org.rj.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.codec.binary.Base64;
/**
* Servlet implementation class DownloadServlet
*/
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//获取需要下载的文件名
String fileName = request.getParameter("filename") ;//form 、a href、 ...Server?a=b
//下载文件:需要设置 消息头
response.addHeader("content-Type","application/octet-stream" );//MIME类型:二进制文件(任意文件)
// response.addHeader("content-Disposition","attachment;filename="+fileName );//fileName包含了文件后缀:abc.txt
// edge浏览器 防止出现中文乱码
// response.addHeader("content-Disposition","attachment;filename="+URLEncoder.encode(fileName, "utf-8") );
// 火狐浏览器 防止出现中文乱码
response.addHeader("content-Disposition","attachment;filename==?UTF-8?B?"+ new String( Base64.encodeBase64(fileName.getBytes("UTF-8")) ) +"?=" );//fileName包含了文件后缀:abc.txt
//Servlet通过文件的地址 将文件转为输入流 读到Servlet中
InputStream in = getServletContext().getResourceAsStream("/res/图片.png") ;
//通过输出流 将 刚才已经转为输入流的文件 输出给用户
ServletOutputStream out = response.getOutputStream() ;
byte[] bs = new byte[10];
int len=-1 ;
while( (len=in.read(bs)) != -1) {
out.write(bs,0,len);
}
out.close();
in.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
图片资源:
后记:
关于文件传输所用到的 IO 流还不是太掌握,基础不是太扎实,看来还是要重新过一下基础部分。
这些代码要是自己在重新敲一遍的话可能有的地方会出错,重要的是先掌握方法。
如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。