前端:利用ExtJs的autoEl功能加載圖片。
1 var imgCheckValid = new Ext.create('Ext.Component',{
2 width: 70, //圖片寬度
3 height: 45, //圖片高度
4 margin:'5',
5 id:"imd_imgCheckValid",
6 autoEl: {
7 tag: 'img', //指定為img標簽
8 src: 'Code/genCodeImg.do?' //指定url路徑
9 },
10 listeners: {
11 render: function(component){
12 component.getEl().on('click', function(e){
13 this.dom.src = 'Code/genCodeImg.do?'+(new Date().getTime()); // autoEl不會自動加載,只有設置了不同的src才會加載
14 });
15 }
16 }
17 });
小編心得:autoEl會自動加載,要實現點擊驗證碼刷新,登錄失敗刷新,方法是給請求的url加上時間戳。所以刷新驗證碼只要在需要刷新的時候重新設置加上時間戳的src即可。
疑問解答:為什麼只是給了src一個路徑,並沒有給圖片地址,頁面能顯示圖片呢?
目前不是很清楚:猜想它是根據給的鏈接,自動從response中獲得二進制資源。明確的是我會向response中寫入流
後台:struts,spring配置
struts:
1 <!-- 客戶端 --> 2 <package name="Code" extends="json" namespace="/Code"> 3 <action name="genCodeImg" class="codeAction" method="genCodeImg"> 4 <result name="success" type="json"> 5 <param name="root">responseJson</param> 6 </result> 7 </action> 8 </package>
spring:
1 <!-- 驗證碼生成器--> 2 <bean id="codeAction" class="com.sinsche.i.action.impl.CodeAction" 3 scope="prototype"></bean>
後台:
1 import java.awt.Color;
2 import java.awt.Font;
3 import java.awt.Graphics;
4 import java.awt.image.BufferedImage;
5 import java.util.Map;
6 import java.util.Random;
7
8 import javax.imageio.ImageIO;
9 import javax.servlet.ServletOutputStream;
10 import javax.servlet.http.HttpServletResponse;
11
12 import org.apache.struts2.ServletActionContext;
13
14 import com.common.core.st2.action.BaseAction;
15 import com.opensymphony.xwork2.ActionContext;
16 import com.sinsche.i.action.ICodeAction;
17
18 public class CodeAction extends BaseAction implements ICodeAction {
19 /**
20 *
21 */
22 private static final long serialVersionUID = 6865491407475710154L;
23 private boolean success;
24 private String message;
25 // 圖片的寬度。
26 private int width = 70;
27 // 圖片的高度。
28 private int height = 45;
29 // 驗證碼字符個數
30 private int codeCount = 4;
31 // 驗證碼干擾線數
32 private int lineCount = 20;
33 // 驗證碼圖片Buffer
34 private BufferedImage buffImg = null;
35 Random random = new Random();
36 public String genCodeImg() throws Exception {
37 HttpServletResponse resp = ServletActionContext.getResponse();
38 int fontWidth = width / codeCount;// 字體的寬度
39 int fontHeight = height - 5;// 字體的高度
40 int codeY = height - 8;
41
42 // 圖像buffer
43 buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
44 Graphics g = buffImg.getGraphics();
45 // Graphics2D g = buffImg.createGraphics();
46 // 設置背景色
47 g.setColor(getRandColor(200, 250));
48 g.fillRect(0, 0, width, height);
49
50 // 設置字體
51 // Font font1 = getFont(fontHeight);
52 Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
53 g.setFont(font);
54
55 // 設置干擾線
56 for (int i = 0; i < lineCount; i++) {
57 int xs = random.nextInt(width);
58 int ys = random.nextInt(height);
59 int xe = xs + random.nextInt(width);
60 int ye = ys + random.nextInt(height);
61 // g.setColor(getRandColor(1, 255));
62 shear(g,1,20,getRandColor(1, 255));
63 g.drawLine(xs, ys, xe, ye);
64 }
65
66 // 添加噪點
67 float yawpRate = 0.01f;// 噪聲率
68 int area = (int) (yawpRate * width * height);
69 for (int i = 0; i < area; i++) {
70 int x = random.nextInt(width);
71 int y = random.nextInt(height);
72
73 buffImg.setRGB(x, y, random.nextInt(255));
74 }
75
76 String str1 = randomStr(codeCount);// 得到隨機字符
77 for (int i = 0; i < codeCount; i++) {
78 String strRand = str1.substring(i, i + 1);
79 g.setColor(getRandColor(1, 255));
80 // g.drawString(a,x,y);
81 // a為要畫出來的東西,x和y表示要畫的東西最左側字符的基線位於此圖形上下文坐標系的 (x, y) 位置處
82
83 g.drawString(strRand, i * fontWidth + 3, codeY);
84 }
85
86 // 將四位數字的驗證碼保存到Session中。
87 Map<String, Object> map = ActionContext.getContext().getSession();
88 System.out.print(str1);
89 map.put("code", str1.toString());
90 // 禁止圖像緩存。
91 resp.setHeader("Pragma", "no-cache");
92 resp.setHeader("Cache-Control", "no-cache");
93 resp.setDateHeader("Expires", 0);
94
95 resp.setContentType("image/jpeg");
96
97 // 將圖像輸出到Servlet輸出流中。
98 ServletOutputStream sos = resp.getOutputStream();
99 ImageIO.write(buffImg, "jpeg", sos);
100 sos.close();
101
102 return null;
103 }
104
105 // 得到隨機字符
106 private String randomStr(int n) {
107 String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
108 String str2 = "";
109 int len = str1.length() - 1;
110 double r;
111 for (int i = 0; i < n; i++) {
112 r = (Math.random()) * len;
113 str2 = str2 + str1.charAt((int) r);
114 }
115 return str2;
116 }
117
118 // 得到隨機顏色
119 private Color getRandColor(int fc, int bc) {// 給定范圍獲得隨機顏色
120 if (fc > 255)
121 fc = 255;
122 if (bc > 255)
123 bc = 255;
124 int r = fc + random.nextInt(bc - fc);
125 int g = fc + random.nextInt(bc - fc);
126 int b = fc + random.nextInt(bc - fc);
127 return new Color(r, g, b);
128 }
129
130 // /**
131 // * 產生隨機字體
132 // */
133 // private Font getFont(int size) {
134 // Font font[] = new Font[5];
135 // font[0] = new Font("Ravie", Font.PLAIN, size);
136 // font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);
137 // font[2] = new Font("Fixedsys", Font.PLAIN, size);
138 // font[3] = new Font("Wide Latin", Font.PLAIN, size);
139 // font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);
140 // return font[random.nextInt(5)];
141 // }
142
143 // 扭曲方法
144 private void shear(Graphics g, int w1, int h1, Color color) {
145 shearX(g, w1, h1, color);
146 shearY(g, w1, h1, color);
147 }
148
149 private void shearX(Graphics g, int w1, int h1, Color color) {
150
151 int period = random.nextInt(2);
152
153 boolean borderGap = true;
154 int frames = 1;
155 int phase = random.nextInt(2);
156
157 for (int i = 0; i < h1; i++) {
158 double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
159 g.copyArea(0, i, w1, 1, (int) d, 0);
160 if (borderGap) {
161 g.setColor(color);
162 g.drawLine((int) d, i, 0, i);
163 g.drawLine((int) d + w1, i, w1, i);
164 }
165 }
166
167 }
168
169 private void shearY(Graphics g, int w1, int h1, Color color) {
170
171 int period = random.nextInt(40) + 10; // 50;
172
173 boolean borderGap = true;
174 int frames = 20;
175 int phase = 7;
176 for (int i = 0; i < w1; i++) {
177 double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
178 g.copyArea(i, 0, 1, h1, 0, (int) d);
179 if (borderGap) {
180 g.setColor(color);
181 g.drawLine(i, (int) d, i, 0);
182 g.drawLine(i, (int) d + h1, i, h1);
183 }
184
185 }
186
187 }
188
189 public BufferedImage getBuffImg() {
190 return buffImg;
191 }
192 @Override
193 public String list() throws Exception {
194 return null;
195 }
196
197 @Override
198 public String create() throws Exception {
199 return null;
200 }
201
202 @Override
203 public String update() throws Exception {
204 return null;
205 }
206
207 @Override
208 public String delete() throws Exception {
209 return null;
210 }
211
212 @Override
213 public String listByPage() throws Exception {
214 return null;
215 }
216
217 public boolean isSuccess() {
218 return success;
219 }
220
221 public void setSuccess(boolean success) {
222 this.success = success;
223 }
224
225 public String getMessage() {
226 return message;
227 }
228
229 public void setMessage(String message) {
230 this.message = message;
231 }
232
233 }
效果:





