原文: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; }