原文:http://blog.csdn.net/qq_26680031/article/details/51168527
效果图如上,
package cn.gdin.captcha;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
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;
public class JcaptchaServlet extends HttpServlet {
Random random = new Random();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int height = 220; //图片高
int width = 220; //图片宽
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) image.getGraphics();
String picPath= JcaptchaServlet.class.getClassLoader().getResource("../image/"+(random.nextInt(4)+1)+".jpg").getPath(); 读取本地图片,做背景图片
g.drawImage(ImageIO.read(new File(picPath)), 0, 20, width, height, null); //将背景图片从高度20开始
g.setColor(Color.white); //设置颜色
g.drawRect(0, 0, width-1, height-1); //画边框
g.setFont(new Font("宋体",Font.BOLD,20)); //设置字体
Integer x=null,y=null; //用于记录坐标
String target=null; // 用于记录文字
for(int i=0;i<4;i++){ //随机产生4个文字,坐标,颜色都不同
g.setColor(new Color(random.nextInt(50)+200, random.nextInt(150)+100, random.nextInt(50)+200));
String str=getRandomChineseChar();
int a=random.nextInt(width-100)+50;
int b=random.nextInt(height-70)+55;
if(x==null){
x=a; //记录第一个x坐标
}
if(y==null){
y=b;//记录第一个y坐标
}
if(target==null){
target=str; //记录第一个文字
}
g.drawString(str, a, b);
}
g.setColor(Color.white);
g.drawString("点击"+target, 0,20);//写入验证码第一行文字 “点击..”
request.getSession().setAttribute("gap",x+":"+y);//将坐标放入session
//5.释放资源
g.dispose();
//6.利用ImageIO进行输出
ImageIO.write(image, "jpg", response.getOutputStream()); //将图片输出
}
//网上找的,随机产生汉字的方法
public String getRandomChineseChar()
{
String str = null;
int hs, ls;
Random random = new Random();
hs = (176 + Math.abs(random.nextInt(39)));
ls = (161 + Math.abs(random.nextInt(93)));
byte[] b = new byte[2];
b[0] = (new Integer(hs).byteValue());
b[1] = (new Integer(ls).byteValue());
try
{
str = new String(b, "GBk"); //转成中文
}
catch (UnsupportedEncodingException ex)
{
ex.printStackTrace();
}
return str;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
前端代码
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(function(){
$("#image").click(function(event){
var obj=this;
var x=event.offsetX;//获取点击时鼠标相对图片坐标
var y=event.offsetY;
$.ajax({
url:"login.shtml", //ajax提交
type:"post",
data:{'x':x,"y":y},
success:function(data){
alert(data)
obj.src=obj.src+"?date="+new Date();
}
})
});
})
</script>
</head>
<body>
<img id="image" src="${pageContext.request.contextPath}/captcha.svl" style="cursor: pointer;" >
</body>
</html>
服务端
package cn.gdin.captcha;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class Login
*/
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8"); //设置编码
//获取前端传来的坐标
String xs=request.getParameter("x");
String ys=request.getParameter("y");
HttpSession session = request.getSession();
String str = (String) session.getAttribute("gap");//获取session中的gap
if(str==null){
response.getWriter().write("验证码超时");
return;
}
String[] split2 = str.split(":");
int x= Integer.parseInt(xs);
int y=Integer.parseInt(ys);
int x1= Integer.parseInt(split2[0]);
int y1=Integer.parseInt(split2[1]);
if(x1-2<x && x<x1+22 && y1-22<y && y<y1+2){ //若前端上传的坐标在session中记录的坐标的一定范围内则验证成功
response.getWriter().write("验证成功");
}else{
response.getWriter().write("验证失败");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
----------------------------------------------以下是我自己改造的------------------------------
@Action("/test") public void test () throws IOException { Random random = new Random(); int height = 220; //图片高 int width = 220; //图片宽 BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); String picPath= "d:/a.png"; //读取本地图片,做背景图片 g.drawImage(ImageIO.read(new File(picPath)), 0, 20, width, height, null); //将背景图片从高度20开始 g.setColor(Color.white); //设置颜色 g.drawRect(0, 0, width-1, height-1); //画边框 g.setFont(new Font("宋体",Font.BOLD,20)); //设置字体 Integer x=null,y=null; //用于记录坐标 String target=null; // 用于记录文字 for(int i=0;i<4;i++){ //随机产生4个文字,坐标,颜色都不同 g.setColor(new Color(random.nextInt(50)+200, random.nextInt(150)+100, random.nextInt(50)+200)); String str=getRandomChineseChar(); int a=random.nextInt(width-100)+50; int b=random.nextInt(height-70)+55; if(x==null){ x=a; //记录第一个x坐标 } if(y==null){ y=b;//记录第一个y坐标 } if(target==null){ target=str; //记录第一个文字 } g.drawString(str, a, b); } g.setColor(Color.white); g.drawString("点击"+target, 0,20);//写入验证码第一行文字 “点击..” request.getSession().setAttribute("gap",x+":"+y);//将坐标放入session System.out.println("gap:"+x+":"+y); ServletOutputStream out = response.getOutputStream(); //5.释放资源 g.dispose(); //6.利用ImageIO进行输出 ImageIO.write(image, "jpg", out); //将图片输出 out.flush(); } public String getRandomChineseChar() { String str = null; int hs, ls; Random random = new Random(); hs = (176 + Math.abs(random.nextInt(39))); ls = (161 + Math.abs(random.nextInt(93))); byte[] b = new byte[2]; b[0] = (new Integer(hs).byteValue()); b[1] = (new Integer(ls).byteValue()); try { str = new String(b, "GBk"); //转成中文 } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } return str; }