java 算数验证码,后台验证不通过?
前两天一直找算数验证码,后来终于东拼西凑搞出来了,但是后台验证老是返回false?求大神帮忙查看,是什么问题??? 我调试的sessionid都有值的, boolean b验证总是返回false? 在下面代码匹配验证码正确性那出错了,b一直返回false??
public class CaptchaServiceSingleton {
private static DefaultManageableImageCaptchaService instance=null;
public static int result;
/**
* 单例模式的类用于生成图片
* @return
*/
public static ImageCaptchaService getInstance() {
VerifImage vi= new VerifImage();
result=vi.getResult();
if(instance==null){
instance = new DefaultManageableImageCaptchaService(new FastHashMapCaptchaStore(), vi, 180, 100000, 75000);
}else{
instance.setCaptchaEngine(vi);
}
return instance;
}
}
public class ImageCaptchaServlet extends HttpServlet {
private static final long serialVersionUID = -11L;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
byte[] b = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
//获取session对象
HttpSession session=request.getSession();
//获取本次会话的sessionID
String captchaId = session.getId();
//生成图片
BufferedImage challenge = CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId, request.getLocale());
//将结果保存到session
session.setAttribute(captchaId,CaptchaServiceSingleton.result);
ImageIO.write(challenge,"jpg",baos);
//加密
// JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(baos);
//
// jpegEncoder.encode(challenge);
} catch (IllegalArgumentException e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} catch (CaptchaServiceException e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
b = baos.toByteArray();
//设置相应的参数,用于显示图片
response.setDateHeader("Expires", 1L);
response.addHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
response.setContentType("image/jpeg");
ServletOutputStream sos = response.getOutputStream();
sos.write(b);
sos.flush();
sos.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
public class VerifImage extends ListImageCaptchaEngine {
static{
System.setProperty("java.awt.headless", "true");
}
private final static String[] noss={"0","1","2","3","4","5","6","7","8","9"};
// 存放加减乘运算符
private final static char[] arr = {'+', '-', '×'};
//汉字加减乘运算符
private StringBuffer stringBuffer=null;
private Random random=null;
private int result;
public int getResult(){
return result;
}
@Override
protected void buildInitialFactories() {
random = new Random();
stringBuffer=new StringBuffer();
//获取一个随机boolean
boolean bool=random.nextBoolean();
//掉用生成运算模式方法
this.model(bool);
int len=stringBuffer.toString().length();
WordGenerator wgen=new DummyWordGenerator(stringBuffer.toString());
//设置字体颜色
RandomRangeColorGenerator cgen = new RandomRangeColorGenerator(new int[]{0, 150}, new int[]{0, 150}, new int[]{0, 150});
// 文字显示的个数
TextPaster textPaster = new RandomTextPaster(len, len, cgen, true);
//设置图片背景颜色
ColorGenerator colorGenerator = new RandomRangeColorGenerator(new int[]{200, 200}, new int[]{200, 200}, new int[]{200, 200});
// 图片的大小
BackgroundGenerator backgroundGenerator = new FunkyBackgroundGenerator(130, 40,colorGenerator);
// 字体格式
Font[] fontsList = new Font[]{new Font("宋体", 0, 10)};
// 文字的大小
FontGenerator fontGenerator = new RandomFontGenerator(20, 20, fontsList);
//将文字写入到图片中
WordToImage wordToImage = new ComposedWordToImage(fontGenerator, backgroundGenerator, textPaster);
this.addFactory(new GimpyFactory(wgen, wordToImage));
}
private void model(boolean bool){
// 生成随机整数num1
int num1 = getRandomNum();
// 生成随机整数num2
int num2 = getRandomNum();
//随机产生运算方式
int operate = random.nextInt(3);
switch (operate) {
case 0:
this.result = num1 + num2;
break;
case 1:
this.result = num1 - num2;
break;
case 2:
this.result = num1 * num2;
break;
}
try{
//随机生成运算表达试
if(bool){
this.getRes(operate,num1,num2);
}else{
int r=random.nextInt(3);
stringBuffer.append(getNos(r,num1)+" ");
r=random.nextInt(2);
stringBuffer.append(getOperate(r,operate)+" ");
r=random.nextInt(3);
stringBuffer.append(getNos(r,num2));
stringBuffer.append(" = ?");
}
}catch (Exception e){
e.printStackTrace();
}
}
//生成运算表达试
private void getRes(int operate,int num1,int num2){
int r=random.nextInt(2);
switch (r){
case 0:
r=random.nextInt(3);
stringBuffer.append(getNos(r,num1)+" ");
r=random.nextInt(2);
stringBuffer.append(getOperate(r,operate)+" ");
stringBuffer.append("?");
stringBuffer.append(" = "+this.result);
this.result=num2;
break;
case 1:
stringBuffer.append("? ");
r=random.nextInt(2);
stringBuffer.append(getOperate(r,operate)+" ");
r=random.nextInt(3);
stringBuffer.append(getNos(r,num2));
stringBuffer.append(" = "+this.result);
this.result=num1;
break;
}
}
//获取运算数字
private String getNos(int random,int num) {
switch (random){
case 0:
return noss[num];
case 1:
return noss[num];
case 2:
return noss[num];
}
return null;
}
//获取运算符
private String getOperate(int random,int num){
switch (random){
case 0:
return String.valueOf(arr[num]);
case 1:
return String.valueOf(arr[num]);
}
return null;
}
//获取0~9随机数
private int getRandomNum(){
int num = random.nextInt(10);
while (num == 0) {
num = random.nextInt(10);
}
return num;
}
}
public class CspUsernamePasswordAuthenticationFilter extends
UsernamePasswordAuthenticationFilter {
// 验证码字段
private String validateCodeParameter = "validateCode";
// 匹对验证码的正确性
public void checkValidateCode(HttpServletRequest request) {
String jcaptchaCode = obtainValidateCodeParameter(request);
if (null == jcaptchaCode)
throw new AuthenticationServiceException("验证码超时,请重新获取!");
boolean b = CaptchaServiceSingleton.getInstance().validateResponseForID(request.getSession().getId(), jcaptchaCode);
if (!b)
throw new AuthenticationServiceException("验证码不正确,请重新输入!");
}
public String obtainValidateCodeParameter(HttpServletRequest request) {
Object obj = request.getParameter(getValidateCodeParameter());
return null == obj ? "" : obj.toString().trim();
}
@Override
protected String obtainUsername(HttpServletRequest request) {
Object obj = request.getParameter(getUsernameParameter());
return null == obj ? "" : obj.toString().trim();
}
@Override
protected String obtainPassword(HttpServletRequest request) {
Object obj = request.getParameter(getPasswordParameter());
return null == obj ? "" : obj.toString().trim();
}
public String getValidateCodeParameter() {
return validateCodeParameter;
}
public void setValidateCodeParameter(String validateCodeParameter) {
this.validateCodeParameter = validateCodeParameter;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
那该怎么改?求教
回复
多个请求公用同一个全局变量,并发肯定会有问题。不要使用全局变量传递返回结果。生成图片并返回的方法,将这个结果一同返回。
回复
每个链接是否共用这一个单例,如果是,那就会共用这一个属性,当然就会有问题
这个地方使用了全局变量,并发会出错。
我感觉你还是debug跟踪一下你的那个设置sessionid关联验证码和获取验证的方法。
回复
@云遮七月 : 我跟踪了,跟踪一天了,就是没找出来为什么我调用CaptchaServiceSingleton.getInstance() .validateResponseForID(request.getSession().getId(),jcaptchaCode); 方法时总是返回false,都纳闷了,难道就我一个人遇到这个问题了
你在生成验证码的地方将结果放在session中,在验证的时候又去生成图片的地方去验证。这两个地方有不一样吧。