JavaLearn#(24)SessionCookieServletContextMVC开发模式JSP九大内建对象及四个作用域JSTL及EL表达式过滤器监听器

Posted LRcoding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaLearn#(24)SessionCookieServletContextMVC开发模式JSP九大内建对象及四个作用域JSTL及EL表达式过滤器监听器相关的知识,希望对你有一定的参考价值。

1. session和cookie

1.1 session和cookie原理

HTTP协议是无状态的协议,客户每次读取 web 页面,服务器都会打开新的连接,而且服务器也不会自动维护客户的上下文信息。

如何在多次请求之间共享信息呢? 服务器端如何判断一个分时段的连接是不是属于同一个客户呢?

Session 和 Cookie 就是为解决 HTTP协议的无状态采用的两种解决方案

  • Cookie:将信息保存在客户端解决
  • Session:将信息保存在服务器端解决

1.2 cookie—实现10天免登录

重定向:可以拿到 cookie(返回到页面再跳转,所以可以拿到)

转发:拿不到 cookie(服务器内部转发,页面拿不到)

LoginServlet.java

  • 创建一个 cookie
  • 指定 cookie 作用范围(默认范围是当前目录)
  • 指定 cookie 有效时间(默认有效时间是当前浏览器打开时)
  • 把 cookie 给客户端
public class LoginServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String remember = req.getParameter("remember");   // 根据勾选判断是否记住

        // 增加一个服务器端格式验证,验证数据合法性
        // TODO
        // 应该调用后台(JDBC)判断登录是否成功;此处直接处理
        boolean flag = false;
        if (username.contains("lwclick") && pwd.contains("click")) 
            flag = true;
        

        if (flag) 
            // ==================================== 完成 10天免登录功能 ====================================
            // 创建一个 cookie
            Cookie usernameCookie = new Cookie("uname", username);
            Cookie pwdCookie = new Cookie("upwd", pwd);

            // 指定 cookie 作用范围(默认范围是当前目录)
            usernameCookie.setPath(req.getContextPath());    // 作用范围当前项目
            pwdCookie.setPath(req.getContextPath());

            if ("yes".equals(remember)) 
                // 指定 cookie 有效时间(默认有效时间是当前浏览器打开时)
                usernameCookie.setMaxAge(60 * 60 * 24 * 10);
                pwdCookie.setMaxAge(60 * 60 * 24 * 10);
             else 
                // 去掉 cookie
                usernameCookie.setMaxAge(0);
                pwdCookie.setMaxAge(0);
            

            // 把 cookie 给客户端
            resp.addCookie(usernameCookie);
            resp.addCookie(pwdCookie);
            // ==================================== 10天免登录功能 end ====================================

            // 跳转到成功页面 【重定向 redirect】
            req.setAttribute("username", username);
            resp.sendRedirect(req.getContextPath() + "/login/success.jsp");
         else 
            // 跳回登录页 【转发 dispatcher】
            req.setAttribute("error", "用户名或密码错误");
            req.getRequestDispatcher("/login/login.jsp").forward(req, resp);
        
    

login.jsp页面

  • 拿出所有的 cookie
  • 找到需要的 cookie
  • 使用 cookie
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
    <script type="text/javascript">
    <!--    客户端验证 省略    -->
    </script>
</head>
<body>

<%
    // 1. 拿出所有的 cookie
    Cookie[] cookies = request.getCookies();
    // 2. 找到需要的 cookie
    String username = "";
    String password = "";
    String isChecked = "";
    if (cookies != null) 
        for (int i = 0; i < cookies.length; i++) 
            if ("uname".equals(cookies[i].getName())) 
                username = cookies[i].getValue();
                isChecked = "checked";
            
            if ("upwd".equals(cookies[i].getName())) 
                password = cookies[i].getValue();
            
        
        // 使用 cookie
        // 在用户名和密码的输入框中,使用 value 字段绑定值
    
%>

<form action="../servlet/LoginServlet" method="post" onsubmit="return checkForm()">
    用户名:<input type="text" id="username" name="username" value="<%=username%>" onblur="checkUser()"/>
    <!-- 错误提示,省略 --><br>
    密码: <input type="text" id="password" name="pwd" value="<%=password%>" onblur="checkPwd()"/>
    <!-- 错误提示,省略 --><br>
    <input name="remember" type="checkbox" value="yes" <%=isChecked%>/>十天免登录<br> <!-- 复选框,勾中才记住 -->
    <input type="submit" value="登录">
</form>
</body>
</html>

1.3 session—实现记住用户名

  • 首次访问服务器上的一个JSP页面时,JSP引擎产生一个session对象
  • 每个session都有一个sessionid
  • 数据保存在服务器端, 将sessionid保存在客户端的Cookie中(服务器端也有sessionId,用来对照)
  • 后续每次请求request都携带cookie到服务器端
  • 服务器端根据客户端的sessionid判断属于哪个会话

LoginServlet.java

public class LoginServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        req.setCharacterEncoding("utf-8");
        // 接收用户编号和密码
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String remember = req.getParameter("remember");  // 根据勾选判断是否记住

        // 增加一个服务器端格式验证,验证数据合法性
        // TODO
        // 应该调用后台(JDBC)判断登录是否成功;此处直接处理
        boolean flag = false;
        if (username.contains("lwclick") && pwd.contains("click")) 
            flag = true;
        

        if (flag) 
            // ==================================== 记住用户名 ====================================
            HttpSession session = req.getSession();
            session.setAttribute("username", username);
            // ==================================== 记住用户名 end ====================================

            // 跳转到成功页面 【重定向 redirect】
            resp.sendRedirect(req.getContextPath() + "/login/success.jsp");
         else 
            // 跳回登录页 【转发 dispatcher】
            req.setAttribute("error", "用户名或密码错误");
            req.getRequestDispatcher("/login/login.jsp").forward(req, resp);
        
    

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <%
        String basePath = request.getScheme() + "://" + request.getServerName() +
                ":" + request.getServerPort() + request.getContextPath() + "/";
    %>
    <base href="<%=basePath%>">
</head>
<body>
    <!--  session 代表当前会话,一个用户一定时间内的多个请求 -->
    登录成功!欢迎<%=session.getAttribute("username")%>  <!-- 使用session可以在【当前项目】的【所有页面】中访问到 -->

    <!--  可以用 sessionId 判断是否为同一个session  -->
    <%=session.getId()%>
    
    <!--  设置 session过期时间,过期后结束  -->
    <% session.setMaxInactiveInterval(10) %>

    <!--  注销操作  -->
    <a href="servlet/LogoutServlet">注销</a>
</body>
</html>

LogoutServlet.java

public class LogoutServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // 立即结束当前的 session
        req.getSession().invalidate();

        // 跳回登录页面(注销操作建议使用重定向)
        resp.sendRedirect(req.getContextPath() + "/login/login.jsp");
    

注意:有的浏览器不支持 cookie时,可以通过 URL重写(http://localhost:8080/sevlet/LoginServelt?sessionId=354nlehtbbew54,每次都传sessionId)的方式,来实现 session对象的唯一性

2. servletContext

2.1 统计网站访问次数

ServletContext

  • 代表 web应用本身,相当于 web应用的全局变量,整个 web应用共享一个 servletContext对象

  • 关闭服务器,servletContext数据清空

    session的数据还在(tomcat会在服务器关闭时,自动保存session信息到硬盘)

LoginServlet.java

public class LoginServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        req.setCharacterEncoding("utf-8");
        // 接收用户编号和密码
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String remember = req.getParameter("remember");  // 根据勾选判断是否记住

        // 增加一个服务器端格式验证,验证数据合法性
        // TODO
        // 应该调用后台(JDBC)判断登录是否成功;此处直接处理
        boolean flag = false;
        if (username.contains("lwclick") && pwd.contains("click")) 
            flag = true;
        

        if (flag) 
            // ==================================== 统计网站的访问人数 ====================================
            // 获取之前的人数
            ServletContext servletContext = req.getServletContext();   // this.getServletContext();
            Integer count = (Integer) servletContext.getAttribute("count");
            if (count == null) 
                count = 1;
             else 
                count++;
            
            servletContext.setAttribute("count", count);
            // ==================================== 统计网站的访问人数 end ====================================
            
            // 跳转到成功页面 【重定向 redirect】
            resp.sendRedirect(req.getContextPath() + "/login/success.jsp");
         else 
            // 跳回登录页 【转发 dispatcher】
            req.setAttribute("error", "用户名或密码错误");
            req.getRequestDispatcher("/login/login.jsp").forward(req, resp);
        
    

2.2 ServletAPI 总结

  • Servlet

    • Servlet、 GenericServlet、 HttpServlet
  • 请求和响应

    • ServletRequest、 ServletResponse
    • HttpServletRequest、 HttpServletResponse
  • 会话和上下文

    • HttpSession、 Cookie、 ServletContext
  • 配置

    • ServletConfig
  • 请求转发

    • RequestDispatcher
  • 异常

    • ServletException
  • Cookie类

    • Cookie cookie = new Cookie(name,value);
  • HttpSession接口

    • HttpSession session=request.getSession();
  • ServletContext接口

    • 上下文表示每个Web应用程序的环境,且被当作是一个应用程序中所有servlet可访问的共享库
    • ServletContext context=this.getServletContext();
  • ServletConfig接口

    • ServletConfig是表示单独的Servlet的配置和参数,只是适用于特定的Servlet。
    • 从servlet访问一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对本servlet有效,一个servlet的ServletConfig对象不能被另一个
    • ServletConfig config = this.getServletConfig();

3. 访问数据库完善登录功能

3.1 创建数据表

CREATE TABLE sys_user (
	userid VARCHAR(10) PRIMARY KEY,
    realname VARCHAR(20) NOT NULL,
    pwd VARCHAR(10),
    age INT(3)
);

INSERT INTO sys_user VALUES ("zhangsan", "张三", "zhangsan123", 23);

3.2 创建实体类

public class SysUser 
    private String userId;
    private String realName;
    private String pwd;
    private Integer age;

    public SysUser(String userId, String realName, String pwd, Integer age) 
        this.userId = userId;
        this.realName = realName;
        this.pwd = pwd;
        this.age = age;
    

    public SysUser() 
    
    
    // getter、 setter、 toString

3.3 DBUtil类

简单封装的

public class DBUtil 
    private DBUtil()
    

    /**
     * 获取数据库连接
     * @return
     */
    public static Connection getConnection()
        String driver ="com.mysql.cj.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "root";
        Connection conn = null;
        try 
            //1.加载驱动
            Class.forName(driver);
            //2.建立和数据库的连接
            conn = DriverManager.getConnection(url, user, password);
         catch (ClassNotFoundException e) 
            e.printStackTrace();
         catch (SQLException e) 
            e.printStackTrace();
        
        return conn;
    

    /**
     * 关闭各种资源
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void closeAll(ResultSet rs, Statement stmt, Connection conn)
        try 
            if(rs!=null)
                rs.close();
            
         catch (SQLException e) 
            e.printStackTrace();
        
        try 
            if(stmt != null)
                stmt.close();
            
         catch (SQLException e) 
            e.printStackTrace();
        
        try 
            if(conn != null)
                conn.close();
            
         catch (SQLException e) 
            e.printStackTrace();
        
    

    /**
     * 完成DML操作:insert、update和delete
     * @param sql
     * @param params
     * @return
     */
    public static int executeUpdate(String sql, Object [] params) 
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs =  null;
        int n = 0;//添加失败
        try 
            //2.建立和数据库的连接
            conn = DBUtil.getConnection();
            //3.创建一个SQL命令发送器

            pstmt = conn.prepareStatement(sql);
            //4.准备好SQL语句,通过SQL命令发送器发送给数据库,并得到结果
            for (int i = 0; i <params.length ; i++) 
                pstmt.setObject(i+1, params[i]);
            
            n = 

以上是关于JavaLearn#(24)SessionCookieServletContextMVC开发模式JSP九大内建对象及四个作用域JSTL及EL表达式过滤器监听器的主要内容,如果未能解决你的问题,请参考以下文章

JavaLearn # Java的常用类

JavaLearn # 异常

JavaLearn # 面向对象案例:猜丁壳

JavaLearn # 数据结构和算法

JavaLearn # 面向对象编程_4

JavaLearn#(11)MapIterator迭代器Collections集合总结泛型