验证码最终效果:除了最后一个输入框样式没写好以及没有居中对齐外,自己觉得还可以

java 识别图片验证码 原生态代码 javaweb怎么实现图形验证码_java

验证码实现步骤:

1.在工具包(util)中写一个验证码的方法(ImageUtil)

2.创建ImageServlet,生成验证码和图片,验证码放session中,并且输出图片

3.在登录页显示图片:将图片地址指向ImageServlet

4.输入验证码,点击提交

5.在LoginServlet中,将提交的验证码session中的验证码进行比对

步骤详解:

1.在工具包(util)中写一个验证码的方法(ImageUtil):

package com.cyzy.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

// 生成  验证码  和  验证码图片  的类
public final class ImageUtil {
	
	private static final char[] chars = {  '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
            'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
            'U', 'V', 'W', 'X', 'Y', 'Z' };
	
	private static final int SIZE = 4;      // 验证码图片中文字的个数
	private static final int LINES = 3;     // 验证码图片中的干扰线的数量
	private static final int WIDTH = 80;    // 验证码图片的宽度
	private static final int HEIGHT = 34;   // 验证码图片的高度
	private static final int FONT_SIZE = 19;// 验证码图片中文字的大小

	/**
	 * 生成验证码和验证码图片的方法,并封装在Map中。 
	 * 
	 * 其中Map的key是验证码,Map的value是验证码图片。
	 */
	public static Map<String, BufferedImage> createImage() {
		
		StringBuffer sb = new StringBuffer();
		
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		
		Graphics graphic = image.getGraphics();
		graphic.setColor(Color.LIGHT_GRAY);  
		graphic.fillRect(0, 0, WIDTH, HEIGHT);
		Random ran = new Random();
		// 画随机字符
		for (int i = 1; i <= SIZE; i++) {
			int r = ran.nextInt(chars.length);
			graphic.setColor(getRandomColor());
			graphic.setFont(new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE));
			graphic.drawString(chars[r] + "", (i - 1) * WIDTH / SIZE,
					HEIGHT / 2);
			sb.append(chars[r]);// 将字符保存,存入Session
		}
		// 画干扰线
		for (int i = 1; i <= LINES; i++) {
			graphic.setColor(getRandomColor());
			graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), ran
					.nextInt(WIDTH), ran.nextInt(HEIGHT));
		}
		Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
		map.put(sb.toString(), image);
		return map;
	}

	
	
	/**
	 * 将图片传入输入流的方法
	 */
	public static InputStream getInputStream(BufferedImage image)
			throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
		encoder.encode(image);
		byte[] imageBts = bos.toByteArray();
		InputStream in = new ByteArrayInputStream(imageBts);
		return in;
	}

	
	// 产生随机颜色的方法
	private static Color getRandomColor() {
		
		Random ran = new Random();   // 随机函数
		// 产生随机的RGB颜色
		Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran
				.nextInt(256));
		return color;
	}
}

2.创建ImageServlet,生成验证码和图片,验证码放session中,并且输出图片

(1)、创建Servlet:右键-->new-->Servlet-->ImageServlet

(2)、

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Map<String, BufferedImage> imageMap=ImageUtil.createImage();
		//得到验证码
		String code=imageMap.keySet().iterator().next();//用于Session进行校验
		request.getSession().setAttribute("code", code);
		//获取图片
		BufferedImage image=imageMap.get(code);
		//输出图片
		ServletOutputStream out=response.getOutputStream();
		ImageIO.write(image, "jpg", out);
	}

3.在登录页显示图片:将图片地址指向ImageServlet(出现了无法访问 [ 生成验证码的Servlet ],是因为什么原因呢,我百思不得其解)

java 识别图片验证码 原生态代码 javaweb怎么实现图形验证码_java_02

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>校务管理系统</title>
<style type="text/css">
a {
	margin-left: 420px;
}
</style>
<link rel="stylesheet"
	href="${pageContext.request.contextPath}/css/index.css">
</head>
<body>
	<div class="wrapper">
		<div class="content">
			<h1>校务管理系统</h1>
			<form action="${pageContext.request.contextPath}/LoginServlet"
				method="post">
				<input type="hidden" name="loginAction" value="login">
				<ul>
					<li>用户名:</li>
					<li><input type="text" placeholder="请输入用户名" name="userName"
						id="userName"></li>
					<li>密码:</li>
					<li><input type="password" placeholder="请输入密码" name="password"
						id="password"></li>
					<li>验证码:</li>
					<li> <input type="text" name="code" id="code"
						placeholder="请输入验证码" />
						<img src="${pageContext.request.contextPath}/ImageServlet"
						id="imageCode" onclick="getCode()" />
					</li>
					<li><input type="submit" value="登陆"><input
						type="reset" value="重置"></li>
				</ul>
				<a href="${pageContext.request.contextPath}/register.jsp">前往注册页面</a>
			</form>
		</div>
	</div>
</body>
<script type="text/javascript">
	function getCode() {
		var image = document.getElementById("imageCode");
		image.src = "${pageContext.request.contextPath}/ImageServlet?"
				+ Math.random();
	}
</script>
</html>

出现无法生成验证码图片的问题后-->我debug发现,自己的ImageServlet[生成验证码的Servlet]根本没有运行-->然后把

SessionFilter过滤器一开始没有判断这个ImageServlet-->下图的意思是说除了这些可以直接访问之外,其他的Servlet都要先登录才能访问,否则会提示会话失效。

 

java 识别图片验证码 原生态代码 javaweb怎么实现图形验证码_验证码_03

4.输入验证码,点击提交 【用户操作】

5.在LoginServlet中,将提交的验证码session中的验证码进行比对

(1)、在ImageServlet中存有session中的验证码

java 识别图片验证码 原生态代码 javaweb怎么实现图形验证码_java_04

(2)、LoginServlet中

java 识别图片验证码 原生态代码 javaweb怎么实现图形验证码_验证码_05

private void login(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
	
		response.setContentType("text/html");
        
		String code=request.getParameter("code");
		String sessionCode=(String)request.getSession().getAttribute("code");
		if(!code.equals(sessionCode)) {
			PrintWriter out =response.getWriter();
			out.println("<script>");
			out.println("window.alert('请输入正确的验证码');");
			out.println("window.location.href='"+request.getContextPath()+"/index.jsp';");
			out.println("</script>");
			return;
		}
		
		//查询用户是不是存在
		String userName=request.getParameter("userName");
		String password=request.getParameter("password");
	    UserService userService=(UserService)ServiceFactory.getServiceImpl(UserService.class.getName());
	    User user=userService.login(userName, password);
	    if(user!=null) {
			HttpSession session=request.getSession();
			//session.setMaxInactiveInterval(10);//超时时间以秒为单位
			session.setAttribute("loginUser", user);
			//还要查询此用户所拥有的菜单
			//菜单列表扔到request/session范围
			List<Menu> menuList=new ArrayList<Menu>();
			MenuService menuService=(MenuService)ServiceFactory.getServiceImpl(MenuService.class.getName());
			menuList=menuService.queryMenuByuserName(userName);
			request.getSession().setAttribute("menuList", menuList);
			//因为页面是由iframe组成,其他页面request没有办法取到
			//request.setAttribute("menuList", menuList);
			request.getRequestDispatcher("/admin/adminMain.jsp").forward(request, response);
			
		}else {
			PrintWriter out =response.getWriter();
			out.println("<script>");
			out.println("window.alert('用户不存在');");
			out.println("window.location.href='http://localhost:8080/JF190902/index.jsp';");
			out.println("</script>");
		}		
	}