【轉(zhuǎn)】:struts2之圖片驗(yàn)證碼實(shí)現(xiàn)
做注冊(cè)模塊,需要圖片驗(yàn)證碼機(jī)制。google了一圈,自己再整理修改了一下,總算是弄出來(lái)了。思路就是在一個(gè)action里應(yīng)用java的awt包里面的類(lèi)繪制一個(gè)內(nèi)存中的圖片,然后產(chǎn)生隨機(jī)數(shù)并將隨機(jī)數(shù)寫(xiě)到圖片上,然后把a(bǔ)ction的返回類(lèi)型設(shè)為stream,把圖片數(shù)據(jù)寫(xiě)入到輸入流返回給瀏覽器。html可以通過(guò)img頁(yè)面直接用src屬性引用該action action的代碼如下
- import java.io.*;
- import javax.imageio.ImageIO;
- import javax.imageio.stream.ImageOutputStream;
- import java.awt.*;
- import java.awt.Color;
- import java.awt.image.BufferedImage;
- //DefaultAction類(lèi)繼承了ActionSupport 并定義了session變量
- public class CreateValidateAction extends DefaultAction {
- private ByteArrayInputStream inputStream;
- //產(chǎn)生四個(gè)0~9的隨機(jī)數(shù),放在一個(gè)字符串里
- public String createRandomString() {
- String str = "";
- for (int i = 0; i < 4; i++) {
- str += Integer.toString((new Double(Math.random() * 10)).intValue());
- }
- return str;
- }
- //隨機(jī)產(chǎn)生一個(gè)顏色
- public Color createsRandomColor() {
- int r = (new Double(Math.random() * 256)).intValue();
- int g = (new Double(Math.random() * 256)).intValue();
- int b = (new Double(Math.random() * 256)).intValue();
- return new Color(r, g, b);
- }
- //生成一個(gè)內(nèi)存圖片,將四個(gè)隨機(jī)數(shù)寫(xiě)在圖片上
- public BufferedImage createImage(String str) {
- int width = 60;
- int height = 22;
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- // 獲取圖形上下文
- Graphics g = image.getGraphics();
- // 設(shè)定背景色
- g.setColor(Color.WHITE);
- g.fillRect(0, 0, width, height);
- //畫(huà)邊框
- g.setColor(Color.black);
- g.drawRect(0, 0, width - 1, height - 1);
- // 將認(rèn)證碼顯示到圖象中
- g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18));
- //使用隨機(jī)顏色
- g.setColor(this.createsRandomColor());
- //將隨機(jī)字符串的每個(gè)數(shù)字分別寫(xiě)到圖片上
- g.drawString(Character.toString(str.charAt(0)), 8, 17);
- g.drawString(Character.toString(str.charAt(1)), 20, 17);
- g.drawString(Character.toString(str.charAt(2)), 33, 17);
- g.drawString(Character.toString(str.charAt(3)), 45, 17);
- // 圖象生效
- g.dispose();
- return image;
- }
- //將圖片的以字節(jié)形式寫(xiě)到InputStream里
- public ByteArrayInputStream createInputStream() throws Exception {
- //獲取隨機(jī)字符串
- String str=this.createRandomString();
- BufferedImage image = this.createImage(str);
- //將產(chǎn)生的字符串寫(xiě)入session,供校驗(yàn)時(shí)使用
- this.getSession().put("validateCode", str);
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
- ImageIO.write(image, "JPEG", imageOut);
- imageOut.close();
- ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
- output.close();
- return input;
- }
- @Override
- public String execute() throws Exception {
- setInputStream(createInputStream());
- return SUCCESS;
- }
- public ByteArrayInputStream getInputStream() {
- return inputStream;
- }
- public void setInputStream(ByteArrayInputStream inputStream) {
- this.inputStream = inputStream;
- }
- }
然后是對(duì)應(yīng)的struts的配置
- <!--action的class是由spring提供的-->
- <action name="createValidateAction" class="createValidateAction">
- <result type="stream">
- <param name="contentType">image/jpeg</param>
- <param name="inputName">inputStream</param>
- </result>
- </action>
最后就是html的寫(xiě)法,點(diǎn)擊圖片的時(shí)候可以更新驗(yàn)證碼
- <script type="text/javascript">
- function changeValidateCode(obj) {
- //獲取當(dāng)前的時(shí)間作為參數(shù),無(wú)具體意義
- var timenow = new Date().getTime();
- //每次請(qǐng)求需要一個(gè)不同的參數(shù),否則可能會(huì)返回同樣的驗(yàn)證碼
- //據(jù)說(shuō)和瀏覽器的緩存機(jī)制有關(guān)系,不太明白,照做吧
- obj.src="createValidateAction.action?d="+timenow;
- }
- </script>
- <img src="createValidateAction.action" onclick="changeValidateCode(this)"/>
posted on 2009-04-23 15:47 nicky 閱讀(2108) 評(píng)論(3) 編輯 收藏