最近突然想温习下Jquery技术,如是我就想到不如通过jquery来实现下验证码的功能,如是,我结合在网上查的资料,总结出了一些知识点,通过碰到问题解决问题来学习进步。
项目结构:
实现英文+数字验证码
http://localhost:8080/jqueryStudy/login/vertyCode.jsp、
http://localhost:8080/jqueryStudy/login/login.html
实现中文验证码
http://localhost:8080/jqueryStudy/login/loginVerfy.jsp
上面是做出来的效果
具体源代码如下:
VerifyCodeServlet.java
public class VerifyCodeServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
// 验证码图片的宽度。
private int width = 105;
// 验证码图片的高度。
private int height = 60;
// 验证码字符个数
private int codeCount = 4;
private int x = 0;
// 字体高度
private int fontHeight;//控制验证码的大小
private int codeY;//控制生成的验证码显示的位置
char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
/** * 初始化验证图片属性 */
public void init() throws ServletException {
// 从web.xml中获取初始信息
// 宽度
String strWidth = this.getInitParameter("width");
// 高度
String strHeight = this.getInitParameter("height");
// 字符个数
String strCodeCount = this.getInitParameter("codeCount");
// 将配置的信息转换成数值
try {
if (strWidth != null && strWidth.length() != 0) {
width = Integer.parseInt(strWidth);
}
if (strHeight != null && strHeight.length() != 0) {
height = Integer.parseInt(strHeight);
}
if (strCodeCount != null && strCodeCount.length() != 0) {
codeCount = Integer.parseInt(strCodeCount);
}
} catch (NumberFormatException e) {
}
x = width / (codeCount + 3);
fontHeight = height - 15;
codeY = height - 10;
}
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, java.io.IOException {
// 定义图像buffer
BufferedImage buffImg = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
// 创建一个随机数生成器类
Random random = new Random();
// 将图像填充为白色
g.setColor(Color.gray);
g.fillRect(0, 0, width, height);
// 创建字体,字体的大小应该根据图片的高度来定。
Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
// 设置字体。
g.setFont(font);
// 画边框。
g.setColor(Color.BLACK);
g.drawRect(0, 0, width - 1, height - 1);
// 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。
g.setColor(Color.BLACK);
for (int i = 0; i < 160; 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);
}
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
StringBuffer randomCode = new StringBuffer();
int red = 0, green = 0, blue = 0;
// 随机产生codeCount数字的验证码。
for (int i = 0; i < codeCount; i++) {
// 得到随机产生的验证码数字。
String strRand = String.valueOf(codeSequence[random.nextInt(36)]);
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 用随机产生的颜色将验证码绘制到图像中。
g.setColor(new Color(red, green, blue));
g.drawString(strRand, (i + 1) * x, codeY);
// 将产生的四个随机数组合在一起。
randomCode.append(strRand);
}
// 将四位数字的验证码保存到Session中。
HttpSession session = req.getSession();
session.setAttribute("validateCode", randomCode.toString());
// 禁止图像缓存。 resp.setHeader("Pragma", "no-cache");
resp.setHeader("Cache-Control", "no-cache");
resp.setDateHeader("Expires", 0);
resp.setContentType("image/jpeg");
// 将图像输出到Servlet输出流中。
ServletOutputStream sos = resp.getOutputStream();
ImageIO.write(buffImg, "jpeg", sos);
sos.close();
}
}
VerifyCodeChinaServlet.java
public class VerifyCodeChinaServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
execute(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
execute(request, response);
}
public void execute(HttpServletRequest request,HttpServletResponse response)throws
ServletException,IOException{
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setContentType("image/jpeg");
response.setDateHeader("Expires", 0);
// 设置图片的长宽
int width = 100, height = 30;
// 设置备选汉字,剔除一些不雅的汉字
//现实中文或者英文
//String base = "/u7684/u4e00/u4e86/u662f/u6211/u4e0d/u5728/u4eba/u4eec/u6709/u6765/u4ed6/u8fd9/u4e0a/u7740/u4e2a/u5730/u5230/u5927/u91cc/u8bf4/u5c31/u53bb/u5b50/u5f97/u4e5f/u548c/u90a3/u8981/u4e0b/u770b/u5929/u65f6/u8fc7/u51fa/u5c0f/u4e48/u8d77/u4f60/u90fd/u628a/u597d/u8fd8/u591a/u6ca1/u4e3a/u53c8/u53ef/u5bb6/u5b66/u53ea/u4ee5/u4e3b/u4f1a/u6837/u5e74/u60f3/u751f/u540c/u8001/u4e2d/u5341/u4ece/u81ea/u9762/u524d/u5934/u9053/u5b83/u540e/u7136/u8d70/u5f88/u50cf/u89c1/u4e24/u7528/u5979/u56fd/u52a8/u8fdb/u6210/u56de/u4ec0/u8fb9/u4f5c/u5bf9/u5f00/u800c/u5df1/u4e9b/u73b0/u5c71/u6c11/u5019/u7ecf/u53d1/u5de5/u5411/u4e8b/u547d/u7ed9/u957f/u6c34/u51e0/u4e49/u4e09/u58f0/u4e8e/u9ad8/u624b/u77e5/u7406/u773c/u5fd7/u70b9/u5fc3/u6218/u4e8c/u95ee/u4f46/u8eab/u65b9/u5b9e/u5403/u505a/u53eb/u5f53/u4f4f/u542c/u9769/u6253/u5462/u771f/u5168/u624d/u56db/u5df2/u6240/u654c/u4e4b/u6700/u5149/u4ea7/u60c5/u8def/u5206/u603b/u6761/u767d/u8bdd/u4e1c/u5e2d/u6b21/u4eb2/u5982/u88ab/u82b1/u53e3/u653e/u513f/u5e38/u6c14/u4e94/u7b2c/u4f7f/u5199/u519b/u5427/u6587/u8fd0/u518d/u679c/u600e/u5b9a/u8bb8/u5feb/u660e/u884c/u56e0/u522b/u98de/u5916/u6811/u7269/u6d3b/u90e8/u95e8/u65e0/u5f80/u8239/u671b/u65b0/u5e26/u961f/u5148/u529b/u5b8c/u5374/u7ad9/u4ee3/u5458/u673a/u66f4/u4e5d/u60a8/u6bcf/u98ce/u7ea7/u8ddf/u7b11/u554a/u5b69/u4e07/u5c11/u76f4/u610f/u591c/u6bd4/u9636/u8fde/u8f66/u91cd/u4fbf/u6597/u9a6c/u54ea/u5316/u592a/u6307/u53d8/u793e/u4f3c/u58eb/u8005/u5e72/u77f3/u6ee1/u65e5/u51b3/u767e/u539f/u62ff/u7fa4/u7a76/u5404/u516d/u672c/u601d/u89e3/u7acb/u6cb3/u6751/u516b/u96be/u65e9/u8bba/u5417/u6839/u5171/u8ba9/u76f8/u7814/u4eca/u5176/u4e66/u5750/u63a5/u5e94/u5173/u4fe1/u89c9/u6b65/u53cd/u5904/u8bb0/u5c06/u5343/u627e/u4e89/u9886/u6216/u5e08/u7ed3/u5757/u8dd1/u8c01/u8349/u8d8a/u5b57/u52a0/u811a/u7d27/u7231/u7b49/u4e60/u9635/u6015/u6708/u9752/u534a/u706b/u6cd5/u9898/u5efa/u8d76/u4f4d/u5531/u6d77/u4e03/u5973/u4efb/u4ef6/u611f/u51c6/u5f20/u56e2/u5c4b/u79bb/u8272/u8138/u7247/u79d1/u5012/u775b/u5229/u4e16/u521a/u4e14/u7531/u9001/u5207/u661f/u5bfc/u665a/u8868/u591f/u6574/u8ba4/u54cd/u96ea/u6d41/u672a/u573a/u8be5/u5e76/u5e95/u6df1/u523b/u5e73/u4f1f/u5fd9/u63d0/u786e/u8fd1/u4eae/u8f7b/u8bb2/u519c/u53e4/u9ed1/u544a/u754c/u62c9/u540d/u5440/u571f/u6e05/u9633/u7167/u529e/u53f2/u6539/u5386/u8f6c/u753b/u9020/u5634/u6b64/u6cbb/u5317/u5fc5/u670d/u96e8/u7a7f/u5185/u8bc6/u9a8c/u4f20/u4e1a/u83dc/u722c/u7761/u5174/u5f62/u91cf/u54b1/u89c2/u82e6/u4f53/u4f17/u901a/u51b2/u5408/u7834/u53cb/u5ea6/u672f/u996d/u516c/u65c1/u623f/u6781/u5357/u67aa/u8bfb/u6c99/u5c81/u7ebf/u91ce/u575a/u7a7a/u6536/u7b97/u81f3/u653f/u57ce/u52b3/u843d/u94b1/u7279/u56f4/u5f1f/u80dc/u6559/u70ed/u5c55/u5305/u6b4c/u7c7b/u6e10/u5f3a/u6570/u4e61/u547c/u6027/u97f3/u7b54/u54e5/u9645/u65e7/u795e/u5ea7/u7ae0/u5e2e/u5566/u53d7/u7cfb/u4ee4/u8df3/u975e/u4f55/u725b/u53d6/u5165/u5cb8/u6562/u6389/u5ffd/u79cd/u88c5/u9876/u6025/u6797/u505c/u606f/u53e5/u533a/u8863/u822c/u62a5/u53f6/u538b/u6162/u53d4/u80cc/u7ec6";
String base = "我是中过人哦苏明清如果还有明天我愿意嫁给你";
// 备选汉字的长度
int length = base.length();
// 创建内存图像
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
// 创建随机类的实例
Random random = new Random();
// 设定图像背景色(因为是做背景,所以偏淡)
g.setColor(getRandColor(random, 200, 250));
g.fillRect(0, 0, width, height);
// 备选字体
String[] fontTypes = { "/u5b8b/u4f53", "/u65b0/u5b8b/u4f53", "/u9ed1/u4f53", "/u6977/u4f53", "/u96b6/u4e66" };
int fontTypesLength = fontTypes.length;
// 在图片背景上增加噪点
g.setColor(getRandColor(random, 160, 200));
g.setFont(new Font("Times New Roman", Font.ITALIC, 18));
for(int i=1;i<160;i++)
{
int x=random.nextInt(width);
int y=random.nextInt(height);
int x1=random.nextInt(5);
int y1=random.nextInt(5);
g.drawLine(x, y, x+x1,y+y1);
}
// 取随机产生的认证码(6个汉字)
// 保存生成的汉字字符串
String sRand = "";
for (int i = 0; i < 4; i++)
{
int start = random.nextInt(length);
String rand = base.substring(start, start + 1);
sRand += rand;
// 设置字体的颜色
g.setColor(getRandColor(random, 10, 150));
// 设置字体
g.setFont(new Font(fontTypes[random.nextInt(fontTypesLength)], Font.BOLD, 15 + random.nextInt(6)));
// 将此汉字画到图片上
g.drawString(rand, 20 * i + 10 + random.nextInt(8),15+random.nextInt(15));
}
System.out.println(sRand.trim());
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
// 将认证码存入session
request.getSession().setAttribute("validateCode", sRand);
g.dispose();
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(image, "jpeg", sos);
sos.close();
}
public void init() throws ServletException {
}
//在此处 获取并生成随机颜色
Color getRandColor(Random random, int ff, int cc) {
if (ff > 255)
ff = 255;
if (cc > 255)
cc = 255;
int r = ff + random.nextInt(cc - ff);
int g = ff + random.nextInt(cc - ff);
int b = ff + random.nextInt(cc - ff);
return new Color(r, g, b);
}
}
ResultServlet.java
public class ResultServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String validateC = (String) request.getSession().getAttribute("validateCode");
String veryCode = new String(request.getParameter("c").getBytes("iso-8859-1"), "UTF-8"); //可以解决中文乱码
PrintWriter out = response.getWriter();
if(veryCode==null||"".equals(veryCode)){
out.println("验证码为空");
}else{
if(validateC.equals(veryCode)){
out.println("验证码正确");
}else{
out.println("验证码错误");
}
}
out.flush();
out.close();
}
}
verifyCode.js
function changeImg(){
var imgSrc = $("#imgObj");
var src = imgSrc.attr("src");
alert(src);
imgSrc.attr("src",chgUrl(src));
}
//时间戳
//为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
function chgUrl(url){
var timestamp = (new Date()).valueOf();
url = url.substring(0,20);
if((url.indexOf("&")>=0)){
url = url + "×tamp=" + timestamp;
}else{
url = url + "?timestamp=" + timestamp;
}
return url;
}
function changeImg1(){
var imgSrc = $("#imgObj");
var src = imgSrc.attr("src");
imgSrc.attr("src",chgUrl1(src));
}
//时间戳
//为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
function chgUrl1(url){
var timestamp = (new Date()).valueOf();
url = url.substring(0,25);
if((url.indexOf("&")>=0)){
url = url + "×tamp=" + timestamp;
}else{
url = url + "?timestamp=" + timestamp;
}
return url;
}
function isRightCode(){
var code = $("#veryCode").attr("value");
code = "c=" + code;
$.ajax({
type:"POST",
url:"../resultServlet",
data:code,
success:callback
});
}
function callback(data){
$("#info").html(data);
var v = data.replace(/(^\s*)|(\s*$)/g,""); ;//str首尾的空格去掉 ;;记得要加这个啊
//var v = data.replace(/^\s+|\s+$/g,"") ;//str首尾的空格去掉 ;;记得要加这个啊
//v =v.replace(/(\s*$)/g,"");
//v = v.replace(/([^u4e00-u9fa5])(\s)(?=[^u4e00-u9fa5])/g, '$1');
if(v == '验证码正确'){//进不来,因为如果是中文上面无法去掉末尾的空格
alert(11111111111111111111);
window.location.href="main.html";
}
}
loginVerfy.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="../js/verifyCode.js"></script>
<script type="text/javascript" src="../js/jquery.js"></script>
<title>企业信息管理系统_用户登录</title>
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
background-color: #016aa9;
overflow:hidden;
}
.STYLE1 {
color: #000000;
font-size: 12px;
}
-->
</style>
</head>
<script type="text/javascript">
function yanzhengma(){
alert(1111);
}
</script>
<body>
<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<table width="962" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td height="235" background="../images/login_03.gif"> </td>
</tr>
<tr>
<td height="53">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<!-- style="background-repeat: no-repeat;background-position: right bottom;"-->
<td width="394" height="53" background="../images/login_05.gif"> </td>
<td width="206" background="../images/login_06.gif">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="20%" height="25"><div align="right"><span class="STYLE1">用户</span></div></td>
<td width="57%" height="25"><div align="center">
<input type="text" name="textfield" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff">
</div></td>
<td width="27%" height="25"> </td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1">密码</span></div></td>
<td height="25"><div align="center">
<input type="password" name="textfield2" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff">
</div></td>
<td height="25"><div align="left"></div></td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1">验证码</span></div></td>
<td height="25"><div align="center">
<img id="imgObj" alt="换就张" src="../verifyCodeChinaServlet"/>
</div></td>
<td height="25"><div align="left"><a href="javascript:void(0)" onclick ="changeImg1()"><img src="../images/main_18.gif" width="49" height="18" border="0"></a></div></td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1"></span></div></td>
<td height="25"><div align="center">
<input id="veryCode" name="veryCode" type="text" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff"/>
</div></td>
<td height="25"><div align="left"><a href="javascript:void(0)" onclick ="isRightCode()"><img src="../images/dl.gif" width="49" height="18" border="0"></a></div></td>
</tr>
<tr>
<td height="25" colspan="3"><div id="info"></div></td>
</tr>
</table>
</td>
<td width="362" height ="25" background="../images/login_07.gif"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td height="213" background="../images/login_08.gif"> </td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
login.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>企业信息管理系统_用户登录</title>
<script type="text/javascript" src="../js/verifyCode.js"></script>
<script type="text/javascript" src="../js/jquery.js"></script>
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
background-color: #016aa9;
overflow:hidden;
}
.STYLE1 {
color: #000000;
font-size: 12px;
}
-->
</style></head>
<script type="text/javascript">
function yanzhengma(){
alert(1111);
}
</script>
<body>
<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<table width="962" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td height="235" background="../images/login_03.gif"> </td>
</tr>
<tr>
<td height="53">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<!-- style="background-repeat: no-repeat;background-position: right bottom;"-->
<td width="394" height="53" background="../images/login_05.gif"> </td>
<td width="206" background="../images/login_06.gif">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="20%" height="25"><div align="right"><span class="STYLE1">用户</span></div></td>
<td width="57%" height="25"><div align="center">
<input type="text" name="textfield" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff">
</div></td>
<td width="27%" height="25"> </td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1">密码</span></div></td>
<td height="25"><div align="center">
<input type="password" name="textfield2" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff">
</div></td>
<td height="25"><div align="left"></div></td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1">验证码</span></div></td>
<td height="25"><div align="center">
<img id="imgObj" alt="验证码" src="../verifyCodeServlet"/>
</div></td>
<td height="25"><div align="left"><a href="javascript:void(0)" onclick ="changeImg()"><img src="../images/main_18.gif" width="49" height="18" border="0"></a></div></td>
</tr>
<tr>
<td height="25"><div align="right"><span class="STYLE1"></span></div></td>
<td height="25"><div align="center">
<input id="veryCode" name="veryCode" type="text" style="width:105px; height:17px; background-color:#292929; border:solid 1px #7dbad7; font-size:12px; color:#6cd0ff"/>
</div></td>
<td height="25"><div align="left"><a href="javascript:void(0)" onclick ="isRightCode()"><img src="../images/dl.gif" width="49" height="18" border="0"></a></div></td>
</tr>
<tr>
<td height="25" colspan="3"><div id="info"></div></td>
</tr>
</table>
</td>
<td width="362" height ="25" background="../images/login_07.gif"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td height="213" background="../images/login_08.gif"> </td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
当然仅靠上面的代码项目是跑不起来的,这需要你有一定的java基础,通过看懂意图,然后自己去进行修改,学习不能死板,要懂得变通。