首頁>Club>
求助
5
回覆列表
  • 1 # 科技小夥子丶

    package com.bbs.servlet;

    import java.awt.Color;

    import java.awt.Font;

    import java.awt.Graphics;

    import java.awt.image.BufferedImage;

    import java.io.IOException;

    import java.io.OutputStream;

    import java.io.PrintWriter;

    import java.util.Random;

    import javax.imageio.ImageIO;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import com.sun.image.codec.jpeg.JPEGCodec;

    import com.sun.image.codec.jpeg.JPEGImageEncoder;

    public class Image extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    throws ServletException, IOException {

    response.setContentType("image/jpeg");

    OutputStream out = response.getOutputStream();

    response.setHeader("Pragma","No-cache");

    response.setHeader("Cache-Control","no-cache");

    response.setDateHeader("Expires", 0);

    int width = 60, height = 20;

    BufferedImage image = new BufferedImage(width, height,

    BufferedImage.TYPE_INT_RGB);

    // 獲取圖形上下文

    Graphics g = image.getGraphics();

    // 生成隨機類

    Random random = new Random();

    // 設定背景色

    g.setColor(getRandColor(200, 250));

    g.fillRect(0, 0, width, height);

    // 設定字型

    g.setFont(new Font("Times New Roman", Font.PLAIN, 18));

    // 隨機產生155條幹擾線,使圖象中的認證碼不易被其它程式探測到

    g.setColor(getRandColor(180, 200));

    for (int i = 0; i < 155; i++) {

    int x = random.nextInt(width);

    int y = random.nextInt(height);

    int xl = random.nextInt(12);

    int yl = random.nextInt(12);

    g.drawLine(x, y, x + xl, y + yl);

    }

    // 取隨機產生的認證碼(4位數字)

    String sRand =setRandValue(request);

    if(sRand!=null)

    for (int i = 0; i < sRand.length(); i++) {

    g.setColor(new Color(20 + random.nextInt(200), 20 + random

    .nextInt(200), 20 + random.nextInt(200)));

    // 呼叫函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成

    g.drawString(sRand.charAt(i) + "", 13 * i + 6, 16);

    }

    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

    encoder.encode(image);

    // 圖象生效

    g.dispose();

    // 輸出圖象到頁面

    // ImageIO.write(image, "JPG", response.getOutputStream());

    out.flush();

    out.close();

    }

    Color getRandColor(int fc, int bc) {// 給定範圍獲得隨機顏色

    Random random = new Random();

    if (fc > 255)

    fc = 255;

    if (bc > 255)

    bc = 255;

    int r = fc + random.nextInt(bc - fc);

    int g = fc + random.nextInt(bc - fc);

    int b = fc + random.nextInt(bc - fc);

    return new Color(r, g, b);

    }

    //48-57對應0-9;65-90對應A-Z;97-122對應a-z;

    String setRandValue(HttpServletRequest request) {

    Random random = new Random();

    String sRand = "";

    //這裡是生成驗證碼的位數

    for (int i = 0; i < 4; i++) {

    char c = 0;

    int k = random.nextInt(3);

    switch (k) {

    case 0:

    c = (char) (random.nextInt(10) + 48);

    break;

    case 1:

    c = (char) (random.nextInt(26) + 65);

    break;

    case 2:

    c = (char) (random.nextInt(26) + 97);

    }

    sRand += c;

    }

    request.getSession().setAttribute("rands", sRand);

    return sRand;

    }

    }

  • 2 # 小小猿愛嘻嘻

    這個實現起來不難,Java生成隨機驗證碼,最主要的是繪製字元及干擾線,下面我簡單介紹一下實現過程,感興趣的朋友可以嘗試一下:

    01設定驗證碼樣式

    首先,設定需要生成驗證碼的樣式,這個是繪製驗證碼的基礎和必須條件,包括字型、可選字符集、背景色、影象寬度、影象高度、字元個數等,後面繪製函式就是根據這些設定的屬性繪製驗證碼,可以設計的複雜,也可以設計的簡單,這裡我只做了簡單必須要的設定:

    02繪製驗證碼

    樣式設定完成後,我們就可以直接繪製驗證碼了,測試程式碼如下,基本思想先建立一個圖片緩衝區(即BufferedImage物件),然後得到繪製環境(即Graphics2D物件),最後再直接根據屬性繪製驗證碼並儲存即可,包括背景色、字型、旋轉角度的設計以及干擾線的繪製等,程式碼量比較多,但理解起來並不難:

    03生成驗證碼

    繪製函式編寫完成後,就是在main函式中呼叫生成驗證碼,這裡就非常簡單了,建立一個VerifyCode類物件,然後直接呼叫drawImage函式即可,程式成功執行後,會在指定目錄下生成一個驗證碼圖片:

    至此,我們就完成了利用Java生成隨機驗證碼。總的來說,整個過程非常簡單,最主要的是字元和干擾線的繪製,只要你有一定Java基礎,熟悉一下上面的程式碼和示例,很快就能掌握的,網上也有相關教程和資料,介紹的非常詳細,感興趣的話,可以搜一下,希望以上分享的內容能對你有所幫助吧,也歡迎大家評論、留言進行補充。

  • 3 # IT資訊i

    【北京】IT技術人員面對面試、跳槽、升職等問題,如何快速成長,獲得大廠入門資格和升職加薪的籌碼?與大廠技術大牛面對面交流,解答你的疑惑。《從職場小白到技術總監成長之路:我的職場焦慮與救贖》活動連結:http://mk1.top/1ndjnvb

    最後邊給出了完整的程式碼。

    //首先定義一個自己的類並且去繼承HttpServlet這個類

    public class CheckImg extends HttpServlet{

    //複寫HttpServlet中的doGet方法

    public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,

    IOException{

    //準備一張畫紙,將驗證碼中的數字字母寫到這張畫紙中

    int width = 120;

    int height = 30;

    BufferedImage bufi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    //這裡面的width、height、就是這張畫紙的長寬。BufferedImage.TYPE_INT_RGB就是這張畫紙基於

    //RGB三原色來進行畫

    //這個時候並沒有在這張紙上書寫任何內容,但是已經可以像客戶端響應請求了

    ImageIO.write(bufi, "jpg", resp.getOutputStream());

    }

    這時候可以在瀏覽器上看到一個長120,高30的矩形小框。

    //設定畫筆顏色

    g.setColor(Color.WHITE);

    //將這個顏色填充到整個畫紙

    g.fillRect(0,0,width,height);

    瀏覽器上就顯示出來一個白色的小框也就是上邊定義的畫紙

    開始在畫紙上畫驗證碼了。

    //定義圖片上可以寫什麼資料

    String data = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";

    //定義書寫在畫紙上的起始位置

    int x =15;

    int y =25;

    //定義一個隨機數

    Random r = new Random();

    //定義一個StringBuilder字串緩衝區

    StringBuilder sb = new StringBuilder();

    //定義一個迴圈給畫紙上寫四個資料

    for(int i = 0; i < 4; i++){

    //從data中隨機獲取一個下標的資料

    char c = data.charAt(r.nextInt(data.length()));

    //每寫一個數據就將這個數放到字串緩衝區中

    sb.append(c+"")

    //隨機生成畫筆的顏色,RGB三原色隨機在0-256中隨機生成

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //設定字型

    g.setFont(new Font("黑體",Font.BOLD,26));

    //將資料寫到畫紙上

    g.drawString(c+"",x,y);

    //沒寫完一個調整下一個資料寫的位置

    x += 25;

    }

    //迴圈結束也就是所有的資料都放在字串緩衝區中

    HttpSession session = req.getSession();

    session.setAttribute("checkNum",sb.toString());

    再重啟tomcat在瀏覽器上能看到書寫驗證碼了

    在畫紙上新增干擾資訊

    //新增線型別的干擾資訊

    for(int i = 0; i < 15 ; i++){

    //同樣設定線的顏色

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //開始劃線,這裡需要的四個引數中前兩個是線開頭的左邊,後邊兩個是線結束的座標

    g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));

    }

    //新增點型別干擾資訊

    for (int i = 0 ; i < 150 ; i++){

    //設定點的顏色

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //開始畫點,實質上這是畫橢圓,將上半軸半徑,左半軸半徑設定為0就可以看成是一個點

    g.drawOval(r.nextInt(width),r.nextInt(height),0,0);

    }

    在瀏覽器上就能看到驗證碼上充滿點和橫線,降低辨識度

    貌似還沒有達到想要的結果,將字型設定一點傾斜度就更好了

    //設定資料旋轉

    double theta =(30 - (r.nextInt(60)))*Math.PI/180;

    g.rotate(theta,x,24);

    //將資料寫到畫紙上

    g.drawString(c+"",x,y);

    //設定完旋轉要調回,防止資料旋轉的看不到

    g.rotate(-theta,x,24);

    可以看到圖片中的資料進行了略微的傾斜

    html註冊頁面程式碼這裡只截取了body和script部分的程式碼

    <body>

    <fieldset>

    <legend>註冊頁面</legend>

    <form action="/day02/register2" method="post" >

    <table>

    <tr>

    <td>使用者名稱:</td>

    <td><input type="text" name="userName" /><span></span></td>

    </tr>

    <tr>

    <td>

    密碼:

    </td>

    <td>

    <input type="password" name="password" />

    </td>

    </tr>

    <tr>

    <td>

    確認密碼:

    </td>

    <td>

    <input type="password" name="repassword" />

    <span></span>

    </td>

    </tr>

    <tr>

    <td>

    性別:

    </td>

    <td>

    <input type="radio" name="sex" value="男" />男

    <input type="radio" name="sex" value="女" />女

    <span></span>

    </td>

    </tr>

    <tr>

    <td>愛好:</td>

    <td>

    <input type="checkbox" name="hobby" value="唱" />唱

    <input type="checkbox" name="hobby" value="跳" />跳

    <input type="checkbox" name="hobby" value="rap" />rap

    <input type="checkbox" name="hobby" value="籃球" />籃球

    <span></span>

    </td>

    </tr>

    <tr>

    <td>國籍:</td>

    <td>

    <select name="country">

    <option value="none">--請選擇國籍--</option>

    <option value="中國">中國</option>

    <option value="南韓">南韓</option>

    <option value="日本">日本</option>

    <option value="美國">美國</option>

    </select>

    <span></span>

    </td>

    </tr>

    <tr>

    <td>自我評價:</td>

    <td>

    <textarea rows="10px" cols="20px" name="describe" ></textarea>

    </td>

    </tr>

    <tr>

    <td>

    驗證碼:

    </td>

    <td>

    //定義一個input標籤,使用者輸入驗證碼

    <input type="text" name="check"/>

    //input標籤後連結了上邊寫的驗證碼生成Servlet程式

    <img src="/day02/demo" onclick="checkImg()" style = "cursor: pointer">

    </td>

    </tr>

    </table>

    <input type="submit" value="提交" />

    <input type="button" value="驗證" />

    </form>

    </fieldset>

    </body>

    <script type="text/javascript">

    function checkImg() {

    //透過ID屬性拿到img標籤

    var img = document.getElementById("img");

    //當瀏覽器發現兩次請求的URL相同時不會主動的向伺服器請求圖片

    //所以需要實時的更改URL,這裡採用的是在URL後邊拼接一個當前系統時間的毫秒值

    //這樣就能保證每一毫秒的URL都不同,從而瀏覽器會給伺服器傳送圖片的請求

    img.src ="/day02/demo?"+new Date().getTime()

    }

    </script>

    完整的程式碼

    @WebServlet(urlPatterns = "/demo")

    public class CheckImg extends HttpServlet {

    //複寫HttpServlet中的doGet方法

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,

    IOException{

    //準備一張畫紙,將驗證碼中的數字字母寫到這張畫紙中

    int width = 120;

    int height = 30;

    BufferedImage bufi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    //這裡面的width、height、就是這張畫紙的長寬。BufferedImage.TYPE_INT_RGB就是這張畫紙基於

    //RGB三原色來進行畫

    //獲取一個畫筆物件,給圖片上畫畫

    Graphics2D g = (Graphics2D) bufi.getGraphics();

    //設定畫筆顏色

    g.setColor(Color.WHITE);

    //將這個顏色填充到整個畫紙

    g.fillRect(0,0,width,height);

    //定義圖片上可以寫什麼資料

    String data = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";

    //定義書寫在畫紙上的起始位置

    int x =15;

    int y =25;

    //定義一個隨機數

    Random r = new Random();

    //定義一個迴圈給畫紙上寫四個資料

    for(int i = 0; i < 4; i++){

    //從data中隨機獲取一個下標的資料

    char c = data.charAt(r.nextInt(data.length()));

    //隨機生成畫筆的顏色,RGB三原色隨機在0-256中隨機生成

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //設定字型

    g.setFont(new Font("黑體",Font.BOLD,26));

    //設定資料旋轉

    double theta =(30 - (r.nextInt(60)))*Math.PI/180;

    g.rotate(theta,x,24);

    //將資料寫到畫紙上

    g.drawString(c+"",x,y);

    //設定完旋轉要調回,防止資料旋轉的看不到

    g.rotate(-theta,x,24);

    //將資料寫到畫紙上

    g.drawString(c+"",x,y);

    //g.rotate(-theta,r.nextInt(width),24);

    //設定完旋轉要調回,防止資料旋轉的看不到

    g.rotate(-((10)*3.14/180),15*i+8,7);

    //每寫完一個調整下一個資料寫的位置

    x += 25;

    }

    //新增線型別的干擾資訊

    for(int i = 0; i < 15 ; i++){

    //同樣設定線的顏色

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //開始劃線,這裡需要的四個引數中前兩個是線開頭的左邊,後邊兩個是線結束的座標

    g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));

    }

    //新增點型別干擾資訊

    for (int i = 0 ; i < 150 ; i++){

    //設定點的顏色

    g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));

    //開始畫點,實質上這是畫橢圓,將上半軸半徑,左半軸半徑設定為0就可以看成是一個點

    g.drawOval(r.nextInt(width),r.nextInt(height),0,0);

    }

    //給客戶端響應請求

    ImageIO.write(bufi, "jpg", resp.getOutputStream());

    }

    }

  • 中秋節和大豐收的關聯?
  • 老公出軌了,還騙我,我有他出軌的照片,我該怎麼做?