設定session驗證碼有效時間,定時刪除session中的驗證碼
阿新 • • 發佈:2019-02-14
contorller.java
import java.util.Timer; import java.util.TimerTask; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.yasinyt.loan.admin.util.VerifyCodeUtils; @Controller @RequestMapping("sys/yzm") public class YZMController { private Logger log = LoggerFactory.getLogger(YZMController.class); @RequestMapping(value = "getYzm", method = RequestMethod.GET) public void getYzm(HttpServletResponse response, HttpServletRequest request) { try { response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); // 生成隨機字串 String verifyCode = VerifyCodeUtils.generateVerifyCode(4); // 存入會話session HttpSession session = request.getSession(true); String attrName = "_code"; session.setAttribute(attrName, verifyCode.toLowerCase()); // 生成驗證碼流 int w = 99, h = 38; VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode); //定時5分鐘刪除驗證碼 this.removeAttrbute(session, attrName); } catch (Exception e) { log.error("獲取驗證碼異常:{}",e.getCause().toString()); } } /** * 設定5分鐘後刪除session中的驗證碼 * @param session * @param attrName */ private void removeAttrbute(final HttpSession session, final String attrName) { final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // 刪除session中存的驗證碼 session.removeAttribute(attrName); timer.cancel(); } }, 5 * 60 * 1000); } }
VerifyCodeUtils.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Random; import javax.imageio.ImageIO; public class VerifyCodeUtils { // 使用到Algerian字型,系統裡沒有的話需要安裝字型,字型只顯示大寫,去掉了1,0,i,o幾個容易混淆的字元 public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; private static Random random = new Random(); /** * 使用系統預設字元源生成驗證碼 * * @param verifySize * 驗證碼長度 * @return */ public static String generateVerifyCode(int verifySize) { return generateVerifyCode(verifySize, VERIFY_CODES); } /** * 使用指定源生成驗證碼 * * @param verifySize * 驗證碼長度 * @param sources * 驗證碼字元源 * @return */ public static String generateVerifyCode(int verifySize, String sources) { if (sources == null || sources.length() == 0) { sources = VERIFY_CODES; } int codesLen = sources.length(); Random rand = new Random(System.currentTimeMillis()); StringBuilder verifyCode = new StringBuilder(verifySize); for (int i = 0; i < verifySize; i++) { verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1))); } return verifyCode.toString(); } /** * 生成隨機驗證碼檔案,並返回驗證碼值 * * @param w * @param h * @param outputFile * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException { String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, outputFile, verifyCode); return verifyCode; } /** * 輸出隨機驗證碼圖片流,並返回驗證碼值 * * @param w * @param h * @param os * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException { String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, os, verifyCode); return verifyCode; } /** * 生成指定驗證碼影象檔案 * * @param w * @param h * @param outputFile * @param code * @throws IOException */ public static void outputImage(int w, int h, File outputFile, String code) throws IOException { if (outputFile == null) { return; } File dir = outputFile.getParentFile(); if (!dir.exists()) { dir.mkdirs(); } try { outputFile.createNewFile(); FileOutputStream fos = new FileOutputStream(outputFile); outputImage(w, h, fos, code); fos.close(); } catch (IOException e) { throw e; } } /** * 輸出指定驗證碼圖片流 * * @param w * @param h * @param os * @param code * @throws IOException */ public static void outputImage(int w, int h, OutputStream os, String code) throws IOException { int verifySize = code.length(); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Random rand = new Random(); Graphics2D g2 = image.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Color[] colors = new Color[5]; Color[] colorSpaces = new Color[] { Color.BLACK, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW }; float[] fractions = new float[colors.length]; for (int i = 0; i < colors.length; i++) { colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; fractions[i] = rand.nextFloat(); } Arrays.sort(fractions); g2.setColor(Color.WHITE);// 設定邊框色 g2.fillRect(0, 0, w, h); Color c = getRandColor(150, 250); g2.setColor(c);// 設定背景色 // g2.fillRect(0, 2, w, h - 4); // 繪製干擾線 Random random = new Random(); g2.setColor(getRandColor(160, 200));// 設定線條的顏色 for (int i = 0; i < 20; i++) { int x = random.nextInt(w - 1); int y = random.nextInt(h - 1); int xl = random.nextInt(6) + 1; int yl = random.nextInt(12) + 1; g2.drawLine(x, y, x + xl + 40, y + yl + 20); } //新增噪點 float yawpRate = 0.05f;// 噪聲率 int area = (int) (yawpRate * w * h); for (int i = 0; i < area; i++) { int x = random.nextInt(w); int y = random.nextInt(h); int rgb = getRandomIntColor(); image.setRGB(x, y, rgb); } // shear(g2, w, h, c);// 使圖片扭曲 g2.setColor(getRandColor(100, 160)); int fontSize = h - 6; Font font = new Font("Arial", Font.BOLD, fontSize); g2.setFont(font); char[] chars = code.toCharArray(); for (int i = 0; i < verifySize; i++) { AffineTransform affine = new AffineTransform(); affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2); g2.setTransform(affine); g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10); } g2.dispose(); ImageIO.write(image, "jpg", os); } private static Color getRandColor(int fc, int bc) { 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); } private static int getRandomIntColor() { int[] rgb = getRandomRgb(); int color = 0; for (int c : rgb) { color = color << 8; color = color | c; } return color; } private static int[] getRandomRgb() { int[] rgb = new int[3]; for (int i = 0; i < 3; i++) { rgb[i] = random.nextInt(255); } return rgb; } }