需求:
验证码非常常见,那么在spring中使用jcaptcha进行认证那么需要集成
实现:
mvn:
<!-- code check captcha start --> <dependency> <groupId>com.octo.captcha</groupId> <artifactId>jcaptcha</artifactId> <version>1.0</version> </dependency> <!-- code check captcha end -->
一般仓库中没有对应的jar,比如imaging-01012005.jar那么需要手动添加仓库
<repository> <id>atlassian</id> <name>atlassian</name> <url>http://maven.jahia.org/maven2</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository>
基于注解mvc,那么图片的请求路径为Controller,流程为请求path:/anon/getcode产生验证码
这样spring的配置信息为:
<context:component-scan base-package="com.someabcd.csr" /> <!-- check code start --> <bean id="captchaService" class="com.octo.captcha.service.multitype.GenericManageableCaptchaService"> <description>验证码服务</description> <constructor-arg index="0"> <ref bean="com.someabcd.csr.web.crsCaptchaEngine" /> </constructor-arg> <constructor-arg index="1"> <value>300</value> </constructor-arg><!--超时时间 秒 --> <constructor-arg index="2"> <value>20000</value> </constructor-arg><!--最大并发数 --> <constructor-arg index="3"> <value>20000</value> </constructor-arg> </bean>
com.someabcd.csr.web.crsCaptchaEngine类为:
@Component("com.someabcd.csr.web.crsCaptchaEngine") public class CSRCaptchaEngine extends ListImageCaptchaEngine { @Override protected void buildInitialFactories() { int minWordLength = 4; int maxWordLength = 5; int fontSize = 50; int imageWidth = 152; int imageHeight = 100; WordGenerator wordGenerator = new RandomWordGenerator( "0123456789abcdefghijklmnopqrstuvwxyz"); TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength, maxWordLength, new RandomListColorGenerator(new Color[] { new Color(23, 170, 27), new Color(220, 34, 11), new Color(23, 67, 172) }), new TextDecorator[] {}); BackgroundGenerator background = new UniColorBackgroundGenerator( imageWidth, imageHeight, Color.white); FontGenerator font = new RandomFontGenerator(fontSize, fontSize, new Font[] { new Font("nyala", Font.BOLD, fontSize), new Font("Bell MT", Font.PLAIN, fontSize), new Font("Credit valley", Font.BOLD, fontSize) }); ImageDeformation postDef = new ImageDeformationByFilters( new ImageFilter[] {}); ImageDeformation backDef = new ImageDeformationByFilters( new ImageFilter[] {}); ImageDeformation textDef = new ImageDeformationByFilters( new ImageFilter[] {}); WordToImage word2image = new DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef, postDef); addFactory(new GimpyFactory(wordGenerator, word2image)); } }
处理请求的Controller:
@Controller @RequestMapping("anon") public class AnonController { @Autowired private GenericManageableCaptchaService captchaService; @RequestMapping(value = "/getcode", method = RequestMethod.GET) public void getCode(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { byte[] captchaChallengeAsJpeg = null; // 输出jpg的字节流 ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { String captchaId = httpServletRequest.getSession().getId(); BufferedImage challenge = (BufferedImage) captchaService .getChallengeForID(captchaId, httpServletRequest.getLocale()); // a jpeg encoder JPEGImageEncoder jpegEncoder = JPEGCodec .createJPEGEncoder(jpegOutputStream); jpegEncoder.encode(challenge); captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); // flush it in the response httpServletResponse.setHeader("Cache-Control", "no-store"); httpServletResponse.setHeader("Pragma", "no-cache"); httpServletResponse.setDateHeader("Expires", 0); httpServletResponse.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = httpServletResponse .getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); } catch (Exception e) { try { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); } catch (IOException e1) { e1.printStackTrace(); } return; } } }
验证码的显示:
<tr> <td colspan="2" align="center"> <img src="${basePath}anon/getcode" onclick="this.src='${basePath}anon/getcode?d='+new Date()*1" width="160" height="30"/> </td> </tr> <tr> <td height="40" align="right"> <strong> 验证码: </strong> </td> <td> <input name="code" type="text" id="code" vld="{required:true}" class="input"/> </td> </tr>
验证码验证代码块:
Boolean isCorrect = Boolean.FALSE; String captchaId = request.getSession().getId(); String code = request.getParameter("code"); try { isCorrect = captchaService.validateResponseForID(captchaId, code); if (!isCorrect) { log.info("check code error!"); return "usr/tologin"; } } catch (Exception e) { log.error(e.getMessage()); }
备注:
可以把CaptchaEngine也配置的配置文件中,好处是可以随时修改,缺点是20%的事情缺耗费了80%时间,且这20%不重要