激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中SSM+Shiro系統登錄驗證碼的實現方法

Java中SSM+Shiro系統登錄驗證碼的實現方法

2020-08-10 19:09Lovnx Java教程

這篇文章主要介紹了 SSM+Shiro系統登錄驗證碼的實現方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

 先給大家展示下效果圖:

Java中SSM+Shiro系統登錄驗證碼的實現方法

1、驗證碼生成類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
/**
 * 驗證碼生成器類,可生成數字、大寫、小寫字母及三者混合類型的驗證碼。 支持自定義驗證碼字符數量; 支持自定義驗證碼圖片的大小; 支持自定義需排除的特殊字符;
 * 支持自定義干擾線的數量; 支持自定義驗證碼圖文顏色
 */
public class ValidateCode {
 /**
  * 驗證碼類型為僅數字 0~9
  */
 public static final int TYPE_NUM_ONLY = 0;
 /**
  * 驗證碼類型為僅字母,即大寫、小寫字母混合
  */
 public static final int TYPE_LETTER_ONLY = 1;
 /**
  * 驗證碼類型為數字、大寫字母、小寫字母混合
  */
 public static final int TYPE_ALL_MIXED = 2;
 /**
  * 驗證碼類型為數字、大寫字母混合
  */
 public static final int TYPE_NUM_UPPER = 3;
 /**
  * 驗證碼類型為數字、小寫字母混合
  */
 public static final int TYPE_NUM_LOWER = 4;
 /**
  * 驗證碼類型為僅大寫字母
  */
 public static final int TYPE_UPPER_ONLY = 5;
 /**
  * 驗證碼類型為僅小寫字母
  */
 public static final int TYPE_LOWER_ONLY = 6;
 private ValidateCode() {
 }
 /**
  * 生成驗證碼字符串
  *
  * @param type
  *   驗證碼類型,參見本類的靜態屬性
  * @param length
  *   驗證碼長度,大于0的整數
  * @param exChars
  *   需排除的特殊字符(僅對數字、字母混合型驗證碼有效,無需排除則為null)
  * @return 驗證碼字符串
  */
 public static String generateTextCode(int type, int length, String exChars) {
  if (length <= 0)
   return "";
  StringBuffer code = new StringBuffer();
  int i = 0;
  Random r = new Random();
  switch (type) {
  // 僅數字
  case TYPE_NUM_ONLY:
   while (i < length) {
    int t = r.nextInt(10);
    if (exChars == null || exChars.indexOf(t + "") < 0) {// 排除特殊字符
     code.append(t);
     i++;
    }
   }
   break;
  // 僅字母(即大寫字母、小寫字母混合)
  case TYPE_LETTER_ONLY:
   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;
  // 數字、大寫字母、小寫字母混合
  case TYPE_ALL_MIXED:
   while (i < length) {
    int t = r.nextInt(123);
    if ((t >= 97 || (t >= 65 && t <= 90) || (t >= 48 && t <= 57))
      && (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();
 }
 /**
  * 已有驗證碼,生成驗證碼圖片
  *
  * @param textCode
  *   文本驗證碼
  * @param width
  *   圖片寬度
  * @param height
  *   圖片高度
  * @param interLine
  *   圖片中干擾線的條數
  * @param randomLocation
  *   每個字符的高低位置是否隨機
  * @param backColor
  *   圖片顏色,若為null,則采用隨機顏色
  * @param foreColor
  *   字體顏色,若為null,則采用隨機顏色
  * @param lineColor
  *   干擾線顏色,若為null,則采用隨機顏色
  * @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);
   }
  }
  // 寫驗證碼
  // g.setColor(getRandomColor());
  // g.setColor(isSimpleColor?Color.BLACK:Color.WHITE);
  // 字體大小為圖片高度的80%
  int fsize = (int) (height * 0.8);
  int fx = height - fsize;
  int fy = fsize;
  g.setFont(new Font("Default", Font.PLAIN, fsize));
  // 寫驗證碼字符
  for (int i = 0; i < textCode.length(); i++) {
   fy = randomLocation ? (int) ((Math.random() * 0.3 + 0.6) * height) : fy;// 每個字符高低是否隨機
   g.setColor(foreColor == null ? getRandomColor() : foreColor);
   g.drawString(textCode.charAt(i) + "", fx, fy);
   fx += fsize * 0.9;
  }
  g.dispose();
  return bim;
 }
 /**
  * 生成圖片驗證碼
  *
  * @param type
  *   驗證碼類型,參見本類的靜態屬性
  * @param length
  *   驗證碼字符長度,大于0的整數
  * @param exChars
  *   需排除的特殊字符
  * @param width
  *   圖片寬度
  * @param height
  *   圖片高度
  * @param interLine
  *   圖片中干擾線的條數
  * @param randomLocation
  *   每個字符的高低位置是否隨機
  * @param backColor
  *   圖片顏色,若為null,則采用隨機顏色
  * @param foreColor
  *   字體顏色,若為null,則采用隨機顏色
  * @param lineColor
  *   干擾線顏色,若為null,則采用隨機顏色
  * @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;
 }
 /**
  * 產生隨機顏色
  *
  * @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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * 生成驗證碼
 * @param request
 * @param response
 * @throws IOException
 * @ValidateCode.generateTextCode(驗證碼字符類型,驗證碼長度,需排除的特殊字符)
 * @ValidateCode.generateImageCode(文本驗證碼,圖片寬度,圖片高度,干擾線的條數,字符的高低位置是否隨機,圖片顏色,字體顏色,干擾線顏色)
 */
@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());
}
/**
 * 登錄請求
 * @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";
 }
 // 想要得到 SecurityUtils.getSubject() 的對象..訪問地址必須跟shiro的攔截地址內.不然后會報空指針
 Subject sub = SecurityUtils.getSubject();
 // 用戶輸入的賬號和密碼,,存到UsernamePasswordToken對象中..然后由shiro內部認證對比,
 // 認證執行者交由ShiroDbRealm中doGetAuthenticationInfo處理
 // 當以上認證成功后會向下執行,認證失敗會拋出異常
 UsernamePasswordToken token = new UsernamePasswordToken(user.getAccountName(), user.getPassWord());
 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";
}

注意:

登錄方法里面一些參數的定義:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface LoginConstant
{
 String LOGIN_ERROR_CODE_100000 = "100000";
 String LOGIN_ERROR_MESSAGE_VALIDATECODE = "驗證碼輸入錯誤,請重新輸入!";
 String LOGIN_ERROR_CODE_100001 = "100001";
 String LOGIN_ERROR_MESSAGE_USERERROR = "賬號或密碼錯誤,請重新輸入!";
 String LOGIN_ERROR_CODE_100002 = "100002";
 String LOGIN_ERROR_MESSAGE_SYSTEMERROR = "用戶已經被鎖定不能登錄,請與管理員聯系!";
 String LOGIN_ERROR_CODE_100003 = "100003";
 String LOGIN_ERROR_MESSAGE_MAXERROR = "登錄失敗次數過多,鎖定10分鐘!";
 String LOGIN_ERROR_CODE_100004 = "100004";
 String LOGIN_ERROR_MESSAGE_FORCELOGOUT = "您已經被管理員強制退出,請重新登錄";
}

3、登錄jsp(重要代碼)

路徑信息:

?
1
2
3
4
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%>

js:用于更換驗證碼圖片

?
1
2
3
4
5
<script>
 function reloadValidateCode(){
  $("#validateCodeImg").attr("src","<%=basePath%>/validateCode.shtml?data=" + new Date() + Math.floor(Math.random()*24));
 }
</script>

登錄表單里面的標簽:

?
1
<img id="validateCodeImg" src="<%=basePath%>/validateCode.shtml" />&nbsp;&nbsp;<a href="#" rel="external nofollow" onclick="javascript:reloadValidateCode();">看不清?</a>

4、Shiro匿名訪問配置(不配置無法生成驗證碼圖片)

?
1
2
3
4
5
6
7
8
<!--自定義filterChainDefinitionMap -->
 <bean id="chainDefinitionSectionMetaSource" class="com.collection.shiro.ChainDefinitionSectionMetaSource">
  <property name="filterChainDefinitions">
   <value>
    /validateCode.shtml = anon//添加這行
   </value>
  </property>
 </bean>

以上所述是小編給大家介紹的JavaSSM+Shiro系統登錄驗證碼的實現方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:http://blog.csdn.net/rickiyeat/article/details/55050440

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本韩国欧美一级片 | 日本中文字幕网址 | 日韩2区| 色网免费观看 | 国产一区二区高清在线 | 视频一区二区不卡 | 麻豆911| 国产一区视频在线观看免费 | 久久经典| 一夜新娘第三季免费观看 | 国产视频99 | 热@国产| 在线看毛片的网站 | 精品久久久久久久久久久久久久久久久久久 | 日本一道aⅴ不卡免费播放 久久久久久久高清 | 国产亚洲精品久久午夜玫瑰园 | 国产精品99久久久久久久 | 色诱亚洲精品久久久久久 | 欧美成人精品h版在线观看 在线2区 | 精品国产一区二区三区在线观看 | 午夜精品一区二区三区免费 | 欧美另类69xxxxx 视频 | 久久久久久久久久亚洲精品 | 老女人碰碰在线碰碰视频 | 羞羞视频免费视频欧美 | 精品一区二区亚洲 | 毛片免费观看日本中文 | 一级毛片免费高清视频 | 香蕉久久久久久 | 国产亚洲精品久久久久久大师 | 一区二区三区日韩在线 | 欧美性生交xxxxx免费观看 | 久久草草亚洲蜜桃臀 | 毛片午夜 | 欧美激情视频一区二区免费 | 亚洲va久久久噜噜噜久久男同 | 国产精品久久久久久影院8一贰佰 | 亚洲网站在线 | 在线看国产视频 | 视频一区二区三区在线 | 久久国产精品二国产精品中国洋人 |