zoukankan      html  css  js  c++  java
  • JSP&Servlet实现简单的验证码登陆

    Servlet(1):

    public class VerifyCodeServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
    * 1. 生成图片
    * 2. 保存图片上的文本到session域中
    * 3. 把图片响应给客户端
    */
    VerifyCode vc = new VerifyCode();
    BufferedImage image = vc.getImage();
    request.getSession().setAttribute("session_vcode", vc.getText());//保存图片上的文本到session域
    VerifyCode.output(image, response.getOutputStream());
    }

    Servlet(2):

    package cn.code.servlet;

    import java.io.IOException;

    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;

    public class demoone extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
    * 校验验证码
    * 1. 从session中获取正确的验证码
    * 2. 从表单中获取用户填写的验证码
    * 3. 进行比较!
    * 4. 如果相同,向下运行,否则保存错误信息到request域,转发到login.jsp
    */
    String sessionCode = (String) request.getSession().getAttribute("session_vcode");
    String paramCode = request.getParameter("verifyCode");

    if(!paramCode.equalsIgnoreCase(sessionCode)) {
    request.setAttribute("msg", "验证码错误!");
    request.getRequestDispatcher("/login.jsp").forward(request, response);
    return;
    }


    /*
    * 1. 获取表单数据
    */
    // 处理中文问题
    request.setCharacterEncoding("utf-8");
    // 获取
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    /*
    * 2. 校验用户名和密码是否正确
    */
    if(!"oycq".equalsIgnoreCase(username)) {//登录成功
    /*
    * 附加项:把用户名保存到cookie中,发送给客户端浏览器
    * 当再次打开login.jsp时,login.jsp中会读取request中的cookie,把它显示到用户名文本框中
    */
    Cookie cookie = new Cookie("uname", username);//创建Cookie
    cookie.setMaxAge(60*60*24);//设置cookie命长为1天
    response.addCookie(cookie);//保存cookie

    /*
    * 3. 如果成功
    * > 保存用户信息到session中
    * > 重定向到succ1.jsp
    */
    HttpSession session = request.getSession();//获取session
    session.setAttribute("username", username);//向session域中保存用户名
    response.sendRedirect("/javaweb115/succ1.jsp");
    } else {//登录失败
    /*
    * 4. 如果失败
    * > 保存错误信息到request域中
    * > 转发到login.jsp
    */
    request.setAttribute("msg", "用户名或密码错误!");
    RequestDispatcher qr = request.getRequestDispatcher("/login.jsp");//得到转发器
    qr.forward(request, response);//转发
    }
    }
    }

    表单:

    <%-- 本页面提供登录表单,并且显示错误信息 --%>

    <h1>登录</h1>
    <%
    /*
    读取名为uname的Cookie!
    如果为空显示:""
    如果不为空显示:Cookie的值
    */
    String uname = "";
    Cookie[] cs = request.getCookies();//获取请求中所有的cookie
    if(cs != null) {// 如果存在cookie
    for(Cookie c : cs) {//循环遍历所有的cookie
    if("uname".equals(c.getName())) {//查找名为uname的cookie
    uname = c.getValue();//获取这个cookie的值,给uname这个变量
    }
    }
    }
    %>
    <%
    String message = "";
    String msg = (String)request.getAttribute("msg");//获取request域中的名为msg的属性
    if(msg != null) {
    message = msg;
    }
    %>
    <font color="red"><b><%=message %> </b></font>
    <form action="/javaweb115/demoone" method="post">
    <%-- 把cookie中的用户名显示到用户名文本框中 --%>
    用户名:<input type="text" name="username" value="<%=uname%>"/><br/>
    密 码:<input type="password" name="password"/><br/>
    验证码:<input type="text" name="verifyCode" size="3"/>
    <img id="img" src="/javaweb115/VerifyCodeServlet"/>
    <a href="javascript:_change()">看不清,换一张</a>
    <br/>
    <input type="submit" value="登录"/>
    </form>

    生成图片工具类:

    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;

    import javax.imageio.ImageIO;

    public class VerifyCode {
    private int w = 70;
    private int h = 35;
    private Random r = new Random();
    // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
    private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
    // 可选字符
    private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
    // 背景色
    private Color bgColor = new Color(255, 255, 255);
    // 验证码上的文本
    private String text ;

    // 生成随机的颜色
    private Color randomColor () {
    int red = r.nextInt(150);
    int green = r.nextInt(150);
    int blue = r.nextInt(150);
    return new Color(red, green, blue);
    }

    // 生成随机的字体
    private Font randomFont () {
    int index = r.nextInt(fontNames.length);
    String fontName = fontNames[index];//生成随机的字体名称
    int style = r.nextInt(4);//生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
    int size = r.nextInt(5) + 24; //生成随机字号, 24 ~ 28
    return new Font(fontName, style, size);
    }

    // 画干扰线
    private void drawLine (BufferedImage image) {
    int num = 3;//一共画3条
    Graphics2D g2 = (Graphics2D)image.getGraphics();
    for(int i = 0; i < num; i++) {//生成两个点的坐标,即4个值
    int x1 = r.nextInt(w);
    int y1 = r.nextInt(h);
    int x2 = r.nextInt(w);
    int y2 = r.nextInt(h);
    g2.setStroke(new BasicStroke(1.5F));
    g2.setColor(Color.BLUE); //干扰线是蓝色
    g2.drawLine(x1, y1, x2, y2);//画线
    }
    }

    // 随机生成一个字符
    private char randomChar () {
    int index = r.nextInt(codes.length());
    return codes.charAt(index);
    }

    // 创建BufferedImage
    private BufferedImage createImage () {
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = (Graphics2D)image.getGraphics();
    g2.setColor(this.bgColor);
    g2.fillRect(0, 0, w, h);
    return image;
    }

    // 调用这个方法得到验证码
    public BufferedImage getImage () {
    BufferedImage image = createImage();//创建图片缓冲区
    Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境
    StringBuilder sb = new StringBuilder();//用来装载生成的验证码文本
    // 向图片中画4个字符
    for(int i = 0; i < 4; i++) {//循环四次,每次生成一个字符
    String s = randomChar() + "";//随机生成一个字母
    sb.append(s); //把字母添加到sb中
    float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标
    g2.setFont(randomFont()); //设置随机字体
    g2.setColor(randomColor()); //设置随机颜色
    g2.drawString(s, x, h-5); //画图
    }
    this.text = sb.toString(); //把生成的字符串赋给了this.text
    drawLine(image); //添加干扰线
    return image;
    }

    // 返回验证码图片上的文本
    public String getText () {
    return text;
    }

    // 保存图片到指定的输出流
    public static void output (BufferedImage image, OutputStream out)
    throws IOException {
    ImageIO.write(image, "JPEG", out);
    }
    }

  • 相关阅读:
    +1和*2
    线段树(区间最大值和最大值的个数)
    CodeForces
    莫队算法入门(暴力而不失优雅)
    二分迷宫
    全错排公式
    C++ PAT乙 1051. 复数乘法 (15)
    C++ PAT乙 1070. 结绳(25)
    C++ PAT乙 1080. MOOC期终成绩 (25)
    C++ PAT 1073. 多选题常见计分法(20)
  • 原文地址:https://www.cnblogs.com/oycq9999/p/10272685.html
Copyright © 2011-2022 走看看