Struts2生成验证码

1:Action类
package com.simperfect.action;

import java.io.ByteArrayInputStream;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;
import com.simperfect.tools.randomvalidate.SecurityCode;
import com.simperfect.tools.randomvalidate.SecurityImage;

public class ValidateCodeAction extends ActionSupport implements SessionAware {

     /**
     *  
     */
     private static final long serialVersionUID = 2223970331282695415L;
     private Map<String, Object> session;
     private ByteArrayInputStream imageStream;
     private String flag="";

     public String getValidateImage() {
          String securityCode = new SecurityCode().getDefaultSecurityCode();
          imageStream = new SecurityImage().getImageAsInputStream(securityCode);
          if(flag.equals("login")){
               session.put("LOGINSECURITYCODE", securityCode);
          }else if(flag.equals("reg")){
               session.put("REGSECURITYCODE", securityCode);
          }else if(flag.equals("write")){
               session.put("WRITESECURITYCODE", securityCode);
          }else if(flag.equals("edit")){
               session.put("EDITSECURITYCODE", securityCode);
          }
          return SUCCESS;
     }

     public void setSession(Map<String, Object> arg0) {
          // TODO Auto-generated method stub
          session = arg0;
     }

     public void setImageStream(ByteArrayInputStream imageStream) {
          this.imageStream = imageStream;
     }

     public ByteArrayInputStream getImageStream() {
          return imageStream;
     }

     public void setFlag(String flag) {
          this.flag = flag;
     }

     public String getFlag() {
          return flag;
     }

}
2.验证码相关类
package com.simperfect.tools.randomvalidate;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
* 工具类,生成验证码图片
*/
public class SecurityImage {

     /**
     * 生成验证码图片
     *  
     * @param securityCode
     *            验证码字符
     * @return BufferedImage 图片
     */
     private BufferedImage createImage(String securityCode) {
          // 验证码长度
          int codeLength = securityCode.length();
          // 字体大小
          int fSize = 14;
          int fWidth = fSize + 1;
          // 图片宽度
          int width = codeLength * fWidth + 6;
          // 图片高度
          int height = fSize * 2 + 1;

          // 图片
          BufferedImage image = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
          Graphics g = image.createGraphics();

          // 设置背景色
          g.setColor(Color.WHITE);
          // 填充背景
          g.fillRect(0, 0, width, height);
          // 设置边框颜色
          g.setColor(Color.LIGHT_GRAY);
          // 边框字体样式
          g.setFont(new Font("Arial", Font.BOLD, height - 2));
          // 绘制边框
          g.drawRect(0, 0, width - 1, height - 1);
          // 绘制噪点
          Random rand = new Random();
          // 设置噪点颜色
          g.setColor(Color.LIGHT_GRAY);
          for (int i = 0; i < codeLength * 6; i++) {
               int x = rand.nextInt(width);
               int y = rand.nextInt(height);
               // 绘制1*1大小的矩形
               g.drawRect(x, y, 1, 1);
          }

          // 绘制验证码
          int codeY = height - 10;
          // 设置字体颜色和样式
          g.setColor(new Color(19, 148, 246));
          g.setFont(new Font("Georgia", Font.BOLD, fSize));
          for (int i = 0; i < codeLength; i++) {
               g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5,
                         codeY);
          }
          // 关闭资源
          g.dispose();

          return image;
     }

     /**
     * 返回验证码图片的流格式
     *  
     * @param securityCode
     *            验证码
     * @return ByteArrayInputStream 图片流
     */
     public ByteArrayInputStream getImageAsInputStream(String securityCode) {
          BufferedImage image = this.createImage(securityCode);
          return this.convertImageToStream(image);
     }

     /**
     * 将BufferedImage转换成ByteArrayInputStream
     *  
     * @param image
     *            图片
     * @return ByteArrayInputStream 流
     */
     private ByteArrayInputStream convertImageToStream(BufferedImage image) {
          ByteArrayInputStream inputStream = null;
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);
          try {
               jpeg.encode(image);
               byte[] bts = bos.toByteArray();
               inputStream = new ByteArrayInputStream(bts);
          } catch (ImageFormatException e) {
               e.printStackTrace();
          } catch (IOException e) {
               e.printStackTrace();
          }
          return inputStream;
     }
}

(2)package com.simperfect.tools.randomvalidate;

import java.util.Arrays;

import com.simperfect.inter.tools.LoggerManager;

public class SecurityCode {
     /**
     * 验证码难度级别,Simple只包含数字,Medium包含数字和小写英文,Hard包含数字和大小写英文
     */
     public enum SecurityCodeLevel {
          Simple, Medium, Hard
     };

     // 字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O)
     public static final char[] codes = { '2', '3', '4', '5', '6', '7', '8',
               '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm',
               'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
               'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
               'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

     /**
     * 产生默认验证码,4位中等难度
     * 
     * @return String 验证码
     */
     public String getDefaultSecurityCode() {
          return this.getSecurityCode(4, SecurityCodeLevel.Hard, false);
     }

     /**
     * 产生长度和难度任意的验证码
     * 
     * @param length
     *            长度
     * @param level
     *            难度级别
     * @param isCanRepeat
     *            是否能够出现重复的字符,如果为true,则可能出现 5578这样包含两个5,如果为false,则不可能出现这种情况
     * @return String 验证码
     */
     public String getSecurityCode(int length, SecurityCodeLevel level,
               boolean isCanRepeat) {
          // 随机抽取len个字符
          // int len = length;
          // 根据不同的难度截取字符数组
          char[] codeRange = this.getCodeRangeByLevel(level);
          // 字符集合长度
          // int n = codes.length;
          // 抛出运行时异常
          this.checkLenISValidate(length, codeRange.length, isCanRepeat, level);
          // 判断能否出现重复的字符
          return this.getCodeStr(length, isCanRepeat, codeRange);

     }

     private String getCodeStr(int length, boolean isCanRepeat, char[] codeRange) {
          // 存放抽取出来的字符
          char[] result = new char[length];
          int n = codeRange.length;
          for (int i = 0; i < result.length; i++) {
               // 索引 0 and n-1
               int r = (int) (Math.random() * n);

               // 将result中的第i个元素设置为codes[r]存放的数值
               result[i] = codeRange[r];

               // 必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。
               // 因此,这里用数组中的最后一个字符改写codes[r],并将n减1
               if (!isCanRepeat) {
                    codeRange[r] = codeRange[n - 1];
                    n--;
               }
          }
          return String.valueOf(result);
     }

     private char[] getCodeRangeByLevel(SecurityCodeLevel level) {
          char[] result = null;
          switch (level) {
          case Simple:
               result = Arrays.copyOfRange(codes, 0, 7);
               break;
          case Medium:
               result = Arrays.copyOfRange(codes, 0, 31);
               break;
          default:
               result = Arrays.copyOfRange(codes,0,codes.length);
               break;
          }
          return result;
     }

     private void checkLenISValidate(int codeLen, int codesLen,
               boolean isCanRepeat, SecurityCodeLevel level) {
          if (codeLen > codesLen && isCanRepeat == false) {
               LoggerManager.writeLogStr(String.format(
                         "调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,"
                                   + "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", codeLen,
                         level, isCanRepeat, codesLen), 3);
               throw new RuntimeException(String.format(
                         "调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,"
                                   + "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", codeLen,
                         level, isCanRepeat, codesLen));
          }
     }
}
3.Struts2配置
         <  package   name  = "Security"   extends =  "struts-default" >
               <  action   name  = "getValidateImage"   class =  "validateCodeAction"
                     method  = "getValidateImage"   >
                     <  result   name  = "success"   type =  "stream" >
                           <  param   name  = "contentType"   >  image/jpeg  </ param   >
                           <  param   name  = "inputName"   >  imageStream </   param  >
                           <  param   name  = "bufferSize"   >  2048 </   param  >
                     </  result >
               </  action >
         </  package >
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值