首页 » 资料 » 验证码半自动登录的简单实现

验证码半自动登录的简单实现

 

首先是web端的代码,分别是login.jsp、validate.jsp和image.jsp。其中login.jsp是登录页面,validate.jsp是验证验证码是否正确,image.jsp是生成验证码的通用代码。

1.login.jsp

<%@ page contentType="text/html;charset=utf-8" %> 
<%@ page language="java" import="java.sql.*" errorPage="" %> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
<title>用户登录</title> 
<script language="javascript"> 
function loadimage(){ 
document.getElementById("randImage").src = "image.jsp?"+Math.random(); 
} 
</script> 
</head> 
<body> 
<table width="256" border="0" cellpadding="0" cellspacing="0"> 
<!--DWLayoutTable--> 
<form action="validate.jsp" method="post" name="loginForm"> 
<tr> 
<td width="118" height="22" valign="middle" align="center">
	<input type="text" name="rand" size="15">
</td> 
<td width="138" valign="middle" align="center">
	<img alt="code..." name="randImage" id="randImage" src="image.jsp" width="60" height="20" border="1" align="absmiddle">
</td> 
</tr> 
<tr> 
<td height="36" colspan="2" align="center" valign="middle"><a href="javascript:loadimage();"><font class=pt95>看不清点我</font></a></td> 
</tr> 
<tr> 
<td height="36" colspan="2" align="center" valign="middle"><input type="submit" name="login" value="提交"></td> 
</tr> 
</form> 
</table> 
</body> 
</html>

2.validate.jsp

<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %> 
<% 
String rand = (String)session.getAttribute("rand"); 
String input = request.getParameter("rand"); 
if(rand.equals(input)){ 
out.print("<script>alert('验证通过!');</script>"); 
} else{ 
out.print("<script>alert('请输入正确的验证码!');location.href='login.jsp';</script>"); 
} 
%> 

3.image.jsp

<%@ page contentType="image/jpeg" import="java.awt.*, 
java.awt.image.*,java.util.*,javax.imageio.*" %> 
<%! 
Color getRandColor(int fc,int bc) 
{ 
Random random = new Random(); 
if(fc>255) fc=255; 
if(bc>255) bc=255; 
int r=fc+random.nextInt(bc-fc); 
int g=fc+random.nextInt(bc-fc); 
int b=fc+random.nextInt(bc-fc); 
return new Color(r,g,b); 
} 
%> 
<% 
out.clear();//这句针对resin服务器,如果是tomacat可以不要这句 
response.setHeader("Pragma","No-cache"); 
response.setHeader("Cache-Control","no-cache"); 
response.setDateHeader("Expires", 0); 
int width=60, height=20; 
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
Graphics g = image.getGraphics(); 
Random random = new Random(); 
g.setColor(getRandColor(200,250)); 
g.fillRect(0, 0, width, height); 
g.setFont(new Font("Times New Roman",Font.PLAIN,18)); 
g.setColor(getRandColor(160,200)); 
for (int i=0;i<155;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); 
} 
String sRand=""; 
for (int i=0;i<4;i++){ 
String rand=String.valueOf(random.nextInt(10)); 
sRand+=rand; 
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110))); 
g.drawString(rand,13*i+6,16); 
} 
// 将认证码存入SESSION 
session.setAttribute("rand",sRand); 
g.dispose(); 
ImageIO.write(image, "JPEG", response.getOutputStream()); 
%>

上面的web代码简单的实现了一个验证码登录的完整过程,下面我们使用java代码实现验证码的半自动模拟登录。
核心是用的httpclient模拟提交post请求。所需要的lib包下载地址:lib

 

1.loginFrame.java

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;


public class loginFrame extends JFrame {

	private final static String imagePath = "c:\\image.jpg";
	
	private static HttpClient client = new DefaultHttpClient();

	private JLabel userL = new JLabel("用户名");
	private JLabel passwordL = new JLabel("密码");

	// https://user.lufax.com/user/captcha/captcha.jpg
	private JLabel codeL = new JLabel("验证码");

	private final static JLabel codeImage = new JLabel(new ImageIcon(Toolkit
			.getDefaultToolkit().createImage(imagePath)));

	private JLabel cue = new JLabel();
	private JTextField user = new JTextField("test");
	private JPasswordField password = new JPasswordField("test");

	private JTextField code = new JTextField("");
	
	private JButton refresh = new JButton("刷新");

	private JButton ok = new JButton("确定");
	private JButton cancel = new JButton("退出");
	private boolean result = false;

	static{
		refreshImageWindows();
	}
	
	public loginFrame() {
		
		super("仿验证码登陆程序");
		this.setBounds(280, 280, 300, 200);
		setLayout(new BorderLayout());
		// 设置登陆界面的宽度和高度
		final JPanel p1 = new JPanel();
		p1.setLayout(new GridLayout(4, 2));
		p1.add(userL);
		p1.add(user);
		p1.add(passwordL);
		p1.add(password);

		p1.add(codeL);
		p1.add(code);

		p1.add(codeImage);
		p1.add(refresh);

		p1.setSize(150, 100);
		JPanel p2 = new JPanel();
		p2.add(ok);
		p2.add(cancel);
		add("North", p1);
		add("Center", p2);
		add("South", cue);
		
		user.setEditable(false);
		password.setEditable(false);

		refresh.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				refreshImageWindows();
				code.requestFocus();
			}
		});

		
		
		addWindowListener(new WindowAdapter(){     //添加一个窗口监听
			public void windowOpened(WindowEvent evt) { 
                focusEvt(evt); 
            }

			private void focusEvt(WindowEvent evt) {
				 code.requestFocus(); 
			}
		 });
		
		
		code.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e){
                int k = e.getKeyCode();
                if(k == e.VK_ENTER){
                	ok.doClick();
                }
			}
		});
		
			
		
		// 到此为止,登陆的界面基本结束!下面的是为里面的按钮设置具体的事件监听器
		cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		
		
		// 设置登陆时的取消按钮,按这个按钮就退出所有的程序
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if ((user.getText()).equals("test")
						&& String.valueOf((password.getPassword())).equals(
								"test")) {
					if(checkCode(code.getText())){
						result = true;
						// hidFun();
						refreshImageWindows();
						code.setText("");
						code.requestFocus();
						JOptionPane.showMessageDialog(null, "你好:你登陆成功,进入系统!");
					}else {
						// cue.setText("你输入的密码错误!");
						code.setText("");
						code.requestFocus();
						JOptionPane.showMessageDialog(null, "你好:你输入密码或验证码错误,请重新输入!");
					}
				} // 设置ok键的事件监听器,并验证用户名和密码,密码输入错误时提示"您输入的密码错误!"
			}
		});
	}

	

	public boolean isLogin() {
		return result;
	}

	/**
	 * 设置本界面隐藏..
	 * 
	 */
	private void hidFun() {
		this.setVisible(false);
	}

	
	
	protected boolean checkCode(String text) {
		boolean flag = false;
		String checkUrl = "http://127.0.0.1/yzm/validate.jsp?rand=" + text;
		//System.out.println("url:" + checkUrl);
		try{
			HttpGet get = new HttpGet(checkUrl);
			HttpResponse response = client.execute(get);
			String reponseText = EntityUtils.toString(response.getEntity());
			//System.out.println(reponseText);
			
			if(reponseText.contains("验证通过!")){
				flag = true;
			}
			
			if(reponseText.contains("请输入正确的验证码!")){
				flag = false;
			}
			
			
		}catch(Exception e){
			
			e.printStackTrace();
		}
		return flag;
	}

	private static void downcode() {

		String picUrl = "http://127.0.0.1/yzm/image.jsp?" + Math.random();
		try {

			HttpGet get = new HttpGet(picUrl);
			HttpResponse response = client.execute(get);

			File storeFile = new File(imagePath);
			FileOutputStream output = new FileOutputStream(storeFile);
			// 得到网络资源的字节数组,并写入文件
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				InputStream instream = entity.getContent();
				byte b[] = new byte[1024];
				int j = 0;
				while ((j = instream.read(b)) != -1) {
					output.write(b, 0, j);
				}

			}
			output.flush();
			output.close();

			//client.getConnectionManager().shutdown();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	
	private static void refreshImageWindows() {
		downcode();
		codeImage.setIcon((new ImageIcon(Toolkit.getDefaultToolkit()
				.createImage(imagePath))));
		codeImage.repaint();
	}
	
	
	public static void main(String[] args) {
		
		loginFrame lf = new loginFrame();
		lf.setVisible(true);
		lf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

 

原文链接:验证码半自动登录的简单实现,转载请注明来源!

1