文件下载需求:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
1.新建一个JAVA EE项目,配置tomcat相关设置。新建一个download.html,就是客户端访问的界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<!--文件下载需求:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
<a href="/Download/img/1.jpg">图片1</a>
-->
<body>
<a href="/Download/downloadServlet?filename=1.jpg">图片1</a>
<a href="/Download/downloadServlet?filename=九尾.jpg">图片2</a>
</body>
</html>
这里注释中的<a href="/Download/img/1.jpg">图片1</a>这个超链接,浏览器会直接将1.jpg给解析到浏览器中,就不会出现附件保存形式,所以我们这里需要创建一个新的servlet来以附件保存的形式来保存图片。
2.新建一个downloadServlet,实现以附件形式保存图片的功能。分位以下几步:
1.通过getParameter方法来获取文件名称(图片文件)
2.要把这个文件通过字节输入流加入到内存,但是出现问题,必须要找到文件所在的真实路径。所以这里通过一系列操作获得到真实路径。然后把这个文件通过字节输入流加入到内存
3.设置response响应头 主要是需要设置两个,一个是响应头类型:content-type,另一个是响应头打开类型(附件):content-disposition
4.将输入流数据写到输出流(下载)
tips:后续通过工具包,解决如果图片是中文名字的乱码问题。
package Download;
import utils.DownLoadUtils;
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;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* 1. 获取文件名称
2. 使用字节输入流加载文件进内存
3. 指定response的响应头: content-disposition:attachment;filename=xxx
4. 将数据写出到response输出流
*/
String filename = request.getParameter("filename");//根据参数名称获取参数值
//如何理解getServletContext()方法:
//一个servlet可以使用getservletcontext()方法得到了web应用中的servletcontext,从而使用servletcontext接口的一些方法
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);//获取文件的真实(服务器)路径
FileInputStream fis = new FileInputStream(realPath);//用字节流关联
//设置response响应头 主要是需要设置两个,一个是响应头类型:content-type,另一个是响应头打开类型(附件):content-disposition
String mimeType = servletContext.getMimeType(filename);
response.setHeader("content-type",mimeType);
//*************************
//解决中文命名的文件名乱码问题
//1.获取请求头user-agent
String agent = request.getHeader("user-agent");
//2.使用我们下载的工具类方法去编码文件名
filename = DownLoadUtils.getFileName(agent,filename);
response.setHeader("content-disposition","attachment;filename = "+filename);
//将输入流数据写到输出流
int len = 0;
byte[] buff = new byte[1024*8];
ServletOutputStream sos = response.getOutputStream();
while ((len = fis.read(buff)) != -1){//等于-1相当于读完了
sos.write(buff,0,len);
}
fis.close();//输入流关掉,这里输出流在服务器不需要关了
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
贴一下工具包:网上很多,其实就是一个编码和解码的过程。
package utils;
//import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
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;
}
}
验证码程序(servlet):
package Download;
import javax.imageio.ImageIO;
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 java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/checkcodeServlet")
public class CheckcodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
//1.创建一对象,在内存中图片(验证码图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//2.美化图片
//2.1 填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,0,width,height);
//2.2画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width - 1,height - 1);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
//生成随机角标
Random ran = new Random();
for (int i = 1; i <= 4; i++) {//生成4个验证码
int index = ran.nextInt(str.length());
//获取字符
char ch = str.charAt(index);//随机字符
//2.3写验证码
g.drawString(ch+"",width/5*i,height/2);
}
//2.4画干扰线
g.setColor(Color.GREEN);
//随机生成坐标点
for (int i = 0; i < 10; i++) {
int x1 = ran.nextInt(width);
int x2 = ran.nextInt(width);
int y1 = ran.nextInt(height);
int y2 = ran.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//3.将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}