属性名  作用                   是否重要
name    Cookie的名称           必须属性
value   Cookie的值(不支持中文) 必须属性
path    Cookie的路径           重要
domain  Cookie的域名           重要
maxAge  Cookie的存活时间       重要
version Cookie的版本号         不重要
comment Cookie的描述           不重要
方法名                           作用
Cookie(String.name,String.Value) 构造方法创建对象
属性对应的set和get就去           赋值和获取值

Cooke 添加和获取

  • 添加 HttpServletResponse
返回值 方法名                   说明
void   addCookie(Cookie.cookie) 向客户端添加Cookie
  • 获取 HttpServletRequest
返回值   方法名       说明
Cookie[] getCookies() 获取所有的Cookie
  • 数量限制
    • 每个网站最多只能有20个Cookie, 且大小不能超过4KB. 所有网站的Cookie总数不能超过300个
  • 名称限制
    • Cookie的名称只能包含ASCCI码表中字母,数字字符. 不能包含逗号,分号,空格, 不能以$开头
    • Cookie的值不支持中文
  • 存活时间限制setMaxAge()方法接收数字
    • 负整数: 当前会放有效, 浏览器关闭则清除
    • 0: 立即清除
    • 正整数: 以秒为单位设置存活时间
  • 访问路径限制
    • 默认路径: 取自第1次访问的资源路径前缀. 只要以这个路径开头就能访问到
    • 设置路径: setPath()方法设置指定路径
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = resp.getWriter();
        pw.write("欢迎访问本网站, 你的最后访问时间为:");

        Cookie cookie = new Cookie("time", System.currentTimeMillis()+"");
        cookie.setMaxAge(10);

        resp.addCookie(cookie);

        Cookie[] arr = req.getCookies();
        for(Cookie c : arr){
            if("time".equals(c.getName())){
                String value = c.getValue();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                pw.write(sdf.format(new Date(Long.parseLong(value))));
            }
        }

    }
}

HttpSession 介绍

  • HttpSession: 服务器端会话管理技术
    • 本质也采用客户端会话管理技术
    • 只不过在客户保存一个特殊标识, 而共享的数据保存到了服务端的内存对象中.
    • 第次请求时, 会将特殊标识带到服务器端, 根据这个标识来找到对应的内存空间, 从而实现数据共享.
    • 是Servlet规范中四大域对象之一的会话域对象
  • 作用: 可以实现数据共享
域对象         功能   作用
ServletContext 应用域 在整个应用之间实现共享数据
ServletRequest 请求域 在当前的请求或请求转发之间实现数据共享
HttpSession    会话域 在当前会话范围之间实现数据共享

HttpSession 常用方法

返回值 方法名                                 说明
void   setAttribute(String.name,Object.value) 设置共享数据
Object getAttribute(String.name)              获取共享数据
void   removeAttribute(String.name)           移除共享数据
String getId()                                获取唯一标识名称
void   involidate()                           让session立即失效

HttpSession 获取

返回值      方法名                     说明
HttpSession getSession()               获取HttpSession对象
HttpSession getSession(boolean.create) 获取HttpSession,未获取到是否自动创建
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( value = "/demo1Session")
public class Demo1Session extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        HttpSession session = req.getSession();
        System.out.println(session);
        System.out.println(session.getId());
        session.setAttribute("username",username);
    }
}
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( value = "/demo2Session")
public class Demo2Session extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        System.out.println(session);

        System.out.println(session.getId());

        Object username = session.getAttribute("username");

        resp.getWriter().write(username+"");
    }
}
  • 禁用Cookie 就获取不到了
  • 可以使用手动拼接链接
resp.getWriter().write("<a href='"+resp.encodeURL("http://localhost:8080/demo3Session")+"'>go to servlet</a>");

HttpSession 的细节

  • 浏览器禁用Cookie, 禁止访问

  • 手动拼接URL, 不推荐

  • 钝化和泛化

    • 什么是钝化和活化
      • 钝化: 序列化. 把长时间不用, 但还不到过期时间的HttpSession进行序列化, 写到磁盘上
      • 活化: 相反动作
    • 何时钝化
      • 每一种情况: 当访问量很大时, 服务器会根据getLastAccessTime来进行排序,对长时不用,还没过期的HttpSession进行序列化
      • 第二种飞速: 当服务器进行重启的时候, 为了保持客户HttpSession中的数据, 也要对其序列化.
    • 注意
      • HttpSession的序列化由服务器自动完成, 无需关心

JSP 介绍

  • JSP(Java Server Pages): 是一种动态见面技术标准
  • JSP部署在服务器上, 可以处理客户端发送的请求, 并根据请求内容动态的生成HTML,XML,或其他格式文件的Web见面, 然后再响应给客户端
  • JSP是基于Java语文的, 它的本质就是Servlet
类别       使用场景
HTML       开发静态资源,无法添加动态资源
CSS        美化页面
JavaScript 给网页添加一些动态效果
Servlet    编写Java代码,实现抬功能处理
JSP        包含显示页面技术,也具备Java代码功能

JSP 执行过程

JSP执行过程

JSP 语法

  • JSP 注释
  • Java 代码块
  • JSP 表达式
  • JSP 声明
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--这是一行注释--%>

<%--输出在控制台上--%>
<% System.out.println("Hello");%>
<%--输出在页面上, out是jspWriter对象--%>
<% out.println("Hello<br>"); %>
<%
String str = "World";
out.println(str);
%>
<br/>

<%--JSP表达式,等效out.println--%>
<%="Hello World<br>"%>

<%--JSP声明, !是成员变量, 不加是局部方法变量, 方法里不能再定义方法 --%>
<%! String s = "AAAA<br>"; %>
<%=s%>
<%! public void he(){} %>
<%--<% public void hehe(){}%>--%>

</body>
</html>

JSP 指令

  • page 指令
<%@ page 属性名=属性值 属性名=属性值... %>
属性名       作用
contentType  响应正文支持的类型和设置编码格式
language     使用的语文,默认使用java
errorPage    当前页面出现异常后跳转的页面
isErrorPage  是否抓住异常,如果为true则页面中就可以使用异常对象,默认是false
import       展示导包import="java.util.ArrayList"
session      是否创建HttpSession对象,默认是true
buffer       设置JspWriter输入jsp内容缓存的大小,默认8kb
pageEncoding 翻译jsp时所用的编码格式
isElgnored   是否忽略EL表达式,默认false
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp"  %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<% int a = 1/0; %>

<% ArrayList<String> s = new ArrayList<>(); %>
</body>
</html>
  • include 指令: 可以包含页面
<%@include file=包含的页面 %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%! String str = "Hahaha"; %>

</body>
</html>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp"  %>
<%@ include file="include.jsp"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--<% int a = 1/0; %>--%>

<% ArrayList<String> s = new ArrayList<>(); %>

<%--引入include.jsp, 可使用其中参数--%>
<%=str%>
</body>
</html>
  • taglib 指令: 可以引入外部标签库
<%@ taglib uri=标签库的地址 prefix=前缀名称 %>

JSP 细节

  • 九大隐式对象
隐式对象名称 代表实际对象
request      javax.servlet.http.HttpServletRequest
reponse      javax.servlet.http.HttpServletResponse
session      javax.servlet.http.HttpSession
application  javax.servlet.ServletContext
page         java.lang.Object
config       java.servlet.ServletConfig
exception    java.lang.Throwable
out          javax.servlet.jsp.JspWriter
pageContext  javax.servlet.jsp.PageContext
  • PageContext 对象

    • 是JSP独有的, Servlet中没有
    • 是四大域对象之一的页面域对象, 还可以操作其他三个域对象中的属性
    • 还可以获取其他八个隐藏对象
    • 生命周期随着JSP的创建而存在,随着JSP的结束而消失. 每个JSP页面都有一个PageContext对象.
  • 四大域对象

域对象名称 范围 级别 备注
PageContext 页面范围 最小,只能在当前页面用 国范围太小,开发中用的小
ServletRequest 请求范围 一次请求或当前请求转发用 请求转发之后,再次转发时请求域丢失
HttpSession 会话范围 多次请求数据共享使用 多次请求共享数据,但不同的客户端不能共享
ServletContext 应用范围 最大整个应用都可以使用 尽量少用,如果对数据有修改需要做同步处理

MVC 模型

  • M(Model): 模型. 用于封装数据, 封装的是数据模型
  • V(View): 视图. 用于显示数据, 动态资源用JSP页面, 静态资源用HTML页面
  • C(Controller): 控制器. 用于处理请求和响应, 例如Servlet

mvc

学生管理

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    <%
        Object username = session.getAttribute("username");
        if( username == null){
    %>
    <a href="/stuLogin.jsp" >请求登录</a>
    <% } else { %>
    <a href="/addStudent.jsp">添加学生</a>
    <a href="/listStudentServlet">查看学生</a>
    <% } %>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/loginServlet" method="get" autocomplete="off">
    <label for="username">账户名称:</label>
    <input type="text" name="username" id="username">
    <br/>
    <label for="password">账户密码:</label>
    <input type="password" name="password" id="password">
    <br/>
    <button type="submit">登录</button>
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加学生</title>
</head>
<body>
<form action="/addStudent" method="get" autocomplete="off">
    <label for="username">学生姓名:</label>
    <input type="text" name="username" id="username">
    <br/>
    <label for="age">学生年龄:</label>
    <input type="text" name="age" id="age">
    <br/>
    <label for="chenji">学生成绩:</label>
    <input type="text" name="chenji" id="chenji">
    <br/>
    <button type="submit">添加</button>
    <button type="reset">重置</button>
</form>
</body>
</html>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.lizicai.bean.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生列表</title>
</head>
<body>
<%
Object name = session.getAttribute("username");
if( name == null){
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("未登录, 跳转到登录页面...");
response.setHeader("Refresh", "2;URL=/stuLogin.jsp");
return;
}
%>
<table border="1px" cellspacing="0">
    <thead>
    <th>学生姓名
    </th>
    <th>
        学生年龄
    </th>
    <th>
        学生成绩
    </th>
    </thead>
    <tbody>
        <%
            ArrayList<Student> list =(ArrayList<Student>) session.getAttribute("students");
            for(Student s: list){
        %>
            <tr align="center">
                <td><%=s.getUsername() %></td>
                <td><%=s.getAge() %></td>
                <td><%=s.getChenji() %></td>
            </tr>
        <% } %>
    </tbody>
</table>
</body>
</html>
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 (value = "/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 判断用户名是否为空或null,   有效则写入session中
        HttpSession session = req.getSession();

        if( username.equals(null) || "".equals(username)){
            resp.sendRedirect("/stuLogin.jsp");
            return;
        } else  {
            session.setAttribute("username", username);
            resp.sendRedirect("/stuIndex.jsp");
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
import com.lizicai.bean.Student;

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.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

@WebServlet (value = "/addStudent")
public class AddStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        HttpSession session = req.getSession();
        Object name = session.getAttribute("username");
        if( name == null){
            resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("未登录, 跳转到登录页面...");
            resp.setHeader("Refresh", "3;URL=/stuLogin.jsp");
            return;
        }

        String username = req.getParameter("username");
        String age = req.getParameter("age");
        String chenji = req.getParameter("chenji");
        Student s = new Student(username, age, chenji);

        String realpath = getServletContext().getRealPath("/stu.txt");
        BufferedWriter bw = new BufferedWriter(new FileWriter(realpath,true));

        bw.write(s.getUsername()+","+s.getAge()+","+s.getChenji());
        bw.newLine();
        bw.close();
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("添加成功, 跳转到回添加页面");
        resp.setHeader("Refresh", "3;URL=/addStudent.jsp");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
import com.lizicai.bean.Student;

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.*;
import java.util.ArrayList;

@WebServlet ( value = "/listStudentServlet")
public class ListStudent extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 查询前校验有没有登录
        HttpSession session = req.getSession();
        Object name = session.getAttribute("username");
        if( name == null){
            resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("未登录, 跳转到登录页面...");
            resp.setHeader("Refresh", "3;URL=/stuLogin.jsp");
            return;
        }

        String realPath = getServletContext().getRealPath("/stu.txt");


        ArrayList<Student> list = new ArrayList<>();
        BufferedReader br = new BufferedReader(new FileReader(realPath));
        String line;
        while ( (line = br.readLine()) != null ){
            String[] split = line.split(",");
            Student s = new Student();
            s.setUsername(split[0]);
            s.setAge(split[1]);
            s.setChenji(split[2]);
            list.add(s);
            System.out.println(split[0]+split[1]+split[2]);
        }

        // 集合对象放到会话里
        session.setAttribute("students", list);

        resp.sendRedirect("/listStudent.jsp");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}