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
- package servlet;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics2D;
- import java.awt.p_w_picpath.BufferedImage;
- import java.io.IOException;
- import java.util.Random;
- import javax.p_w_picpathio.ImageIO;
- import javax.servlet.ServletException;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- /**
- * create a validateCode p_w_picpath and validate user's input
- * @author Ahaha_Ge
- *
- */
- public class ValidateCodeServlet extends HttpServlet{
- private static final long serialVersionUID = 1L;
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- doPost(req,resp);
- }
- /**
- * generate validateCode p_w_picpath
- * p_w_picpath shape is rectangular with some lines and codes
- * codeCount is 4, code should contain 26 English chars and number
- */
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- int width = 160;
- int height = 40;
- int codeCount = 4;
- Random r = new Random();
- //create a buffered p_w_picpath instance
- BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- //create a graphics to render the p_w_picpath
- Graphics2D g = bi.createGraphics();
- //set context color and fill rectangular
- g.setColor(setRandomColor());
- g.fillRect(0, 0, width-1, height-1);
- //set context color and draw rectangular
- g.setColor(setRandomColor());
- g.drawRect(0, 0, width-1, height-1);
- //draw disturb lines
- for(int i=0; i<5; i++){
- g.setColor(setRandomColor());
- g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
- }
- //set font
- Font font = new Font("font",Font.PLAIN,height*3/4);
- g.setFont(font);
- //create and draw codes
- String codes = generateCodes(codeCount);
- for(int i=0; i<codes.length(); i++){
- g.drawString(String.valueOf(codes.charAt(i)), width*(i+1)/(codeCount+1), height*7/8);
- }
- //put codes into session
- HttpSession session = req.getSession();
- session.setAttribute("validateCode", codes);
- //forbid cache
- resp.setHeader("Pragma", "no-cache");
- resp.setHeader("Cache-Control", "no-cache");
- resp.setDateHeader("expires", 0);
- resp.setContentType("p_w_picpath/jpeg");
- //send p_w_picpath to output stream
- ServletOutputStream sos = resp.getOutputStream();
- ImageIO.write(bi, "jpeg", sos);
- sos.close();
- }
- //set Random color
- private Color setRandomColor(){
- int r = new Random().nextInt(256);
- int g = new Random().nextInt(256);
- int b = new Random().nextInt(256);
- Color c = new Color(r,g,b);
- return c;
- }
- //create codes set
- private char[] createCodesSet(){
- char[] c = new char[62];
- for(int i=0; i<26; i++){
- //add A to Z
- c[i] = (char)(i+65);
- //add a to z
- c[26+i] = (char)(i+97);
- }
- for(int i=0; i<10; i++){
- //add 0 to 9
- c[52+i] = (char)(i+48);
- }
- return c;
- }
- //create n codes
- private String generateCodes(int n){
- //codes set
- char[] codes = createCodesSet();
- StringBuffer sb = new StringBuffer();
- for(int i=0;i<n;i++){
- sb.append(codes[new Random().nextInt(codes.length)]);
- }
- return sb.toString();
- }
- public static void main(String[] args){
- System.out.println(new ValidateCodeServlet().setRandomColor());
- }
- }
Step2: 在web.xml中配置写好的ValidateCodeServelt
- <servlet>
- <servlet-name>validateCodeServlet</servlet-name>
- <servlet-class>servlet.ValidateCodeServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>validateCodeServlet</servlet-name>
- <url-pattern>/validateCodeServlet</url-pattern>
- </servlet-mapping>
Step3: 在使用验证码的地方,创建一个p_w_picpath控件,再改变src为ValidateCodeServlet
- <input type="p_w_picpath" id="p_w_picpath" width="160" height="40" name="code" src="validateCodeServlet"/>
Step4: 用javascript来实现刷新验证码,写一个按钮,当点击它时,定义一个方法,改变p_w_picpath控件的src,不要忘了newDate(),不然生成的验证码是一样的。
- <input type="button" name="fresh" value="fresh" onclick="freshValidateCode();"/>
- <script type="text/javascript">
- function freshValidateCode()
- {
- document.getElementById("p_w_picpath").setAttribute("src","validateCodeServlet?"+new Date());
- }
- </script>
总结:这么简单的功能写了两天,第一天竟然被画验证码给吓住了,这么多代码,这么多类,现在回过来看看,发现还是挺简单的,主要是参考了网上的代码,跟着理解了一遍,做了两遍,做的时候总是会忘,总是会出小错,终于作出来了,接着得写上传下载。