Author AhahaGe

主要实现了创建验证码servlet,以及刷新验证码功能

创建验证码主要做以下几个步骤:

  • 建一个bufferedImage,来存放可改变的p_w_picpath
  • 得到graphics2D来渲染2维的p_w_picpath,设置颜色setColor()和字体setFont()
  • 用drawRect()方法画矩形
  • 用fillRect()方法填充矩形
  • 用drawLine()方法画干扰线
  • 用drawString()方法画验证码
  • 浏览器设置不缓存
  • 设置返回类型为p_w_picpath
  • 用ImageIO把bufferedImage写入servletOutputStream

Step1:创建验证码servlet,类名为ValidateCodeServlet

  1. package servlet;  
  2.  
  3. import java.awt.Color;  
  4. import java.awt.Font;  
  5. import java.awt.Graphics2D;  
  6. import java.awt.p_w_picpath.BufferedImage;  
  7. import java.io.IOException;  
  8. import java.util.Random;  
  9.  
  10. import javax.p_w_picpathio.ImageIO;  
  11. import javax.servlet.ServletException;  
  12. import javax.servlet.ServletOutputStream;  
  13. import javax.servlet.http.HttpServlet;  
  14. import javax.servlet.http.HttpServletRequest;  
  15. import javax.servlet.http.HttpServletResponse;  
  16. import javax.servlet.http.HttpSession;  
  17.  
  18. /**  
  19.  * create a validateCode p_w_picpath and validate user's input  
  20.  * @author Ahaha_Ge  
  21.  *  
  22.  */ 
  23. public class ValidateCodeServlet extends HttpServlet{  
  24.  
  25.     private static final long serialVersionUID = 1L;  
  26.  
  27.     @Override 
  28.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  29.             throws ServletException, IOException {  
  30.         doPost(req,resp);  
  31.     }  
  32.  
  33.     /**  
  34.      * generate validateCode p_w_picpath  
  35.      * p_w_picpath shape is rectangular with some lines and codes  
  36.      * codeCount is 4, code should contain 26 English chars and number  
  37.      */ 
  38.     @Override 
  39.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  40.             throws ServletException, IOException {  
  41.           
  42.         int width = 160;  
  43.         int height = 40;  
  44.         int codeCount = 4;  
  45.         Random r = new Random();  
  46.         //create a buffered p_w_picpath instance  
  47.         BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  48.         //create a graphics to render the p_w_picpath  
  49.         Graphics2D g = bi.createGraphics();  
  50.         //set context color and fill rectangular  
  51.         g.setColor(setRandomColor());  
  52.         g.fillRect(00, width-1, height-1);  
  53.         //set context color and draw rectangular  
  54.         g.setColor(setRandomColor());  
  55.         g.drawRect(00, width-1, height-1);  
  56.         //draw disturb lines  
  57.         for(int i=0; i<5; i++){  
  58.             g.setColor(setRandomColor());  
  59.             g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));  
  60.         }  
  61.         //set font  
  62.         Font font = new Font("font",Font.PLAIN,height*3/4);  
  63.         g.setFont(font);  
  64.         //create and draw codes  
  65.         String codes = generateCodes(codeCount);  
  66.         for(int i=0; i<codes.length(); i++){  
  67.             g.drawString(String.valueOf(codes.charAt(i)), width*(i+1)/(codeCount+1), height*7/8);  
  68.         }  
  69.         //put codes into session  
  70.         HttpSession session = req.getSession();  
  71.         session.setAttribute("validateCode", codes);  
  72.         //forbid cache  
  73.         resp.setHeader("Pragma""no-cache");  
  74.         resp.setHeader("Cache-Control""no-cache");  
  75.         resp.setDateHeader("expires"0);  
  76.         resp.setContentType("p_w_picpath/jpeg");  
  77.         //send p_w_picpath to output stream  
  78.         ServletOutputStream sos = resp.getOutputStream();  
  79.         ImageIO.write(bi, "jpeg", sos);  
  80.         sos.close();  
  81.     }  
  82.       
  83.     //set Random color  
  84.     private Color setRandomColor(){  
  85.         int r = new Random().nextInt(256);  
  86.         int g = new Random().nextInt(256);  
  87.         int b = new Random().nextInt(256);  
  88.         Color c = new Color(r,g,b);  
  89.         return c;  
  90.     }  
  91.       
  92.     //create codes set  
  93.     private char[] createCodesSet(){  
  94.         char[] c = new char[62];  
  95.         for(int i=0; i<26; i++){  
  96.             //add A to Z  
  97.             c[i] = (char)(i+65);  
  98.             //add a to z  
  99.             c[26+i] = (char)(i+97);  
  100.         }  
  101.         for(int i=0; i<10; i++){  
  102.             //add 0 to 9  
  103.             c[52+i] = (char)(i+48);  
  104.         }  
  105.         return c;  
  106.     }  
  107.       
  108.     //create n codes  
  109.     private String generateCodes(int n){  
  110.         //codes set  
  111.         char[] codes = createCodesSet();  
  112.         StringBuffer sb = new StringBuffer();  
  113.         for(int i=0;i<n;i++){  
  114.             sb.append(codes[new Random().nextInt(codes.length)]);  
  115.         }  
  116.         return sb.toString();     
  117.     }  
  118.       
  119.     public static void main(String[] args){  
  120.         System.out.println(new ValidateCodeServlet().setRandomColor());  
  121.     }  
  122.       
  123. }  

Step2: 在web.xml中配置写好的ValidateCodeServelt

  1. <servlet> 
  2.     <servlet-name>validateCodeServlet</servlet-name> 
  3.     <servlet-class>servlet.ValidateCodeServlet</servlet-class> 
  4. </servlet> 
  5. <servlet-mapping> 
  6.     <servlet-name>validateCodeServlet</servlet-name> 
  7.     <url-pattern>/validateCodeServlet</url-pattern> 
  8. </servlet-mapping> 

Step3: 在使用验证码的地方,创建一个p_w_picpath控件,再改变src为ValidateCodeServlet

  1. <input type="p_w_picpath" id="p_w_picpath" width="160" height="40" name="code" src="validateCodeServlet"/> 

Step4: 用javascript来实现刷新验证码,写一个按钮,当点击它时,定义一个方法,改变p_w_picpath控件的src,不要忘了newDate(),不然生成的验证码是一样的。

  1. <input type="button" name="fresh" value="fresh" onclick="freshValidateCode();"/> 
  1. <script type="text/javascript">  
  2.         function freshValidateCode()  
  3.         {     
  4.             document.getElementById("p_w_picpath").setAttribute("src","validateCodeServlet?"+new Date());  
  5.         }  
  6.     </script> 

总结:这么简单的功能写了两天,第一天竟然被画验证码给吓住了,这么多代码,这么多类,现在回过来看看,发现还是挺简单的,主要是参考了网上的代码,跟着理解了一遍,做了两遍,做的时候总是会忘,总是会出小错,终于作出来了,接着得写上传下载。