JSP入门教程(DOC格式)-第17部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
2。 了解设置 contentType 使 servlet 生成不同格式的文件。
12。1。 图片校验码
进入首页,会显示一个彩色图形验证码,用户根据图片上的文字输入文本框。
如果输入错误,会提示输入与图片文字不同,并更新验证码。
108 / 148
…………………………………………………………Page 109……………………………………………………………
输入正确会显示成功信息。
彩色验证码用来防止恶意程序自动发送垃圾消息,或者是恶意程序循环尝试登录
密码。人眼可以根据图片了解验证码的内容,但如果是程序就需要扫描图片分析
图片中的内容,为了加大程序分析破解的难度,我们还为图片准备了干扰用的背
景颜色,并随便修改文字的颜色。这些都是为了加大程序破解的难度。
现在所有的注意力都集中到如何动态生成校验用的图片,看一下 index。jsp 中的
代码。
大家可能感到奇怪了,这里 img 标签对应的是一个静态 jpg 图片,为什么每次刷
新显示的图片内容都不同呢?仔细检查 12…01 目录下我们也看不到captcha。jpg
这个图片,这个图片到底是从哪里得到的呢?
如我们之前所谈到的第 3。4。2 节 “forward 导致找不到图片”,在 html 里包
含的图片,css 样式表,js 脚本,视频等等外部资源,都需要浏览器再次向服务
器发起请求。现在我们进行的请求是一个名叫 captcha。jpg 的图片,而服务器上
并没有这个图片,从 web。xml 里的配置可以看到如下配置。
CaptchaServlet
anni。CaptchaServlet
CaptchaServlet
/captcha。jpg
在这里,名叫/captcha。jpg 的请求会交给CaptchaServlet 处理。虽然这个请求
看起来很像一个实际存在的文件,可服务器接收到这个请求之后并没有去磁盘上
找这个文件,而是根据 web。xml 中配置把request 发送给 CaptchaServlet 并等
待它做出响应。
109 / 148
…………………………………………………………Page 110……………………………………………………………
请大家注意,jsp 和 servlet 并不是只能返回 html 格式的数据,实际上它们可
以生成任意格式的数据,比如这里我们就用 servlet 生成了一个图片。正如我们
之前讨论 forward 时提到的,第 3。4。2 节 “forward 导致找不到图片”,浏览
器只是向服务器发送了一个请求,这个请求的地址是/captcha。jpg 还是
/index。jsp 并没有什么区别,在服务器看来他们仅仅是一个字符串而已,接收
到请求后服务器先去按照 web。xml 中的配置做映射,将请求交给对应的 servlet
处理,如果 web。xml 中没有对应这个请求的映射,才会去磁盘查找是否有这么一
个文件,找到文件则输出到响应中传回客户端,如果找不到就返回经典的 404(找
不到访问资源)。
其实我们使用的/check。do 也是一样的道理,你在服务器上找不到名叫 check。do
的文件,它只是一个指向CheckServlet 的道标,告诉服务器调用CheckServlet
处理这个请求,请记住,这些仅仅是请求,你永远不知道服务器会返回给你什么。
代码请大家参考 12…01/WEB…INF/src/CaptchaServlet。java,因为 img 只可能通
过 GET 方式发送请求,所以我们仅仅定义了 doGet()方法。
public void doGet(HttpServletRequest request; HttpServletResponse
response)
throws ServletException; IOException {
//设置页面不缓存
response。setHeader(〃Pragma〃; 〃No…cache〃);
response。setHeader(〃Cache…Control〃; 〃no…cache〃);
response。setDateHeader(〃Expires〃; 0);
// 在内存中创建图象
int width = 60; height = 20;
BufferedImage image = new BufferedImage(width; height;
BufferedImage。TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image。getGraphics();
//生成随机类
Random random = new Random();
// 设定背景色
g。setColor(getRandColor(200; 250));
g。fillRect(0; 0; width; height);
//设定字体
g。setFont(new Font(〃Times New Roman〃; Font。PLAIN; 18));
110 / 148
…………………………………………………………Page 111……………………………………………………………
//画边框
//g。setColor(new Color());
//g。drawRect(0; 0; width 1; height 1);
// 随机产生 155条干扰线,使图象中的认证码不易被其它程序探测到
g。setColor(getRandColor(160; 200));
for (int i = 0; i 《 155; i++) {
int x = random。nextInt(width);
int y = random。nextInt(height);
int xl = random。nextInt(12);
int yl = random。nextInt(12);
g。drawLine(x;y;x+xl;y+yl);
}
// 取随机产生的认证码 (4位数字)
String sRand = 〃〃 ;
for (int i = 0;i 《 4; i++) {
String rand = String。valueOf(random。nextInt(10));
sRand += rand;
// 将认证码显示到图象中
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接
生成
g。setColor(new Color(20 + random。nextInt(110); 20 +
random。nextInt(110); 20 + random。nextInt(110)));
g。drawString(rand; 13 * i + 6; 16);
}
// 将认证码存入 SESSION
request。getSession()。setAttribute(〃captcha〃; sRand);
// 图象生效
g。dispose();
// 输出图象到页面
ImageIO。write(image; 〃JPEG〃; response。getOutputStream());
}
代码最先设置 response (响应)中的头部配置,告诉浏览器不要缓存对
/captcha。jpg 的请求结果,这样才能保证每次刷新页面都看到最新生成的图片,
要是设置了缓存很可能每次看到的都是最先请求看到的图片。
中间一大段代码实现动态生成图片的功能,我们先随机获得几个数字,然后写到
BufferedImage 中,最后就可以把图片数据写到response,因为图片是二进制数
111 / 148
…………………………………………………………Page 112……………………………………………………………
据,所以我们使用了 response。getOutputStream()而不是
response。getWriter()。
为了达到验证的功能,每次生成图片之后要记得讲随机得到的数字保存到
session 中,session 中的变量可以跨越多个请求周期存在,等用户输入验证码
提交后就能与 session 中的数据做比较了,这些是在CheckServlet 中实现的。
public void doPost(HttpServletRequest request; HttpServletResponse
response)
throws ServletException; IOException {
HttpSession session = request。getSession();
String requestCaptcha = request。getParameter(〃captcha〃);
String sessionCaptcha = (String) session。getAttribute(〃captcha〃);
if (sessionCaptcha != null &&
sessionCaptcha。equals(requestCaptcha)) {
session。removeAttribute(〃captcha〃);
request。getRequestDispatcher(〃/success。jsp〃)。forward(request;
response);
} else {
request。setAttribute(〃message〃; 〃验证码输入错误〃);
request。getRequestDispatcher(〃/index。jsp〃)。forward(request;
response);
}
}
这样我们便获得了彩色图性校验码的功能,例子在 12…01 目录下。
12。2。 图片校验码 jsp 版
使用 servlet 既需要编译源代码,又要在web。xml 加入对应的请求映射。如果只
是需要简单的验证码功能,我们也可以使用 jsp 实现。
我们已经知道 jsp 就是 servlet 的另一种形式,servlet 能做的事情 jsp 也可以
实现,下面就是实现 CaptchaServlet 功能的 captcha。jsp。
255) {
fc = 255;
}
if (bc 》 255) {
bc = 255;
}
int r = fc + random。nextInt(bc fc);
int g = fc + random。nextInt(bc fc);
int b = fc + random。nextInt(bc fc);
return new Color(r; g; b);
}
%》
captcha。jsp 中的代码与 servlet 基本相同,不过需要注意两点。