1.首先先写一个把绘制的图片保存到本地的,后面用servlet展现在页面上.
2.绘制验证码到本地保存,再写把验证码保存到Servlet的页面.
绘制图片 将绘制的图片保存到本地保存.
package junit.test; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import org.junit.Test; import cn.itcast.VCode; public class Demo1 { @Test public void fun1() throws FileNotFoundException, IOException{ //创建一张内存中的图片 BufferedImage img = new BufferedImage(100, 35, BufferedImage.TYPE_INT_RGB); //获取当前图片的画笔 Graphics g = img.getGraphics(); //画笔 //g.setColor(new Color(240,240,240)); //背景色 //g.fillRect(0, 0, 100, 35); //g.setColor(Color.CYAN); //颜色 //g.drawLine(5, 5, 100-5, 35-5); //直线 //g.drawRect(5, 5, 90, 25); //矩形 //g.fillRect(5, 5, 90, 25); //填充 g.setFont(new Font("幼圆",Font.BOLD,26)); g.drawString("董老师", 5, 28); //保存图片 ImageIO.write(img, "JPEG", new FileOutputStream("E:\\a.jpg")); } }
E盘就会生成一个jpg的图片,E:\\a.jpg
如何将董老师图片输出到web页面呢,那么需要create一个Servlet,这里我create一个DongServlet用来绘制董老师这张图片,DongServlet的代码如下.
package cn.itcast; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DongServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建一张内存中的图片 BufferedImage img = new BufferedImage(100, 35, BufferedImage.TYPE_INT_RGB); //获取当前图片的画笔 Graphics g = img.getGraphics(); //画笔 g.setColor(new Color(240,240,240)); //背景色 g.fillRect(0, 0, 100, 35); g.setColor(Color.PINK); //颜色 g.drawLine(5, 5, 100-5, 35-5); //直线 g.drawRect(5, 5, 90, 25); //矩形 //g.fillRect(5, 5, 90, 25); //填充 g.setFont(new Font("幼圆",Font.BOLD,26)); g.drawString("董老师", 5, 28); //保存图片 ImageIO.write(img, "JPEG",response.getOutputStream()); //向客户端写 } }并且修改一下我们的index.jsp页面的代码,
<body> This is my JSP page. <br> 验证码:<img src="/yanzhengma/servlet/AServlet"><br> </body>
然后开启Tomcat运行项目,在浏览器访问项目,如下图所示.
绘制验证码 下面开始绘制验证码的图片,首先我们写一个VCode的类,用来绘制验证码的图片.
package cn.itcast; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; import com.sun.org.apache.commons.digester.rss.Image; public class VCode { private int w = 70; //宽 private int h = 35; //宽 private Color bgColor = new Color(240,240,240); private Random random = new Random(); private StringBuilder code = new StringBuilder(4); private BufferedImage createImage(){ /* * 1创建图片 * 2设置背景色 */ //创建图片 BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); //设置画笔颜色 img.getGraphics().setColor(bgColor); //填充一个与图片一样大小的矩形!即设置背景色! img.getGraphics().fillRect(0, 0, w, h); return img; } private Color randomColor(){ int r = random.nextInt(256); int g = random.nextInt(256); int b = random.nextInt(256); return new Color(r,g,b); } /* * 字体名,样式,字号 */ private String[] fontNames = {"宋体","华文楷体","黑体","华文新魏","华文隶书","微软雅黑","楷体_GB2312"}; //private int[] fontstyles = {0,1,2,3}; private int[] fontSize = {24,25,26,27,28}; //字号范围 private Font randomFont(){ int index = random.nextInt(fontNames.length); //如果数组长度为7,数值为0~6,合法下标 String name = fontNames[index]; int style = random.nextInt(4); //0,1,2,3 index = random.nextInt(fontSize.length); //随机生成fontSize的下标 int size = fontSize[index]; return new Font(name,style,size); } private String codes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //随机生成字符 private String randomChar(){ int index = random.nextInt(codes.length()); return codes.charAt(index) + ""; } private void drawLine(BufferedImage img){ Graphics2D g = (Graphics2D)img.getGraphics(); g.setColor(Color.black); g.setStroke(new BasicStroke(1.5F)); for(int i = 0; i < 5;i++){ int x1 = random.nextInt(w); int y1 = random.nextInt(h); int x2 = random.nextInt(w); int y2 = random.nextInt(h); g.drawLine(x1, y1, x2, y2); } } //用户调用这个方法获取图片 public BufferedImage getImage(){ /* * 我们要写字符 * 写的是随机生成!范围是: 0~9A~Za~z * 什么字体,字号多大,是否粗体? 都是随机的! * 字符的颜色,每个字符是否要相同的颜色? 都是随机 */ BufferedImage img = createImage(); Graphics g = img.getGraphics(); //画东西 for(int i = 0;i<4;i++){ String ch = this.randomChar(); //获取随机字符 code.append(ch); //记录下来生成的字符 g.setColor(this.randomColor()); //随机颜色 g.setFont(this.randomFont()); //随机字体 g.drawString(ch, w/4*i, h-5); } this.drawLine(img); //添加干扰线 return img; } //保存图片的 public String getCode(){ return code.toString(); } //保存图片 public static void saveImage(BufferedImage img,OutputStream out) throws IOException { ImageIO.write(img,"JPEG",out); } }
再create一个demo类,在类里面调用VCode的方法,把验证码绘制到本地保存.
package junit.test; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.junit.Test; import cn.itcast.VCode; public class Demo1 { @Test public void fun2() throws FileNotFoundException, IOException{ VCode v = new VCode(); BufferedImage img = v.getImage(); VCode.saveImage(img, new FileOutputStream("E:\\a.jpg")); } }
这样就把验证码绘制到本地保存了,图片下.
然后把验证码绘制到web页面上,create一个BServlet.
package cn.itcast; import java.awt.image.BufferedImage; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { VCode vc = new VCode(); BufferedImage img = vc.getImage(); System.out.println(vc.getCode()); VCode.saveImage(img, response.getOutputStream()); } }
还有index的页面代码,为了点击看不清,换一张换一张验证码而不刷新整个网页,从而写了一个 function _chage().
<body> This is my JSP page. <br> 验证码:<input type="text" name="vcode" size="3"/> <img id="vc" src="/yanzhengma/servlet/BServlet" border="2"> <a href="javascript:_chage()">看不清,换一张</a><br> <script type="text/javascript"> function _chage(){ var img = document.getElementById("vc"); img.src = "/yanzhengma/servlet/BServlet?a=" + new Date().getTime(); } </script> <input type="submit" value="提交"/> </body>
页面展示图.