页面中添加图片验证码功能
jsp代码:
<form action="<c:url value="/RegistServlet"/>" method="post">
用户名<input type="text" name="username" value=""/><br/><br/>
密 码<input type="password" name="password" value=""/><br/><br/>
验证码<input type="text" name="VerifyCode" size="3" value=""/>
<img id="img" src="<c:url value="/MyVerifyCode"/>"/><a href="javascript:changImage()">看不清,换一张</a><br/><br/>
<input type="submit" value="注册"/>
</form>
</center>
</body>
<script>
function changImage(){
var img = document.getElementById("img");
img.src="<c:url value="/MyVerifyCode"/>?a="+ new Date().getTime();
}
</script>
servlet代码:
VerifyCode vc = new VerifyCode();
BufferedImage image = vc.getImage();
String text = vc.getText();
VerifyCode.output(image, response.getOutputStream());
System.out.println(text);
需要导入的jar包:
utils.jar(自己封装的jar包) 这个jar包里面封装了一个VerifyCode类,代码如下
package cn.itcast.vcode.utils;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class VerifyCode {
private int w = 70;
private int h = 35;
private Random r = new Random();
// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
private Color bgColor = new Color(255, 255, 255);
private String text ;
private Color randomColor () {
int red = r.nextInt(150);
int green = r.nextInt(150);
int blue = r.nextInt(150);
return new Color(red, green, blue);
}
private Font randomFont () {
int index = r.nextInt(fontNames.length);
String fontName = fontNames[index];
int style = r.nextInt(4);
int size = r.nextInt(5) + 24;
return new Font(fontName, style, size);
}
private void drawLine (BufferedImage image) {
int num = 3;
Graphics2D g2 = (Graphics2D)image.getGraphics();
for(int i = 0; i < num; i++) {
int x1 = r.nextInt(w);
int y1 = r.nextInt(h);
int x2 = r.nextInt(w);
int y2 = r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));
g2.setColor(Color.BLUE);
g2.drawLine(x1, y1, x2, y2);
}
}
private char randomChar () {
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
private BufferedImage createImage () {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D)image.getGraphics();
g2.setColor(this.bgColor);
g2.fillRect(0, 0, w, h);
return image;
}
public BufferedImage getImage () {
BufferedImage image = createImage();
Graphics2D g2 = (Graphics2D)image.getGraphics();
StringBuilder sb = new StringBuilder();
// 向图片中画4个字符
for(int i = 0; i < 4; i++) {
String s = randomChar() + "";
sb.append(s);
float x = i * 1.0F * w / 4;
g2.setFont(randomFont());
g2.setColor(randomColor());
g2.drawString(s, x, h-5);
}
this.text = sb.toString();
drawLine(image);
return image;
}
public String getText () {
return text;
}
public static void output (BufferedImage image, OutputStream out)
throws IOException {
ImageIO.write(image, "JPEG", out);
}
}
这个类可以每次访问生成一张图形验证码,并且有相应的方法来得到他的验证码text内容。这个类中的内容大家可以自己封装到自己的jar中,以便使用。
下面说明一下封装好之后的使用步骤:
1.导入自己封装好的jar包
2.在servlet中的代码如下几步:
2.1:VerifyCode vc = new VerifyCode() 这个是创建这个类的一个实例,以便调用类中的方法。
2.2:BufferedImage image = vc.getImage(); 这个是获得图形验证码图片。
2.3:String text = vc.getText(); 这个是获取当前图片上的验证码文本内容。
2.4:VerifyCode.output(image,response.getOutPutStream); 这个是将图片用响应流输出到请求页面。
2.5:request.getSession().setAttribute("VerifyCode",text); 可以将图片验证码内容保存到session中,用来校验页面输入是否正确。
3.在页面中的代码:
<img id = "image" src="<c:url value="/此处写servlet的映射"/>"/><a href="javascript:changImage()">看不清,换一张</a>
这样,页面中已经可以显示图片验证码了,可以打开页面一看。但是有一个问题,就是点击换一张,图片竟然没有变。
这是因为两次图片访问的路径是同一路径,没有什么变化,浏览器直接将缓存的东西再次输出。所以页面没有变化。
这里用到javascript中的一个方法。动态的给访问路径后面添加一个无效参数,以便于每次访问的路径参数变化。每次都从服务器上获取图片。
代码如下:
<script>
function changImage(){
1.通过id得到此元素。
var image = document.getElementById("image");
2.通过这个元素,给他的src属性设置内容
image.src="<c:url value="/这里写servlet的映射"/>?a="+new Date().getTime();
这个是获取系统当前的时间,时间一直在变,所以参数每次都在变,所以系统就会认为这是一个新请求,每次都会从服务器请求新的图片验证码来显示
}
</script>
到这里基本上页面图形验证码的问题已经得到了解决。
这里再说一下那个封装到jar的VerifyCode类中如何生成图片呢?
基本思路:
*先从所有的验证码字母和数字中,随机选取四个,将其绘制到图片上即可。
1.从所有的里面选四个,这个应该不难。
首先将所有的内容都放在一个字符串中。
int index = r.nextInt(codes.length());
return codes.charAt(index);
return codes.charAt(index);
2.将字符绘制到图片上。
首先创建一个图片缓冲区 BufferedImage bi = new BufferedImage();
得到图片绘制环境: Graphics g = bi.getGraphics()
设置图片填充颜色和大小 g.setColor(this.bgColor);
g.fillRect(0, 0, w, h);
g.fillRect(0, 0, w, h);
设置图片上的字体的大小和颜色。同上。
绘制:g.drawString(); 将刚才选取的字符串当作参数传递进去,就可以了。
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
-
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
-
关注公众号 『逆行的碎石机』,不定期分享原创知识。
-
同时可以期待后续文章ing🚀