笔记-JavaWeb学习之旅13

验证码案列

昨天晚上出现的500错误缘由在于验证码没有获取到,获取验证码是应该获取的是共享域中的验证码,而我把获取值得键给写成了jsp中的键,而不是内存生成图片中,而后把图片上传到共享域中的键。这两个键搞混了,因此获取不到验证码。html

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>


    <script>
        window.onload = function(){
            document.getElementById("img").onclick = function(){
                this.src="/day14/checkCodeDemo4?time="+new Date().getTime();
            }
        }


    </script>
    <style>
        div{
            color: red;
        }

    </style>
</head>
<body>

<form action="/day14/loginServlet" method="post">
    <table>
        <tr>
            <td>用户名</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密码</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>验证码</td>
            <td><input type="text" name="checkCode"></td>
        </tr>
        <tr>
            <td colspan="2"><img id="img" src="/day14/checkCodeDemo4"></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="登陆"></td>
        </tr>
    </table>


</form>


<div><%=request.getAttribute("cc_error") == null ? "" : request.getAttribute("cc_error")%></div>
<div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error") %></div>

</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1><%=request.getSession().getAttribute("user")%>,欢迎您</h1>

</body>
</html>
package com.data;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/checkCodeDemo4")
public class checkCode extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int width = 100;
        int height = 50;
        //建立对象,该对象能够在内存中生成图片
        //BufferedImage是Image的一个子类,Image和BufferedImage的主要做用就是将一副图片加载到内存中。
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//这个类第一次接触,好陌生,好抽象
        //图片加载进内存了,就尽情的虐待他吧
        //美化图片
        //填充背景色
        Graphics g = image.getGraphics();
        g.setColor(Color.PINK);
        g.fillRect(0,0,width,height);
        //画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width-1,height-1);
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        //  写验证码
        Random ran = new Random();
        StringBuilder sb = new StringBuilder();//初始容量为16字节
        //随机生成4个字符
        for(int i = 1;i<=4;i++){
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);
            sb.append(ch);//这个方法能够接收任意类型的数据
            g.drawString(ch+"",width/5*i,height/2);//ch表明要绘制的字符,x,y表明绘制的坐标
        }
        String value_checkCode_session = sb.toString();//把字符变成字符串
        System.out.println(value_checkCode_session);
        //建立对象,使用方法将验证码存入session
        req.getSession().setAttribute("key_checkCode_session",value_checkCode_session);//把数据放入共享域
        g.setColor(Color.GREEN);//线条的颜色
        //画10条干扰线
        for (int i = 0 ; i< 10 ;i++){
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);//参数是坐标
        }


        //将图片输出到页面上
        ImageIO.write(image,"jpg",resp.getOutputStream());

    }
}
package com.data;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;


@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //根据键获取值
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");//这里的checkCode是用户输入的验证码
        //要先看看获取的验证码是否正确
        //先得取得内存中生成的验证码,
        HttpSession session = request.getSession();//建立HttpSession对象
        String checkCode1 = (String)session.getAttribute("key_checkCode_session");//这里的checkCode是内存中得到的验证码
        //把得到的验证码删除,确保只使用一次
        session.removeAttribute("checkCode_session");
        //判断验证码是否正确,忽略大小写
        if(checkCode1!=null&&checkCode1.equalsIgnoreCase(checkCode)){
            //验证码正确
            //判读用户名和密码是否一致
            if("zhangsan".equals(username)&&"123".equals(password)){
                //存储信息,
                session.setAttribute("user",username);
                //重定向到success.jsp页面
                response.sendRedirect(request.getContextPath()+"/success.jsp");

            }else{
                //储存信息到request
                request.setAttribute("login_error","用户名或密码错误");
                //转发都登陆页面
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }
        } else{
            //验证码不一致
            //存储提示信息到request
            request.setAttribute("cc_error","验证码错误,请重试");
            //转发到登陆页面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
JSP:

1.指令java

做用:用于配置JSP页面,导入资源文件数据库

格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...%>数组

指令分类:浏览器

1.page :配置JSP页面的session

  • contentType:等同于response.setContentType(),设置响应体的mime类型
  • import:导包
  • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
  • isErrorPage:标识当前是不是错误页面,true,是,可使用内置对象exception,false:否,默认值,不能够设置内置对象exception

2.include:页面包含的,导入页面的资源文件mvc

  • <% @include file="要导入的资源文件名称"%>

3.taglib :导入资源app

  • <%@ taglib prefix="c" uri="文件的地址" %>
  • prefix :前缀,自定义的

2.注释:

  • html注释: 只能注释html代码片断
  • jsp注释:<%-- --%>能够注释全部
3.内置对象

在jsp页面中不须要建立,直接使用的对象,一共有9个dom

变量名 真实类型 做用
pageContext PageContext 当前页面共享数据,还能够获取其余八个内置对象
request HttpServletRequest 一次请求访问的多个资源
session HttpSession 一次会话的多个请求间
application ServletContext 全部用户间共享数据
response HttpServletResponse 响应对象
page Object 当前页面的对象
out jspWriter 输出对象,数据输出到页面上
config ServletConfig Servlet的配置对象
exception Throwable 异常对象
MVC:开发模式 模型视图控制器

M:Model,模型。JavaBean,完成具体的业务操做,如,查询数据库,封装对象jsp

V:view,视图,JSP,展现数据

C:Controller,控制器。Servlet,获取用户输入,调用模型,将数据交给视图进行展现

EL表达式:

1.概念:Expression Language 表达式语言

2.做用:替换和简化jsp页面中java代码的编写

3.语法:${表达式}

4.注意:jsp默认支持el表达式,浏览器会解析el表达式,若是让浏览器忽略jsp页面中全部的el表达式能够设置jsp中page指令中:isELIgnored="true"会 忽略当前jsp页面中全部的el表达式,或者使用${表达式}:会忽略当前这个el表达式。

EL_表达式获取域中的值

1.el表达式只能从域对象中获取值

2.语法:

  1. ${域名称.键名}:从指定域中获取指定键的值
    • 有四种域
    • 1.pageScope 2.requestScope 3.sessionScope 4.applicationScope
  2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,知直到找到为止,若是域有多个同名的键,则从小范围的域开始找起。
获取对象,List集合,Map集合的值

对象格式:${域名称.键名.属性名}

List集合格式:${域名称.键名[索引]}

Map集合格式:${域名称.键名.key名称}或者${域名称.键名["key名称"]}

package com.data.jsp;
import java.text.SimpleDateFormat;
import java.util.Date;

public class User {
    private String name;
    private int age;
    private Date birthday;
    //逻辑视图
    //须要显示年月日的日期格式须要建立一个方法
    public String getBirStr(){
        //格式化日期
        if(birthday !=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            //返回字符串
            return sdf.format(birthday);
        }else{
            return "";
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
<%@ page import="com.data.jsp.User" %>
<%@ page import="java.util.*" %><%--
  Created by IntelliJ IDEA.
  User: Yuan
  Date: 2019/6/11
  Time: 18:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--给User设置值--%>
    <%
        User user = new User();
        user.setName("张三");
        user.setAge(23);
        user.setBirthday(new Date());
//        共享域
        request.setAttribute("u",user);
        //建立List集合
        List list = new ArrayList();
        list.add("云想衣裳花想容");
        list.add("春风扶槛露华浓");
//        添加对象进去看看
        list.add(user);
        request.setAttribute("list",list);

        //建立Map集合
        Map map = new HashMap();
        map.put("sname","李四");
        map.put("gender","男");
        //添加用户进去看看
        map.put("user",user);
        request.setAttribute("map",map);
    %>
<h3>el获取对象中的值</h3>
    <%--获取对象的值须要经过对象的方法来获取--%>
        <%--setter或getter方法,去掉set或get,在将剩余部分,首字母变小写--%>
${requestScope.u.name}<br>
${requestScope.u.age}<br>
${requestScope.u.birthday}<br>
${requestScope.u.birStr}<br>
<h3>el获取List集合中的值</h3>
${requestScope.list}<br><%--获取的是整个集合--%>
${requestScope.list[0]}<br>
${requestScope.list[1]}<br>
${requestScope.list[2].name}<br>
${requestScope.list[2].age}<br>
<h3>el获取Map集合中的值</h3>
${requestScope.map}<br>
${requestScope.map.sname}<br>
${requestScope.map.gender}<br>
${requestScope.map.user.name}<br>
</body>
</html>

img

空运算符:empty

功能:用于判断字符串,集合,数组对象是否为null而且长度是否为0

格式:{empty list}

3.隐式对象:

el表达式中有11个隐式对象

pageContext:获取jsp其余八个内置对象

${pageContext.request.contextPath}:动态获取虚拟目录