上传
一、开发环境搭建
创建一个Upload项目,加入Apache的commons-fileupload文件上传组件的相关Jar包,如下图所示:
二、实现文件上传
index.jsp提交表单信息
index.jsp
<form action="UploadServlet" method="post" enctype="multipart/form-data">
学号:<input type="text" name="snum"><br>
姓名:<input type="text" name="sname"><br>
照片:<input type="file" name="spicture"><br>
<input type="submit" value="上传">
<a href="DownLoadServlet?filename=图片.jpg">图片</a>
</form>
UploadServlet接收处理前端信息:
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//用于检测是否满足一个文件上传的请求 是为true 否为false
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
//文件上传的步骤
//1、创建一个DiskFileItemFactory工厂
FileItemFactory factory = new DiskFileItemFactory();
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//3、判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(request)){
return;
}
try{
//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,
// 每一个FileItem对应一个Form表单的输入项
List<FileItem> items = upload.parseRequest(request);
//5、使用迭代器遍历List集合
Iterator<FileItem> iter = items.iterator();
int snum = -1;
String sname = null;
while(iter.hasNext()){
FileItem item = iter.next();
if(item.getFieldName().equals("snum")){
snum = Integer.parseInt(item.getString());
System.out.println(snum);
}else if(item.getFieldName().equals("sname")){
sname = item.getString("UTF-8");
System.out.println(sname);
}else {
//6、如果fileitem中封装的是上传文件,得到上传的文件名称
String fileName = item.getName();
//7、获取文件后缀,限制上传文件的类型
String ext = fileName.substring(fileName.indexOf(".")+1);
if(!(ext.equals("png")||ext.equals("jpg")||ext.equals("gif")))
{
System.out.println("上传类型有误");
return;
}
//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
String path = this.getServletContext().getRealPath("/WEB-INF/upload");
File file = new File(path,fileName);
//判断上传文件的保存目录是否存在
if (!file.exists() && !file.isDirectory()) {
System.out.println(path+"目录不存在,需要创建");
//创建目录
file.mkdir();
}
try{
item.write(file);
}catch (Exception e){
e.printStackTrace();
}
}
}
}catch (FileUploadException e){
e.printStackTrace();
}
}
System.out.println("上传成功");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
三、文件上传的细节问题
- 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
- 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。
- 要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
下载
一、超链接下载
在jsp中定义超链接,用户点击超链接后自动下载
<form action="UploadServlet" method="post" enctype="multipart/form-data">
学号:<input type="text" name="snum"><br>
姓名:<input type="text" name="sname"><br>
照片:<input type="file" name="spicture"><br>
<input type="submit" value="上传">
<a href="DownLoadServlet?filename=图片.jpg">图片</a>
</form>
二、实现文件下载
public class DownLoadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//获取超链接中要下载的文件名
String fileName = request.getParameter("filename");
//下载文件需要设置消息头
response.addHeader("content-Type","application/octet-stream");
response.addHeader("content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));
//Servlet通过文件的地址将文件转化为输入流读入Servlet
InputStream inputStream = getServletContext().getResourceAsStream("/res/图片.jpg");
//通过输出流将刚才输入流的文件传输给用户
OutputStream outputStream = response.getOutputStream();
//创建缓冲区
byte[] bs = new byte[10];
int len = -1;
//循环将输入流中的内容读取到缓冲区当中
while((len = inputStream.read(bs))!=-1){
//输出缓冲区的内容到浏览器,实现文件下载
outputStream.write(bs,0,len);
}
outputStream.close();
inputStream.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}