1, the verification code generated class:
import java.util.Random; import java.awt.image.BufferedImage; import java.awt.Graphics; import java.awt.Font; import java.awt.Color; /** * Code generator class, may generate a digital, uppercase, lowercase, and mixing the three types of codes. Support for custom code to verify the number of characters; support for custom code size of the picture; support for special characters to be excluded from the definition; * Number of custom support line interference; support custom color graphic codes */ public class ValidateCode { /** * Code type only numbers 0-9 */ public static final int TYPE_NUM_ONLY = 0; /** * Code type only letters, uppercase letters, lowercase letters mixed */ public static final int TYPE_LETTER_ONLY = 1; /** * The type of digital codes, uppercase letters, lowercase letters mixed */ public static final int TYPE_ALL_MIXED = 2; /** * The type of digital codes, mixed uppercase */ public static final int TYPE_NUM_UPPER = 3; /** * The type of digital codes, mixed lowercase */ public static final int TYPE_NUM_LOWER = 4; /** * Code type only uppercase letters */ public static final int TYPE_UPPER_ONLY = 5; /** * Code type only lowercase */ public static final int TYPE_LOWER_ONLY = 6; private ValidateCode() { } /** Generating a verification code string * * * @param type * Type codes, refer to the static properties of the class * @param length * Length codes, an integer greater than 0, * @param exChars * Need to exclude special characters (only numbers, letters, codes efficiently mixed, without exclusion was null) * @return 验证码字符串 */ public static String generateTextCode(int type, int length, String exChars) { if (length <= 0) return ""; StringBuffer code = new StringBuffer(); int i = 0; R & lt the Random = new new the Random (); Switch (type) { // only digital Case TYPE_NUM_ONLY: the while (I < length) { int T = r.nextInt (10 ); IF (exChars == null || exChars.indexOf (T + "") <0) { // exclude special characters code.append (t); i++; } } BREAK ; // only letters (i.e. uppercase letters, lowercase letters mixed) Case TYPE_LETTER_ONLY: the while (I < length) { int T = r.nextInt (123 ); IF ((T> 97 || = (T> = 65 && T <= 90)) && (exChars == null || exChars.indexOf (( char ) T) <0 )) { code.append((char) t); i++; } } BREAK ; // numbers, uppercase letters, lowercase letters mixed Case TYPE_ALL_MIXED: the while (I < length) { int T = r.nextInt (123 ); IF ((T> 97 || = (T> T && = 65 <= 90) || (T> T && = 48 <= 57 is )) && (exChars == null || exChars.indexOf (( char ) T) <0 )) { code.append((char) t); i++; } } break; // 数字、大写字母混合 case TYPE_NUM_UPPER: while (i < length) { int t = r.nextInt(91); if ((t >= 65 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) { code.append((char) t); i++; } } break; // 数字、小写字母混合 case TYPE_NUM_LOWER: while (i < length) { int t = r.nextInt(123); if ((t >= 97 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) { code.append((char) t); i++; } } break; // 仅大写字母 case TYPE_UPPER_ONLY: while (i < length) { int t = r.nextInt(91); if ((t >= 65) && (exChars == null || exChars.indexOf((char) t) < 0)) { code.append((char) t); i++; } } break; // 仅小写字母 case TYPE_LOWER_ONLY: while (i < length) { int t = r.nextInt(123); if ((t >= 97) && (exChars == null || exChars.indexOf((char) t) < 0)) { code.append((char) t); i++; } } break; } return code.toString(); } /** * Verification code has been generated CAPTCHA image * * @param textCode * Text Code * @param width * Image Width * @param height * Image Height * @param interLine * The number of lines of picture interference * @param randomLocation * The level of the position of each character whether random * @param backColor * Color pictures, if it is null, then the use of random colors * @param foreColor * Font color, if it is null, then the use of random colors * @param lineColor * Line color interference, if it is null, then random color * @return 图片缓存对象 */ public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor) { BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = bim.getGraphics(); // 画背景图 g.setColor(backColor == null ? getRandomColor() : backColor); g.fillRect(0, 0, width, height); // 画干扰线 Random r = new Random(); if (interLine > 0) { int x = 0, y = 0, x1 = width, y1 = 0; for (int i = 0; i < interLine; i++) { g.setColor(lineColor == null ? getRandomColor() : lineColor); y = r.nextInt(height); y1 = r.nextInt(height); g.drawLine(x, y, x1, y1); } } // write code // g.setColor (getRandomColor ()); // g.setColor (isSimpleColor Color.BLACK:? Color.WHITE); // font size of the image height% 80 int fsize = ( int ) ( 0.8 * height ); int FX = height - fsize; int FY = fsize; g.setFont ( new new the Font ( "the Default" , Font.PLAIN, fsize)); // write the character codes for ( int I = 0; I <textCode.length (); I ++ ) { fy = randomLocation (? int ) ((Math.random () * 0.3 + 0.6) * height): fy; // each character level if random g.setColor (foreColor == null ? :; getRandomColor () foreColor) g.drawString(textCode.charAt(i) + "", fx, fy); fx += fsize * 0.9; } g.dispose (); return bim; } /** * Generate image verification code * * @param type * Type codes, refer to the static properties of the class * @param length * Code characters in length, an integer greater than 0, * @param exChars * Subject to exclude special characters * @param width * Image Width * @param height * Image Height * @param interLine * The number of lines of picture interference * @param randomLocation * The level of the position of each character whether random * @param backColor * Color pictures, if it is null, then the use of random colors * @param foreColor * Font color, if it is null, then the use of random colors * @param lineColor * Line color interference, if it is null, then random color * @return 图片缓存对象 */ public static BufferedImage generateImageCode(int type, int length, String exChars, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor) { String textCode = generateTextCode(type, length, exChars); BufferedImage bim = generateImageCode(textCode, width, height, interLine, randomLocation, backColor, foreColor, lineColor); return bim; } /** * Generates random colors * * @return */ private static Color getRandomColor() { Random r = new Random(); Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)); return c; } }
2、Controller
/** Generating codes * * @param request * @param response * @throws IOException * @ ValidateCode.generateTextCode (character type codes, length codes, special characters should be excluded) * @ ValidateCode.generateImageCode (verification code text, picture width, picture height, the number of lines of interference, whether random height position of the character, image color, font color, line color interference) */ @RequestMapping(value = "validateCode") public void validateCode(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setHeader("Cache-Control", "no-cache"); String verifyCode = ValidateCode.generateTextCode(ValidateCode.TYPE_NUM_LOWER, 4, null); request.getSession().setAttribute("validateCode", verifyCode); response.setContentType("image/jpeg"); BufferedImage bim = ValidateCode.generateImageCode(verifyCode, 90, 30, 5, true, Color.WHITE, Color.BLUE, null); ImageIO.write(bim, "JPEG", response.getOutputStream()); } /** * Logon request * @param */ @RequestMapping(value = "login", method = RequestMethod.POST, produces = "text/html; charset=utf-8") public String login(HttpServletRequest request, HttpServletResponse response, UserEntity user) { //首先进行验证码验证 Session session = SecurityUtils.getSubject().getSession(); String code = (String) session.getAttribute("validateCode"); String submitCode = WebUtils.getCleanParam(request, "validateCode"); if (StringUtils.isEmpty(submitCode) || !StringUtils.equals(code,submitCode.toLowerCase())) { request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100000); request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_VALIDATECODE); return "login"; } // I want to get SecurityUtils.getSubject () object. . Access address must follow within interception of shiro address. Not a null pointer then will report the Subject Sub = SecurityUtils.getSubject (); // user account and password input into the memory ,, .. UsernamePasswordToken object and then compare the internal authentication shiro, // authentication executor process referred ShiroDbRealm in doGetAuthenticationInfo // performs the above authentication is successful when the downwardly authentication failure will be thrown UsernamePasswordToken token = new new UsernamePasswordToken (user.getAccountName (), user.getPassWord ()); the try { sub.login(token); } catch (LockedAccountException lae) { token.clear(); request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100002); request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_SYSTEMERROR); return "login"; } catch (ExcessiveAttemptsException e) { token.clear(); request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100003); request.setAttribute("LOGIN_ERROR_MESSAGE","账号:" + user.getUserName() + LoginConstant.LOGIN_ERROR_MESSAGE_MAXERROR); return "login"; } catch (AuthenticationException e) { token.clear(); request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100001); request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_USERERROR); return "login"; } return "redirect:/index.shtml"; }
note:
Login method which some of the parameters of the definition:
public interface LoginConstant { String LOGIN_ERROR_CODE_100000 = "100000"; LOGIN_ERROR_MESSAGE_VALIDATECODE String = "Verification code input errors, please re-enter!" ; String LOGIN_ERROR_CODE_100001 = "100001"; LOGIN_ERROR_MESSAGE_USERERROR String = "error account or password, please try again!" ; String LOGIN_ERROR_CODE_100002 = "100002"; LOGIN_ERROR_MESSAGE_SYSTEMERROR String = "User has been locked can not log in, please contact your administrator!" ; String LOGIN_ERROR_CODE_100003 = "100003"; LOGIN_ERROR_MESSAGE_MAXERROR String = "too many failed login lock 10 minutes!" ; String LOGIN_ERROR_CODE_100004 = "100004"; LOGIN_ERROR_MESSAGE_FORCELOGOUT String = "You have been forced to withdraw from the administrator, please log in again ' ; }
3, login jsp (important Code)
Path information:
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %>
js: to replace the verification code picture
<script> function reloadValidateCode(){ $("#validateCodeImg").attr("src","<%=basePath%>/validateCode.shtml?data=" + new Date() + Math.floor(Math.random()*24)); } </script>
Login form inside the label:
<img id="validateCodeImg" src="<%=basePath%>/validateCode.shtml" /> <a href="#" rel="external nofollow" onclick="javascript:reloadValidateCode();">看不清?</a>
4, Shiro anonymous access configuration (not configured can not generate a CAPTCHA)
<-! Custom filterChainDefinitionMap -> <bean id="chainDefinitionSectionMetaSource" class="com.collection.shiro.ChainDefinitionSectionMetaSource"> <property name="filterChainDefinitions"> <value> anon = /validateCode.shtml // add this line </value> </property> </bean>
The above is in Java SSM + Shiro small series to introduce the system login authentication implementation code, we want to help, if you have any questions please give me a message, Xiao Bian will promptly reply to everyone. In this I am also very grateful for the support of the home-site scripting!
Original Address: https: //www.jb51.net/article/105481.htm