为了提高网站的安全性,或者软件的安全性,现在再输入用户名和密码进行网站或者软件登陆的时候,如果输错一次就会出现输入验证码这一项,主要是为了保护账号不被暴力破解。这里我简单实现一下验证码。 使用Servlet生成验证码部分是摘自javaeye,有现成的代码直接使用就好了。不过前台这块纠结了半天,本来是打算用js对输入的验证码进行判断结果发现实现不了。最后只能写jsp脚本实现了。 首先是Servlet代码:SimpleCaptchaServlet.java:
package com.web;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.*;
/**
* 生成验证码的Servlet
* @author 胡阳
* 注:该代码参考自javaeye
*
*/
public class SimpleCaptchaServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
{
res.setContentType("image/jpeg");
res.setHeader("Pragma","No-cache");
res.setHeader("Cache-Control","no-cache");
res.setDateHeader("Expires", 0);
HttpSession session = req.getSession(true);
// 在内存中创建图象
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));
// 随机产生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
session.setAttribute("VerifyCode",sRand);
// 图象生效
g.dispose();
// 输出图象到页面
ImageIO.write(image, "JPEG", res.getOutputStream());
//JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(res.getOutputStream());
//encoder.encode(image);
}
public void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
{
doGet(req,res);
}
//给定范围获得随机颜色
private Color getRandColor(int fc,int bc)
{
Random random = new Random();
if(fc>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);
}
}
然后配置xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>SimpleCaptchaServlet</servlet-name>
<servlet-class>com.web.SimpleCaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SimpleCaptchaServlet</servlet-name>
<url-pattern>/servlet/SimpleCaptchaServlet</url-pattern>
</servlet-mapping>
</web-app>
最后index.jsp页面:
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%
String verifyCode = (String)session.getAttribute("VerifyCode");
String command = request.getParameter("command");
String anthCode = request.getParameter("authCode");
if ("ok".equalsIgnoreCase(command)) {
if (anthCode != null && anthCode.equalsIgnoreCase(verifyCode)) {
out.print("测试成功!");
} else{
out.println("验证码错误!");
}
}
%>
<!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=GB18030">
<title>Insert title here</title>
<script language=JavaScript>
function change(field) {
/*采用ajax的话可以使用这个代码,另外还需要从服务器端得到当前验证码
var timenow = new Date().getTime();
field.src="servlet/SimpleCaptchaServlet?d=" + timenow;
*/
document.URL=location.href;
}
</script>
</head>
<body>
<form action="index.jsp">
<input type="hidden" name="command" value="ok">
<input id="authCode" name="authCode" type="text" size="6" maxlength="4">
<img src="servlet/SimpleCaptchaServlet" alt="验证码" onClick="change(this);">
<input name="ok" type="submit" value="确定">
</form>
</body>
</html>
比较简单。
—EOF—