response生成验证码
验证码的作用:防止恶意注册、攻击等
网站上看到的验证码,实际上都是一些图片,而这些图片都是程序(Servlet)生成的!
package day19.test;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("all")
public class CheckCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int width = 130, height = 39; // 图片宽度和高度
// 创建用于保存图片信息的缓冲区对象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics(); // 获取画笔
g.setColor(new Color(255, 255, 255)); // 设置画笔颜色
g.fillRect(0, 0, width, height); // 填充背景颜色
g.setColor(new Color(0, 0, 0)); // 重新设置画笔颜色
g.drawRect(0, 0, width - 1, height - 1); // 绘制边框
Random r = new Random(); // 创建随机数对象
// 添加干扰线
for (int i = 0; i < 15; i++) {
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); // 重新设置画笔颜色
g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
}
// 生成验证码的数据
String data = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789";
int length = data.length();
String capstr = "";
g.setFont(new Font("宋体", Font.BOLD, 35)); // 设置字体
for (int i = 0; i < 4; i++) {
int index = r.nextInt(length);
String str = data.charAt(index) + "";
capstr += str;
g.setColor(new Color(r.nextInt(200), r.nextInt(200), r.nextInt(200))); // 重新设置画笔颜色
g.drawString(str, 10 + (i * 28), 30); // 将字符写入图片
}
g.dispose(); // 释放资源
response.setContentType("image/jpg"); // 设置响应类型
OutputStream strm = response.getOutputStream(); // 输出流
ImageIO.write(image, "jpg", strm); // 将图片写到输出流
strm.close(); // 关闭输出流
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
文件下载
文件下载分为2种方式:
- 使用超链接方式直接下载:服务器自动将请求的资源以流的形式发送给浏览器,浏览器会自动识别并下载到本地
- Servlet方式下载:使用输入流读取文件,然后使用response获取输出流对象,将输入流中的数据响应到客户端
超链接方式
<a href="1.txt">1.txt</a><br/>
<a href="1.jpg">1.jpg</a><br/>
<a href="1.doc">1.doc</a><br/>
<a href="1.rar">1.rar</a><br/>
<a href="中文.rar">中文.rar</a><br/>
<a href="中 文 带 空 格.rar">中 文 带 空 格.rar</a>
问题:
- 如果下载的文件浏览器能够解析,则会自动显示处来,而不是我们要的下载
- 如果下载的资源中,有中文,则提示找不到文件
可以修改tomcat的配置conf/server.xml,编码方式改为UTF-8,不推荐使用
Servlet方式
Servlet代码
package web;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Encoder;
@SuppressWarnings("all")
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getParameter("filename");
// UTF-8浏览器编码 ----> ISO-8859-1服务器解码
byte[] bytes = filename.getBytes("ISO-8859-1");
filename = new String(bytes, "UTF-8");
// 获取当前项目在服务器中的真实路径
// servletContext表示当前的项目对象
ServletContext servletContext = request.getServletContext();
// D:\apache-tomcat-7.0.77\webapps\hei26_web10
//String appPath = servletContext.getRealPath("");
// D:\apache-tomcat-7.0.77\webapps\hei26_web10\
//String appPath2 = servletContext.getRealPath("/");
// D:\apache-tomcat-7.0.77\webapps\hei26_web10\+filename
String appPath3 = servletContext.getRealPath("/" + filename);
InputStream is = new FileInputStream(appPath3);
ServletOutputStream os = response.getOutputStream();
// 获取浏览器类型,通过请求头中的User-Agent来判断
String ua = request.getHeader("User-Agent");
boolean IE_LT11 = ua.contains("MSIE"); // IE11以下版本
boolean IE11 = ua.contains("rv:11.0) like Gecko"); // IE11
boolean Edge = ua.contains("Edge"); // win10自带的Edge浏览器
// 如果是微软的浏览器,直接进行UTF-8编码
if (IE_LT11 || IE11 || Edge) {
filename = URLEncoder.encode(filename, "UTF-8");
// java的编码方式和浏览器有略微的不同:对于空格,java编码后的结果是加号,
// 而浏览器的编码结果是%20,因此将+替换成%20, 这样浏览器才能正确解析空格
filename = filename.replace("+", "%20");
}
// 标准浏览器使用Base64编码
else {
BASE64Encoder encoder = new BASE64Encoder();
filename = encoder.encode(filename.getBytes("utf-8"));
// =?utf-8?B?文件名?= 是告诉浏览器以Base64进行解码
filename = "=?utf-8?B?" + filename + "?=";
}
// 告诉浏览器,不要解析文件,要以附件的形式下载
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
byte[] buf = new byte[1024];
int len = 0;
while ( ( len = is.read(buf) ) != -1 ) {
os.write(buf, 0, len);
}
is.close();
os.flush();
os.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
public static void main(String[] args) throws UnsupportedEncodingException {
String url = "AAhttp://127.0.0.1:8080/hei26_web10/download?filename=1.txtZZ";
BASE64Encoder encoder = new BASE64Encoder();
url = encoder.encode(url.getBytes("utf-8"));
System.out.println(url);
}
}
download.html
<!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>
<script type="text/javascript" src="jquery-1.8.3.js"></script>
<script type="text/javascript">
$(function() {
// 给超链接绑定单击事件:e:事件对象,可以获取左键还是右键?是按下了键盘上的哪个键?
$("div a").click(function(e) {
// 获取要下载的文件名
var href = $(this).attr("href");
// 将文件名赋给隐藏域:目的是为了利用表单的特性:提交时会对数据进行UTF-8编码
$("#filename").val(href);
// 提交表单:在事件方法中,如果指定函数,则表示事件绑定,如果没有参数,表示调用相应的事件
$("#dForm").submit();
// 元素的默认动作: 点击超链接会发生跳转、点击下拉框会展开选项、点击复选按钮会选中... 这些就是元素的默认动作
e.preventDefault(); // 阻止元素的默认动作
});
});
</script>
</head>
<body>
<div>
<a href="1.txt">1.txt</a><br/>
<a href="1.jpg">1.jpg</a><br/>
<a href="1.doc">1.doc</a><br/>
<a href="1.rar">1.rar</a><br/>
<a href="中文.rar">中文.rar</a><br/>
<a href="中 文 带 空 格.rar">中 文 带 空 格.rar</a>
</div>
<a href="thunder://QUFodHRwOi8vMTI3LjAuMC4xOjgwODAvaGVpMjZfd2ViMTAvZG93bmxvYWQ/ZmlsZW5hbWU9MS50
eHRaWg==">1.txt--迅雷下载</a>
<form id="dForm" action="/hei26_web10/download">
<input type="hidden" id="filename" name="filename" />
</form>
<!-- <a href="/hei26_web10/download?filename=1.txt">1.txt</a><br/>
<a href="/hei26_web10/download?filename=1.jpg">1.jpg</a><br/>
<a href="/hei26_web10/download?filename=1.doc">1.doc</a><br/>
<a href="/hei26_web10/download?filename=1.rar">1.rar</a><br/>
<a href="/hei26_web10/download?filename=中文.rar">中文.rar</a><br/>
<a href="/hei26_web10/download?filename=中 文 带 空 格.rar">中 文 带 空 格.rar</a> -->
</body>
</html>