1 import java.awt.Color; 2 import java.awt.Font; 3 import java.io.IOException; 4 import java.io.OutputStream; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 import javax.imageio.ImageIO; 9 import javax.servlet.Servlet; 10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 import org.apache.commons.lang.math.RandomUtils; 16 17 import nl.captcha.Captcha; 18 import nl.captcha.Captcha.Builder; 19 import nl.captcha.gimpy.BlockGimpyRenderer; 20 import nl.captcha.text.producer.ChineseTextProducer; 21 import nl.captcha.text.producer.DefaultTextProducer; 22 import nl.captcha.text.renderer.DefaultWordRenderer; 23 import nl.captcha.text.renderer.WordRenderer; 24 25 26 27 public class CaptchaServlet extends HttpServlet implements Servlet { 28 private static final long serialVersionUID = 1L; 29 private static final String PARAM_HEIGHT = "height"; // 高度 默认为50 30 31 private static final String PARAM_WIDTH = "width";// 宽度 默认为200 32 33 private static final String PAEAM_NOISE = "noise";// 干扰线条 默认是没有干扰线条 34 35 private static final String PAEAM_TEXT = "text";// 文本 36 37 protected int _width = 150; 38 protected int _height = 40; 39 protected boolean _noise = false; 40 protected String _text = "number:1,word:1,number:1,number:1,word:1"; 41 42 /** 43 * 初始化过滤器.将配置文件的参数文件赋值 44 * 45 * @throws ServletException 46 */ 47 @Override 48 public void init() throws ServletException { 49 if (getInitParameter(PARAM_HEIGHT) != null) { 50 _height = Integer.valueOf(getInitParameter(PARAM_HEIGHT)); 51 } 52 53 if (getInitParameter(PARAM_WIDTH) != null) { 54 _width = Integer.valueOf(getInitParameter(PARAM_WIDTH)); 55 } 56 57 if (getInitParameter(PAEAM_NOISE) != null) { 58 _noise = Boolean.valueOf(getInitParameter(PAEAM_NOISE)); 59 } 60 61 if (getInitParameter(PAEAM_NOISE) != null) { 62 _text = String.valueOf(getInitParameter(PAEAM_TEXT)); 63 } 64 } 65 66 /** 67 * 因为获取图片只会有get方法 68 */ 69 @Override 70 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 71 72 Builder builder = new Captcha.Builder(_width, _height); 73 // 增加边框 74 // builder.addBorder(); 75 // 是否增加干扰线条 76 if (_noise == true) { 77 builder.addNoise(); 78 } 79 // ----------------自定义字体大小----------- 80 // 自定义设置字体颜色和大小 最简单的效果 多种字体随机显示 81 List<Font> fontList = new ArrayList<Font>(); 82 fontList.add(new Font("微软 雅黑", Font.LAYOUT_NO_START_CONTEXT, 30));// 可以设置斜体之类的 83 DefaultWordRenderer dwr = new DefaultWordRenderer(getRandomColor(), fontList); 84 // 加入多种颜色后会随机显示 字体空心 85 86 WordRenderer wr = dwr; 87 // 增加文本,默认为5个随机字符. 88 if (_text == null) { 89 builder.addText(); 90 } else { 91 String[] ts = _text.split(","); 92 for (int i = 0; i < ts.length; i++) { 93 String[] ts1 = ts[i].split(":"); 94 if ("chinese".equals(ts1[0])) { 95 builder.addText(new ChineseTextProducer(Integer.parseInt(ts1[1])), wr); 96 } else if ("number".equals(ts1[0])) { 97 // 这里没有0和1是为了避免歧义 和字母I和O 98 char[] numberChar = new char[] { '2', '3', '4', '5', '6', '7', '8' }; 99 builder.addText(new DefaultTextProducer(Integer.parseInt(ts1[1]), numberChar), wr); 100 } else if ("word".equals(ts1[0])) { 101 // 原理同上 102 char[] numberChar = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'k', 'm', 'n', 'p', 'r', 103 'w', 'x', 'y' }; 104 builder.addText(new DefaultTextProducer(Integer.parseInt(ts1[1]), numberChar), wr); 105 } else { 106 builder.addText(new DefaultTextProducer(Integer.parseInt(ts1[1])), wr); 107 } 108 } 109 110 } 111 112 // --------------添加背景------------- 113 // 设置背景渐进效果 以及颜色 form为开始颜色,to为结束颜色 114 // GradiatedBackgroundProducer gbp=new GradiatedBackgroundProducer(); 115 // gbp.setFromColor(Color.yellow); 116 // gbp.setToColor(Color.red); 117 // 无渐进效果,只是填充背景颜色 118 // FlatColorBackgroundProducer fbp=new 119 // FlatColorBackgroundProducer(Color.red); 120 // 加入网纹--一般不会用 121 // SquigglesBackgroundProducer sbp=new SquigglesBackgroundProducer(); 122 // 没发现有什么用,可能就是默认的 123 // TransparentBackgroundProducer tbp = new 124 // TransparentBackgroundProducer(); 125 126 // builder.addBackground(gbp); 127 // ---------装饰字体--------------- 128 // 字体边框齿轮效果 默认是3 129 builder.gimp(new BlockGimpyRenderer(1)); 130 // 波纹渲染 相当于加粗 131 // builder.gimp(new RippleGimpyRenderer()); 132 // 修剪--一般不会用 133 // builder.gimp(new ShearGimpyRenderer(Color.red)); 134 // 加网--第一个参数是横线颜色,第二个参数是竖线颜色 135 // builder.gimp(new FishEyeGimpyRenderer(Color.red,Color.yellow)); 136 // 加入阴影效果 默认3,75 137 // builder.gimp(new DropShadowGimpyRenderer()); 138 // 创建对象 139 Captcha captcha = builder.build(); 140 141 req.getSession().setAttribute("simpleCaptcha", captcha); 142 resp.setHeader("Cache-Control", "private,no-cache,no-store"); 143 resp.setContentType("image/png"); 144 try { 145 OutputStream os = resp.getOutputStream(); 146 ImageIO.write(captcha.getImage(), "png", os); 147 os.close(); 148 } catch (IOException e) { 149 e.printStackTrace(); 150 } 151 } 152 153 public Color getRandomColor() { 154 int n = RandomUtils.nextInt(100); 155 156 if (n % 3 == 1) { 157 return Color.RED; 158 } else if (n % 3 == 2) { 159 return Color.BLUE; 160 } 161 return Color.GREEN; 162 } 163 }