美文网首页
注册码出现的错误

注册码出现的错误

作者: 义无反顾00 | 来源:发表于2019-08-19 22:12 被阅读0次

实现注册码时候出现的错误

在建立SSM框架中,在控制类中建立了验证码控制类

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

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/captcha")
public class CaptchaController {
    /**
     * 验证码验证
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/checkCode")
    public String CAPTCHA(HttpServletRequest request, HttpServletResponse response) {
        String info = null;
        /* 获取输入的值 */
        String value1 = request.getParameter("name");

        /* 获取图片的值 */
        HttpSession session = request.getSession();
        String value2 = (String) session.getAttribute("checkcode");

        /* 对比两个值(字母不区分大小写) */
        if (value2.equalsIgnoreCase(value1)) {
            info = "验证码输入正确";
        } else {
            info = "验证码输入错误";
        }
        System.out.println(info);
        request.setAttribute("info", info);
        return "logintest";
    }

    /**
     * 生成验证码
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/logCheck")
    public String logcheck(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("image/jpeg");
        HttpSession session = request.getSession();
        int width = 100;
        int height = 60;

        // 设置浏览器不要缓存此图片
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 创建内存图像并获得图形上下文
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();

        /*
         * 产生随机验证码 定义验证码的字符表
         */
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] rands = new char[4];
        for (int i = 0; i < 4; i++) {
            int rand = (int) (Math.random() * 36);
            rands[i] = chars.charAt(rand);
        }

        /*
         * 产生图像 画背景
         */
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, width, height);

        /*
         * 随机产生120个干扰点
         */

        for (int i = 0; i < 120; i++) {
            int x = (int) (Math.random() * width);
            int y = (int) (Math.random() * height);
            int red = (int) (Math.random() * 255);
            int green = (int) (Math.random() * 255);
            int blue = (int) (Math.random() * 255);
            g.setColor(new Color(red, green, blue));
            g.drawOval(x, y, 1, 0);
        }
        g.setColor(Color.BLACK);
        g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));

        // 在不同高度输出验证码的不同字符
        g.drawString("" + rands[0], 21, 37);
        g.drawString("" + rands[1], 36, 35);
        g.drawString("" + rands[2], 51, 38);
        g.drawString("" + rands[3], 66, 36);
        g.dispose();

        // 将图像传到客户端
        ServletOutputStream sos = response.getOutputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//      ImageIO.write(image, "JPG", baos);
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
        encoder.encode(image);
        byte[] buffer = baos.toByteArray();
        response.setContentLength(buffer.length);
        sos.write(buffer);
        baos.close();
        sos.close();
        session.setAttribute("checkcode", new String(rands));
        return null;
//      int vlength = 4;
//      int weidt = 60;
//      int height = 15;
//      Object vl = request.getParameter("vl");
//      Object w = request.getParameter("w");
//      Object h = request.getParameter("h");
//      //如果长度不为空
//      if(vl != null) {
//          vlength = Integer.parseInt(vl.toString());
//      }
//      if(w != null) {
//          weidt = Integer.parseInt(w.toString());
//      }
//      if(h != null) {
//          height = Integer.parseInt(h.toString());
//      }
//      CpachaUtil cpachaUtil = new CpachaUtil(vlength,weidt,height);
//      String generatorVCode = cpachaUtil.generatorVCode();
//      request.getSession().setAttribute("loginCpacha", generatorVCode);
//      BufferedImage generatorRotateVCodeImage = cpachaUtil.generatorRotateVCodeImage(generatorVCode, true);
//      try {
//          ServletOutputStream outputStream = response.getOutputStream();
//          ImageIO.write(generatorRotateVCodeImage, "gif", outputStream);
//      } catch (IOException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
//      System.out.println("generatorVCode");
//      return generatorVCode;
    }

}

在网页上的实现代码如下

<div class="form-group col-5">
    <input type="text" class="form-control" id="code" name="code" placeholder="验证码">
</div>
<div class="form-group col-3" style="padding: 0px;">
    < img src="${pageContext.request.contextPath}/captcha/logCheck" id="vimg" style="height: 60px;width: 100%;" alt="验证码"/>
</div>
<div class=" col-3" style="padding: 0px;">
    < a href=" " id="transform" style="display: block;line-height: 60px;margin-left:20px ;">换一换</ a>
</div>

为了实现验证码刷新需要在请求后面加上时间戳

//时间戳 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
function chgUrl(url){
    var timestamp = (new Date()).valueOf();
    url = url.substring(0, 20);
    if ((url.indexOf("&") >= 0)) {
        url = url + "×tamp=" + timestamp;
    } else {
        url = url + "?timestamp=" + timestamp;
    }
    return url;
}


$(function(){
    /**
     * 重新生成验证码
     */
    $("a[id='transform']").click(function(){
        /** 重新设置验证码图片的src属性,让它引用一张新的图片 */
        var imgsrc = "/captcha/logCheck";
        $("#vimg").attr("src",chgUrl(imgsrc));
    });
    /**
     * 验证表单信息
     */

});

在测试中遇到了500错误

javax.imageio.IIOException: Can't create output stream!
    javax.imageio.ImageIO.write(ImageIO.java:1574)
    cn.suyizhen.controller.CaptchaController.logcheck(CaptchaController.java:116)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)

主要原因如下:

在使用ImageIO进行图片写操作时,默认会使用缓存目录:${tomcat}/temp,在此缓存目录会生成缓存文件imageio4138671232726624650.tmp(这一串数字应该是当前时间戳,临时文件名),有些生产环境的tomcat,会将temp目录删除,因此报错

4种解决方法如下:

1、在tomcat下新建temp目录;

2、与方法1相似,通过ImageIO.setCacheDirectory(cacheDirectory);设置任意的、存在的缓存目录

3、ImageIO默认是使用缓存目录,可以通过ImageIO.setUseCache(false)来设置,更改缓存策略,不使用文件目录缓存,使用内存缓存

4、不使用ImageIO,换成其它JDK方法

ImageIO.write(bi, "jpg", baos);

换成:

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
encoder.encode(image);

参考博客(https://blog.csdn.net/cwfreebird/article/details/51820993)

相关文章

网友评论

      本文标题:注册码出现的错误

      本文链接:https://www.haomeiwen.com/subject/jprysctx.html