注,本代码引用来之张孝祥的最新力作<深入体验java web开发内幕-核心基础>,保留所有权利。
此段servlet完整展示了动态验证码的生成过程,通俗易懂,不愧为张老师所写的代码,在此遇到一个问题,就是常说的javax.servlet包无法引入,我按要求都把servlet包放入了lib目录中,可还是一样找不到,因此实际调试效果还没看到。
首先是一个简单的登录页面。
Check_login.htm
<
html
>
<
head
>
<
title
>
实现验证码功能
</
title
>
</
head
>
<
body
>
<
h1
>
带有验证码功能的登录演示
</
h1
>
<
form
action
="LogonFormServlet"
>
<
table
>
<
tr
>
<
td
>
用户名:
</
td
>
<
td
><
input
type
="text"
name
="userName"
></
td
>
</
tr
>
<
tr
>
<
td
>
密码:
</
td
>
<
td
><
input
type
="password"
name
="password"
></
td
>
</
tr
>
<
tr
>
<
td
>
验证码:
</
td
>
<
td
><
input
type
="text"
value
="mildo"
name
="passport"
><
img
src
="CheckCodeServlet"
></
td
>
</
tr
>
<
tr
colspan
="2"
>
<
td
><
input
type
="submit"
value
="登录"
></
td
>
</
tr
>
</
table
>
</
form
>
</
body
>
</
html
>
接下来就是生成图片验证码的Servlet了,源代码: CheckCodeServlet.java
import
java.io.
*
;
import
javax.servlet.
*
;
import
javax.servlet.http.
*
;
import
java.awt.
*
;
import
java.awt.image.
*
;
import
javax.imageio.ImageIO;
public
class
CheckCodeServlet
extends
HttpServlet
...
{ private static int WIDTH = 60 ; private static int HIGHT = 20 ; public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException ... { HttpSession session = Request.session(); response.setContent( " image/jpeg " ); ServletOutputStream sos = response.getOutputStream(); // 设置浏览器不要缓存图片 response.setHead( " Pragma " , " No-cache " ); response.setHead( " Cache-Control " , " no-cache " ); response.setDateHead( " Expires " , 0 ); // 创建内建图像,并获得上下文 BufferedImage image = new BufferedImage(WIDTH,HIGHT,BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); // 生成随机认证码 char [] rands = new generateCheckCode(); // 产生图像 drawBackgrounds(g); drawRands(g,rands); // 结束图像绘制,完成输出 g.dispose(); // 输出到客户端 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(image, " jpeg " ,bos); byte [] buf = bos.toByteArray(); response.setContentLength(buf.length); // 下面的语句也可以写成 bos.write(sos); sos.wirte(buf); bos.close(); sos.close(); // 将当前验证码插入到session中 session.setAttribute( " check_code " , new String(rands)); } private char [] generateCheckCode() ... { // 定义验证码的字符集 String str = " 0123456789abcdefghjklmnopqrstuvwxyz " ; char [] rands = new char [ 4 ]; for ( int i = 0 ;i < 4 ;i ++ ) ... { int rand = ( int )(Math.random() * 36 ); rands[i] = chars.charAt(rand); } return rands; } private void drawRands(Graphics g, char [] rands) ... { g.setColor(Color.black); g.setFont( new Font( null ,Font.ITALIC | Font.BOLD, 18 )); // 在不同的高度输出验证码的字符 g.drawString( "" + rands[ 0 ], 1 , 16 ); g.drawString( "" + rands[ 1 ], 16 , 18 ); g.drawString( "" + rands[ 2 ], 32 , 15 ); g.drawString( "" + rands[ 3 ], 51 , 17 ); System.out.println(rands); } private void drawBackground(Graphics g) ... { // 画背景 g.setColor(Color.cyan); g.fillRect( 0 , 0 ,WIDTH,HIGHT); // 添加随机120个杂点 for ( int i = 0 ;i < 120 ;i ++ ) ... { int x = ( int )(Math.random() * WIDTH); int y = ( int )(Math.random() * HIGHT); int red = ( int )(Math.random() * 255 ); int blue = ( int )(Math.random() * 255 ); int green = ( int )(Math.random() * 255 ); g.setColor( new Color(red,green,blue)); g.drawOval(x,y, 1 , 0 ); } } }
用来验证的servlet代码: LogonFormServlet.java
import
java.io.
*
;
import
javax.servlet.
*
;
import
javax.servlet.http.
*
;
import
java.awt.
*
;
import
java.awt.image.
*
;
import
javax.imageio.ImageIO;
public
class
CheckCodeServlet
extends
HttpServlet
...
{ private static int WIDTH = 60 ; private static int HIGHT = 20 ; public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException ... { HttpSession session = Request.session(); response.setContent( " image/jpeg " ); ServletOutputStream sos = response.getOutputStream(); // 设置浏览器不要缓存图片 response.setHead( " Pragma " , " No-cache " ); response.setHead( " Cache-Control " , " no-cache " ); response.setDateHead( " Expires " , 0 ); // 创建内建图像,并获得上下文 BufferedImage image = new BufferedImage(WIDTH,HIGHT,BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); // 生成随机认证码 char [] rands = new generateCheckCode(); // 产生图像 drawBackgrounds(g); drawRands(g,rands); // 结束图像绘制,完成输出 g.dispose(); // 输出到客户端 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(image, " jpeg " ,bos); byte [] buf = bos.toByteArray(); response.setContentLength(buf.length); // 下面的语句也可以写成 bos.write(sos); sos.wirte(buf); bos.close(); sos.close(); // 将当前验证码插入到session中 session.setAttribute( " check_code " , new String(rands)); } private char [] generateCheckCode() ... { // 定义验证码的字符集 String str = " 0123456789abcdefghjklmnopqrstuvwxyz " ; char [] rands = new char [ 4 ]; for ( int i = 0 ;i < 4 ;i ++ ) ... { int rand = ( int )(Math.random() * 36 ); rands[i] = chars.charAt(rand); } return rands; } private void drawRands(Graphics g, char [] rands) ... { g.setColor(Color.black); g.setFont( new Font( null ,Font.ITALIC | Font.BOLD, 18 )); // 在不同的高度输出验证码的字符 g.drawString( "" + rands[ 0 ], 1 , 16 ); g.drawString( "" + rands[ 1 ], 16 , 18 ); g.drawString( "" + rands[ 2 ], 32 , 15 ); g.drawString( "" + rands[ 3 ], 51 , 17 ); System.out.println(rands); } private void drawBackground(Graphics g) ... { // 画背景 g.setColor(Color.cyan); g.fillRect( 0 , 0 ,WIDTH,HIGHT); // 添加随机120个杂点 for ( int i = 0 ;i < 120 ;i ++ ) ... { int x = ( int )(Math.random() * WIDTH); int y = ( int )(Math.random() * HIGHT); int red = ( int )(Math.random() * 255 ); int blue = ( int )(Math.random() * 255 ); int green = ( int )(Math.random() * 255 ); g.setColor( new Color(red,green,blue)); g.drawOval(x,y, 1 , 0 ); } } }
这些做好了,当然要对servlet进行注册和映射了,web.xml
<
servlet-name
>
CheckCodeServlet
</
servlet-name
>
<
servlet-class
>
CheckCodeServlet
</
servlet-class
>
</
servlet
>
<
servlet
>
<
servlet-name
>
LogonFormServlet
</
servlet-name
>
<
servlet-class
>
LogonFormServlet
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
serlet-name
>
CheckCodeServlet
</
serlet-name
>
<
url-pattern
>
/CheckCodeServlet
</
url-pattern
>
</
servlet-mapping
>
<
servlet-mapping
>
<
serlet-name
>
LogonFormServlet
</
serlet-name
>
<
url-pattern
>
/LogonFormServlet
</
url-pattern
>
</
servlet-mapping
>