第一种:
导入jar包com.github.axet生成法
①导包
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>0.0.9</version>
</dependency>
②创建配置类,用来配置验证码的生成
配置类
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha
producer(){
Properties properties
= new Properties();
properties
.put("kaptcha.border","yes");
properties
.put("kaptcha.border.thickness","2");
properties
.put("kaptcha.border.color","blue");
properties
.put("kaptcha.textproducer.font.color","black");
properties
.put("kaptcha.noise.impl","com.google.code.kaptcha.impl.DefaultNoise");
properties
.put("kaptcha.noise.color","yellow");
properties
.put("kaptcha.image.width","90");
properties
.put("kaptcha.image.height","33");
properties
.put("kaptcha.textproducer.font.size","25");
properties
.put("kaptcha.textproducer.char.length","4");
properties
.put("kaptcha.textproducer.char.space","5");
properties
.put("kaptcha.background.clear.from","247,247,247");
properties
.put("kaptcha.background.clear.to","247,247,247");
properties
.put("kaptcha.word.impl","com.google.code.kaptcha.text.impl.DefaultWordRenderer");
Config config
= new Config(properties
);
DefaultKaptcha defaultKaptcha
= new DefaultKaptcha();
defaultKaptcha
.setConfig(config
);
return defaultKaptcha
;
}
}
控制类
③调用图片生成的类(一般为Controller层)
@Controller
@RequestMapping("/producer")
public class KaptchaController {
@Autowired
private Producer producer
;
@RequestMapping("/kaptcha")
public void produceKaptcha(HttpServletRequest request
, HttpServletResponse response
) throws Exception
{
response
.setHeader("Cache-Control", "no-store, no-cache");
response
.setContentType("image/jpeg");
String text
= producer
.createText();
System
.out
.println(text
);
BufferedImage image
= producer
.createImage(text
);
ServletOutputStream out
= response
.getOutputStream();
ImageIO
.write(image
,"jpg",out
);
}
}
第二种:自己编写验证码生成的方
①控制层(调用处的编写)
控制层
@RequestMapping("/selfdefinitionkaptcha")
public void selfDefinitionKaptcha(HttpServletResponse response
) throws Exception
{
Object
[] objs
= CreateKaptcha
.createImage();
String text
= (String
) objs
[0];
BufferedImage image
=
(BufferedImage
) objs
[1];
response
.setHeader("Cache-Control", "no-store, no-cache");
response
.setContentType("image/jpeg");
ServletOutputStream out
= response
.getOutputStream();
ImageIO
.write(image
, "png", out
);
}
②验证码生成类
public class CreateKaptcha {
private static final char[] chars
= {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
private static Map
<String,String> map
= new HashMap<String,String>();
private static List
<String> list
= new ArrayList<String>();
static{
map
.put("李白的女儿","李紫嫣");
map
.put("31*51=?", "1581");
map
.put("潘金莲的老公", "武大郎");
map
.put("dnf外号", "毒奶粉");
map
.put("你是猪吗", "是");
map
.put("光头强职业", "伐木工");
map
.put("床前明月光","疑是地上霜");
map
.put("天王盖地虎","宝塔镇河妖");
Set
<String> set
=map
.keySet();
for(String s
:set
){
list
.add(s
);
}
set
=null
;
}
private static final int SIZE
= 4;
private static final int LINES
= 5;
private static final int WIDTH
= 130;
private static final int HEIGHT
= 35;
private static final int FONT_SIZE
=15;
public static Object
[] createImage() {
StringBuffer sb
= new StringBuffer();
BufferedImage image
= new BufferedImage(
WIDTH
, HEIGHT
, BufferedImage
.TYPE_INT_RGB
);
Graphics graphic
= image
.getGraphics();
graphic
.setColor(Color
.LIGHT_GRAY
);
graphic
.fillRect(0, 0, WIDTH
, HEIGHT
);
Random ran
= new Random();
if(ran
.nextInt(2)==0){
for (int i
= 0; i
<SIZE
; i
++) {
int n
= ran
.nextInt(chars
.length
);
graphic
.setColor(getRandomColor());
int size
=(ran
.nextInt(15)+FONT_SIZE
);
graphic
.setFont(new Font(
null
, Font
.ITALIC
,size
));
graphic
.drawString(
chars
[n
] + "", i
* WIDTH
/SIZE
, HEIGHT
/2+5);
sb
.append(chars
[n
]);
}
}else{
String key
= list
.get(ran
.nextInt(list
.size()));
char[] cha
= key
.toCharArray();
graphic
.setColor(new Color(0,0,0));
for(int i
=0;i
<cha
.length
;i
++){
int size
= WIDTH
/cha
.length
-2;
graphic
.setFont(new Font(null
,Font
.ITALIC
+1,size
));
graphic
.drawString(cha
[i
]+"", i
* WIDTH
/cha
.length
, HEIGHT
/2+5);
}
char[] value
=map
.get(key
).toCharArray();
for(int i
=0;i
<value
.length
;i
++){
sb
.append(value
[i
]);
}
}
for (int i
= 0; i
< LINES
; i
++) {
graphic
.setColor(getRandomColor());
graphic
.drawLine(ran
.nextInt(WIDTH
), ran
.nextInt(HEIGHT
),
ran
.nextInt(WIDTH
), ran
.nextInt(HEIGHT
));
}
return new Object[]{sb
.toString(), image
};
}
public static Color
getRandomColor() {
Random ran
= new Random();
Color color
= new Color(ran
.nextInt(256),
ran
.nextInt(256), ran
.nextInt(256));
return color
;
}
}
总结:
1.第一种更简单,第二种效果更好,更容易控制。也可以做更多花样,比如:加减乘除,唐诗宋词,都可以。 我更爱第二种。 2.两种方法对验证码的缓存采用了两种不同方法,需上心。ShiroUtils.setSessionAttribute()需要使用shiro