一.下载
需求: 1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
分析:1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。
--- - 图片是可以直接被解析的,不能弹出下载提示框,但是视频不能被解析。
2. 任何资源都必须弹出下载提示框
3. 使用响应头设置资源的打开方式: content-disposition:attachment;filename=xxx ---- 所有资源都以附件的形式打开
步骤: 1. 定义页面,编辑超链接href属性,指向Servlet,传递资源参数名称filename --- 指定下载资源的形式, 是图片还 是视频 .
2. 定义Servlet:
(1) 获取文件名称
(2)使用字节输入流加载文件进内存 --- 需要获取真实路径
(3) 指定response的响应头: content-disposition:attachment;filename=xxx
(4) 将数据写出到response输出流
问题:中文文件问题 解决思路:
(1) 获取客户端使用的浏览器版本信息
(2) 根据不同的版本信息,响应不同类型的数据 ---- 设置filename不同的编码方式
Download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/Demo5/img/2.jpg">图片</a>
<a href="/Demo5/DownloadServlet?filename=2.jpg">图片下载</a>
</body>
</html>
DownloadServlet.java
package com.hbsi.servlet;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletContext;
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;
/**
* Servlet implementation class DownloadServlet
*/
/*
* 常见的响应头: Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
* Content-disposition:服务器告诉客户端以什么格式打开响应体数据 值: in-line:默认值,在当前页面内打开
* attachment;filename=xxx:以附件形式打开响应体。文件下载
*/
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public DownloadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
String fileName = request.getParameter("filename");
System.out.println(fileName);
//获取Servlet容器对象
ServletContext context = request.getServletContext();
String realpath = context.getRealPath("/img/" + fileName);
FileInputStream in = new FileInputStream(realpath);
System.out.println(realpath);
// 获取文件mime类型 设置响应头
String miMeType = context.getMimeType(fileName);
response.setHeader("content-type", miMeType);
// 获取浏览器名称
String agent = request.getHeader("user-agent");
// 根据不同的浏览器对文件名进行编码
fileName = DownLoadUtils.getFileName(agent, fileName);
// 用字节输入流读取文件
// 设置浏览器以什么格式打开响应体数据
// attachment;filename=xxx:以附件形式打开响应体。文件下载
response.setHeader("content-disposition", "attachment;filename=" + fileName);
OutputStream out = response.getOutputStream();
int length = 0;
byte[] buff = new byte[1024 * 8];
while ((length = in.read(buff)) != -1) {
out.write(buff, 0, length);
}
in.close();
}
}
解决中文文件名称DownLoadUtils.java
package com.hbsi.servlet;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import sun.misc.BASE64Encoder;
public class DownLoadUtils {
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
效果图
二、上传
(1)文件上传的需要的jar包,要注意根据需求下载相应的版本,此处奉上我用的jar包
commons-fileupload-1.3.jar commons-io-1.3.2.jar
链接:https://pan.baidu.com/s/1HGCQBy7KD8ap03enkuxgkQ
提取码:grxa
(2)在webContent新建一个upload文件夹,用于存放上传到服务器的文件
fileUpload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传文件</title>
</head>
<body>
<!-- 文件上传表单的提交方式必须是“post” 编码类型必须为:enctype="multipart/form-data" -->
<form action="/Demo5/UploadServlet" method="post" enctype="multipart/form-data">
file1:<input type="file" name="fileName1"><br>
file2:<input type="file" name="fileName2"><br>
<input type="submit" value="上传"><br>
<input type="reset" value="重置"><br>
</form>
</body>
</html>
UploadServlet.java
package com.hbsi.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UploadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// //得到上传文件的保存目录,将上传的文件放在webRoot目录下(但是一般为了安全放在WEB-INF目录下,不允许外界直接访问,保证上传的安全)
String path = this.getServletContext().getRealPath("/upload");
//文件目录的实例
File file = new File(path);
//判断上传文件的保存目录是否存在
if(!file.exists()&&!file.isDirectory()){
System.out.println(path="目录不存在,需要创建");
file.mkdir();
}
//消息提示
String message="";
try {
//使用apache文件上传组件处理文件上传步骤
//1.创建一个DiskFileItemFactory工厂 (磁盘文件項工厂)
DiskFileItemFactory factory = new DiskFileItemFactory();
//2创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
//3.使用ServletFileUpload 解析器解析上传数据,解析结果返回一个List<FileIiftem>集合
//每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list){
if(item.isFormField()){
//是否是普通表单域,按照传统方式上传
String name = item.getFieldName();
String value = item.getString("UTF-8");
System.out.println(name+" "+value);
}else{
//获取上传文件名称
String fileName = item.getName();
System.out.println(fileName);
if(fileName==null||fileName.trim().equals(" ")){
continue;
}
//去掉文件名中的路径名 保留单纯的文件名 D:\\poject\Webroot\hello.jsp
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
//获取Item中上传文件的输入流
InputStream in = item.getInputStream();
//输出流
OutputStream out = new FileOutputStream(path+"\\" + fileName);
System.out.println(path+"\\" + fileName);
//创建一个缓冲区
byte buffer[] = new byte[1024];
int len =0;
while((len = in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
//删除处理文件上传生成的临时文件
item.delete();
message="文件上传成功";
System.out.println(message);
}
}
} catch (Exception e) {
// TODO: handle exception
message="文件上传失败";
System.out.println(message);
e.printStackTrace();
}
}
}
效果图
总结:下载时,要从服务器读取下载的文件 FileInputStream in = new FileInputStream(realpath);
上传时,要把文件写入到服务器 OutputStream out = new FileOutputStream(path+"\\" + fileName);