1. 程式人生 > >java繪製圖片驗證碼(看不清,換一張)

java繪製圖片驗證碼(看不清,換一張)

現在正式開發中圖片驗證碼好像已經很少用了,但是為了加深個人印象,做個小筆記。

驗證碼實現分析

  1. 在用java生成一張固定尺寸的圖片,會用到api是BufferedImage(int width,int height,int type);
  2. 給圖片上繪製出隨機的文字、字母或者數字,用到API是Graphics2D(繪製文字)和Random(生成隨機數)
  3. 繪製隨機的干擾線用到Api為graphics2d.drawLine(x1, y1, x2, y2);
  4. 將圖片展示到瀏覽器上用到Api為 ImageIO

生成圖片的具體java程式碼如下


/**
 * @author
jiangrongtao 圖片驗證碼 */
public class VerificationCodeUtils { private static List<Color> colors; static{ colors=new ArrayList<>(); colors.add(Color.CYAN); colors.add(Color.yellow); colors.add(Color.PINK); colors.add(Color.green); } /** * 1、繪製圖片 2、給圖片上隨機繪製文字 3、隨機繪製干擾線4、將圖片繪製到瀏覽器 * @param
response HttpServletResponse * @param width 圖片寬度 * @param height 圖片高度 * @param fontNum 數字個數 * @return 返回隨機生成的驗證碼 */
public static String drawVerificationCode(HttpServletResponse response, int width, int height,int fontNum) { /** * 生成圖片 */ BufferedImage bufferedImage = new
BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); // 繪製文字 Graphics2D graphics2d = bufferedImage.createGraphics(); graphics2d.setFont(new Font("華文行楷", Font.ITALIC | Font.BOLD, 20));// 設定字型樣式 String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; StringBuilder sb=new StringBuilder(); // 隨機取四個值 Random random = new Random(); for (int i = 1; i <= fontNum; i++) { char ch = words.charAt(random.nextInt(words.length())); graphics2d.setColor(getColor(random));// 設定字型顏色 graphics2d.drawString(ch + "", (width/fontNum)*i-30, height/2+10); sb.append(ch); } //繪製干擾線 for (int i = 0; i <5; i++) { graphics2d.setColor(getColor(random)); int x1=random.nextInt(width); int x2=random.nextInt(width); int y1=random.nextInt(height); int y2=random.nextInt(height); graphics2d.drawLine(x1, y1, x2, y2); } try { ImageIO.write(bufferedImage, "jpg", response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } /** * 隨機獲取一種顏色 * @param random * @return Color */ private static Color getColor(Random random){ return random==null?null:colors.get(random.nextInt(4)); } }

在具體用的時候直接

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String code=VerificationCodeUtils.drawVerificationCode(resp,160,40,4);
            System.out.println("code="+code);
    }

這裡我打印出了隨機生成的驗證碼,實際開發中可以把這個存到資料庫來跟客戶端提交的驗證碼進行比對驗證

實現”看不清,換一張“

這裡可以用js或者ajax實習非同步區域性重新整理,具體如下

js實現如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>驗證碼</title>
</head>
<body>
     <form action="/MyWebTest/login" method="post">
           <img id="_img" alt="" src="/MyWebTest/verifyCode">
           <a href="#" onclick="changeCode();">看不清,換一張</a><br/>
     </form>
     <script type="text/javascript">
          function changeCode(){
              var img=document.getElementById("_img");
              img.src="/MyWebTest/verifyCode?"+new Date().getTime();
          }
     </script>
</body>
</html>

Jquery方式實現

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
<title>驗證碼</title>
</head>
<body>
     <form action="/MyWebTest/login" method="post">
           <img id="_img" alt="" src="/MyWebTest/verifyCode">
           <a href="#">看不清,換一張</a><br/>
     </form>
     <script type="text/javascript">
          $(document).ready(function () {  
              $("a").click(function() {

                 var src= $("#_img").attr("src","/MyWebTest/verifyCode?"+new Date().getTime());

              });
             });
     </script>
</body>
</html>

注意:

  1. a標籤中的href屬性值用”#“號佔位,如果用”javascript:void(0)“的話會出現IO異常。
  2. 給”/MyWebTest/verifyCode”後面拼接new Date().getTime())引數是為了防止瀏覽器快取導致驗證碼不重新整理;
  3. 用jQuery的時候匯入對應的js庫檔案
<script type="text/javascript" src="http://xxxx/jquery-3.2.1.min.js"></script>

總結

  學一點,總結一點,每天提升一點。