Servlet:response生成图片验证码
src 目录下com.xieyuan包MyServlet.java文件(Servlet文件)
package com.xieyuan; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.PrintWriter; import java.net.URLEncoder; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.corba.se.impl.javax.rmi.CORBA.Util; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class MyServlet extends HttpServlet { /** * Constructor of the object. */ public MyServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { execute(request, response); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { execute(request, response); } 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' }; public static Random random=new Random(); //生成随机数字,len为需要随机数字的个数 public static String getRandomString(int len) { StringBuilder builder=new StringBuilder(); for(int i=0;i<len;i++) { builder.append(CHARS[random.nextInt(CHARS.length)]) ; } return builder.toString(); } //随机生成颜色,座位背景色 public static Color getColor() { return new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)); } //取颜色的反色 public static Color getReverseColor(Color color) { return new Color(255-color.getRed(),255-color.getGreen(),255-color.getBlue()); } private void execute(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); //设置返回的文件编码 response.setContentType("image/jpeg"); //获取随机码 String getRandomCode=getRandomString(5); //将随机码放到Session中 request.getSession().setAttribute("randomcode", getRandomCode); int width=100; int height=30; Color color=getColor(); Color reverseColor=getReverseColor(color); //创建一个彩色图片 BufferedImage bi=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g=bi.createGraphics(); g.setFont(new Font(null,Font.BOLD,16)); g.setColor(color); g.fillRect(0,0,width,height); g.setColor(reverseColor); g.drawString(getRandomCode, 18,20); //绘制噪点,最多100个 for(int i=0,n=random.nextInt(100);i<n;i++) { g.drawRect(random.nextInt(width), random.nextInt(height), 1,1); } ServletOutputStream out=response.getOutputStream(); JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(out); encoder.encode(bi); out.flush(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { } }
配置好web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>MyServlet</servlet-name> <servlet-class>com.xieyuan.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/servlet/MyServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>接着部署您的WEB 应用,此时访问:
http://127.0.0.1:8080/Test/servlet/MyServlet
可以看到一张图片验证码。但是,这种效果好吗?这,并不是我们想要的,图片验证码应该混搭在HTML页面里,做登录等功能才对。
那么,接下来我们来做个JSP页面,直接使用项目WebRoot目录下的,index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script language="JavaScript" > function reloadImage() { <!--将按钮状态设置为不可用,当图片加载完成触发onload后,按钮状态就为可用了。这样可用避免重复获取--> document.getElementById("btn").disabled=true; <!--第一次连接的时候不会有问题,第二次连接时,假如你后面没有new Date().getTime(),加参数就会连接的时候拿缓存,没有连到服务器。加上时间函数就能保证你每次得到的不是浏览器的缓存。--> document.getElementById("img").src="servlet/MyServlet?timestamp="+new Date().getTime(); } </script> </head> <body> <img src="servlet/MyServlet" id="img" onload="btn.disabled=false;" /><br/><br/> <input type="button" value="换一张图片" onClick="reloadImage()" id="btn" /><br/> <script>document.write("页面最后更新:"+document.lastModified)</script> </body> </html>
此时,我直接访问:http://127.0.0.1:8080/Test/
结果就是我们想要的了
可以看到,无论我们点击多少次 “换一张图片”按钮,网页始终没有刷新,页面最后更新时间也没变,变的就是图片验证码!