一:Code.java文件(servlet文件)
package main;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
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;
import javax.servlet.http.HttpSession;
public class Code extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//回应为image
response.setContentType("image/jpeg");
// 设置要画的图片的宽和高
int width = 70;
int height = 24;
// 具有可访问图像数据缓冲区的Image
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 创建两个画笔
Graphics g = image.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g.setColor(getColor(200, 240));// 上色
g.fillRect(0, 0, width, height);// 全图绘制背景色
// 在图片上绘制150条干扰线
g.setColor(getColor(180, 200));// 上色
Random random = new Random();
for (int i = 0; i < 150; i++)
{
// 绘制线的坐标
int x = random.nextInt(width - 1);
int y = random.nextInt(height - 1);
// x、y坐标偏移多少个单位
int deltax = random.nextInt(6) + 1;
int deltay = random.nextInt(12) + 1;
// 构造一个具有指定属性的实心的 BasicStroke(2D图形)
BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL);
// Line2D是一个无法直接实例化的抽象类
Line2D line = new Line2D.Double(x, y, x + deltax, y + deltay);
g2d.setStroke(bs);// 绘制 BasicStroke
g2d.draw(line);// 再绘制线条
}
// 输出那些字符,以便验证
String str = "";
int temp = 0;
Font font = new Font("华文宋体", Font.BOLD, 14);
g.setFont(font);// 设置画笔画的字体格式
// 绘制四个字符
for (int i = 0; i < 4; i++)
{
if (random.nextInt(2) == 1)
{
temp = random.nextInt(26) + 'A';
}
else
{
temp = random.nextInt(10) + '0';
}
char ctemp = (char) temp;
str += ctemp;
Color c=getColor(20,130);//颜色较深
g.setColor(c);
/** ******随机将文字缩放并旋转一定的角度****** */
// 将文字旋转一定角度
/*AffineTransform 类表示 2D 仿射变换,它执行从 2D 坐标到其他 2D 坐标的线性映射,
保留了线的“直线性”和“平行性”。可以使用一系列
平移 (translation)、缩放 (scale)、翻转 (flip)、旋转 (rotation) 和错切 (shear)
来构造仿射变换。*/
AffineTransform trans=new AffineTransform();
//45弧度,旋转点位置
trans.rotate(random.nextInt(45) * Math.PI / 180, 15 * i + 10, 6);
// 缩放文字
float scaleSize=random.nextFloat()+0.5f;//缩放大小
if(scaleSize<0.8f||scaleSize>1.2)
{
scaleSize=1.0f;
}
trans.scale(scaleSize, scaleSize);
g2d.setTransform(trans);
//画在什么位置
g.drawString(ctemp+"", 15*i+10, 14);
}
//禁止图片缓存那样刷新就不会有重复的图片出现
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);
HttpSession session=request.getSession();
session.setAttribute("BBScode", str);//把验证码发送到session以便验证
try
{
//把得到的验证码保存称jpeg格式放在输入流中
ImageIO.write(image, "jpeg", response.getOutputStream());
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 得到具有规定的颜色
public static Color getColor(int start, int end)
{
Random R = new Random();
int r = start + R.nextInt(end - start);
int g = start + R.nextInt(end - start);
int b = start + R.nextInt(end - start);
return new Color(r, g, b);
}
}
二、在XML里配置
<servlet>
<servlet-name>code</servlet-name>
<servlet-class>main.Code</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>code</servlet-name>
<url-pattern>/code</url-pattern>
</servlet-mapping>
三、code.jsp(显示页面)
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<script language="javascript">
function reloadcode()
{
var timenow = new Date().getTime();
document.getElementById("reqCode").src="../code?d="+timenow;
}
</script>
<style type="text/css">
body{
color:blue;
font-family:楷体;
text-align:center;
background:cyan;
font-Size:24;
background-image: url(image/4.jpg);
}
.style1 {font-size: 15px}
</style>
<title>注册君临账号_君临论坛</title>
</head>
<body>
<font color="olive" size="6" face="华文行楷">注册君临账号</font>
<hr color="silver">
<div align="left" class="style1"><a href="load.jsp">首页</a>>>注册页</div>
<form action="checkmyindex.jsp" name="info" id="info">
<center>
<img alt="验证码" name="reqCode" id="reqCode" src="<%=request.getContextPath() %>/code"/>
<a href="JavaScript:reloadcode();">再换一张</a>
<input type="text" name="xincode" size="15" />
<%
String ssss=request.getParameter("codeerror");
if(ssss!=null){
%>
<label id="codeError"><font color='red' size='-1'>您输入的验证码不正确!</font></label><br/>
<%
}
%>
<input type="submit" value="确定">
</form>
<hr color="gray">
<font size="2" face="宋体">
<a href="#">关于君临</a>|
<a href="#">君临客服</a>|
<a href="#">隐私和版权</a>|
<a href="#">联系我们</a>|
<a href="#">加入君临</a>|
<a href="#">举报投诉</a>
</font>
</body>
</html>
四、验证输入的验证码是否一致
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>验证BBS</title>
</head>
<body>
<%
String yuancode=(String)session.getAttribute("BBScode");
String xingcode=request.getParameter("xincode");
if(xingcode.equals(yuancode)){
response.sendRedirect("register.jsp");
}else{
response.sendRedirect("code.jsp?codeerror=4564641");
}
%>
</body>
</html>