个人主页:Hello Code.
本文专栏:《Java WEB从入门到实战》
Java WEB完整内容请点击前往Java WEB从入门到实战 查看
如有问题,欢迎指正,一起学习~~
文章目录
-
- Cookie
-
- 会话
- 概述
- Cookie属性
- 方法
- 练习
- 注意事项
- Session
-
- JSP
-
- 快速入门
- 执行过程
- 语法
- 指令
- 注意事项
- MVC模型
- 学生管理系统3
Cookie
会话
- 会话:浏览器和服务器之间的多次请求和响应
- 为了实现一些功能,浏览器和服务器之间可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束(关闭浏览器、到了过期时间)。这期间产生的多次请求和响应加在一起就称之为浏览器和服务器之间的一次会话
- 会话过程所产生的一些数据,可以通过会话技术(Cookie 和 Session)保存。
概述
- Cookie: 客户端会话管理技术
把要共享的数据保存到客户端
每次请求时,把会话信息带到服务器端,从而实现多次请求的数据共享
- 作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率
- 特点:
- 是一个普通的Java类
- 两个必须属性:name 和value
- 发送:
HttpServletResponse.addCookie(Cookie对象)
- 每个网站最多20个Cookie,浏览器存储的Cookie总数不大于300个,每个Cookie大小限制在4kb
- 获取所有Cookie对象:
HttpServletRequest.getCookie()
Cookie属性
属性名 |
作用 |
是否重要 |
name |
Cookie的名称 |
必须属性 |
value |
Cookie的值(不支持中文) |
必须属性 |
path |
Cookie的路径 |
重要 |
domain |
Cookie的域名 |
重要 |
maxAge |
Cookie的存活时间(s) |
重要 |
version |
Cookie的版本号 |
不重要 |
comment |
Cookie的描述 |
不重要 |
方法
方法名 |
作用 |
Cookie(String name, String value) |
构造方法创建对象 |
属性对应的set和get方法 |
赋值和获取值(name有final修饰,无set方法) |
- 向客户端添加Cookie:
void HttpServletResponse.addCookie(Cookie cookie)
- 获取所有的Cookie:
Cookie[] HttpServletRequest.getCookies()
练习
- 需求说明:通过Cookie记录最后访问时间,并在浏览器上显示出来
- 最终目的:掌握Cookie的基本使用,从创建到添加客户端,再到从服务器端获取
- 实现步骤
- 通过响应对象写出一个提示信息
- 创建Cookie对象,指定name和value
- 设置Cookie最大存活时间
- 通过响应对象将Cookie对象添加到客户端
- 通过请求对象获取Cookie对象
- 将Cookie对象中的访问时间写出
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.write("您的最后访问时间为:");
pw.write("
");
Cookie cookie = new Cookie("time", System.currentTimeMillis()+"");
cookie.setMaxAge(3600);
resp.addCookie(cookie);
Cookie[] cookies = req.getCookies();
for(Cookie ck : cookies){
if("time".equals(ck.getName())){
String value = ck.getValue();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String lastTime = sdf.format(new Date(Long.parseLong(value)));
pw.write(lastTime);
}
}
}
注意事项
- 数量限制
每个网站最多只能用20个Cookie,且大小不能超过4kb,所有网站的Cookie总数不超过300个
- 名称限制
Cookie的名称只能包含ASCII码表中的字母、数字字符。不能包含逗号、分号、空格,不能以$开头。
Cookie的值不支持中文
- 存活时间限制:
setMaxAge()
方法接收数字
负整数:当前会话有效,浏览器关闭则清除(默认)
0:立即清除
正整数:以秒为单位设置存活时间
- 访问路径限制
取自第一次访问的资源路径前缀
只要以这个前缀开头(包括子级路径)就能获取到,反之获取不到
设置路径:setPath()
方法设置指定路径
Session
- HttpSession:服务器端会话管理技术
- 本质也是采用客户端会话管理技术
- 只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中。
- 每次请求时,会将特殊标识带到服务器端,根据这个标识来找到对应的内存空间,从而实现数据共享
- 是Servlet规范中四大域对象之一的会话域对象
- 作用:可以实现数据共享
域对象 |
功能 |
作用 |
ServletContext |
应用域 |
在整个应用之间实现数据共享 |
ServletRequest |
请求域 |
在当前的请求或请求转发之间实现数据共享 |
HttpSession |
会话域 |
在当前会话范围之间实现数据共享 |
常用方法
返回值 |
方法名 |
说明 |
void |
setAttribute(String name, Object value) |
设置共享数据 |
Object |
getAttribute(String name) |
获取共享数据 |
void |
removeAttribute(String name) |
移除共享数据 |
String |
getId() |
获取唯一标识名称 |
void |
Invalidate() |
让session立即失效 |
对象获取
HttpSession 是一个接口,对应的实现类对象是通过HttpServletRequest 对象来获取
返回值 |
方法名 |
说明 |
HttpSession |
getSession() |
获取HttpSession对象 |
HttpSession |
getSession(boolean create) |
获取HttpSession对象,未获取到是否自动创建(默认true) |
练习
- 需求说明:通过第一个Servlet 设置共享数据用户名,并在第二个Servlet 获取到
- 最终目的:掌握HttpSession 的基本使用,如何获取和使用
- 实现步骤
- 在第一个 Servlet 中获取请求的用户名
- 获取 HttpSession 对象
- 将用户名设置到共享数据中
- 在第二个 Servlet 中获取 HttpSession 对象
- 获取共享数据用户名
- 将获取到的用户名响应给客户端浏览器
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
HttpSession session = req.getSession();
session.setAttribute("username",username);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Object username = session.getAttribute("username");
PrintWriter pw = resp.getWriter();
pw.write(username+"");
}
注意事项
- 唯一标识的查看:借助浏览器开发者工具
- 浏览器禁用Cookie
方式一:通过提示信息告知用户,大部分网站采用的解决方式【推荐】
方式二:通过resp.enconeURL
方法实现url重写(地址栏拼接jsessionid)【了解】
- 钝化和活化
- 钝化:序列化。把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上
- 活化:相反的状态
- 钝化时间
第一种情况: 当访问量很大时,服务器会根据getLastAccessTime 来进行排序,对长时间不用,但还没到过期时间的HttpSession进行序列化
第二种情况: 当服务器进行重启的时候,为了保持客户HttpSession 中的数据,也要对其进行序列化
HttpSession 的序列化由服务器自动完成,我们无需关心
JSP
- JSP(Java Server Pages):是一种动态网页技术标准
- JSP 部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成 HTML、XML 或其他格式文档的 Web网页,然后再响应给客户端。
- Jsp 是基于Java 语言的,它的本质就是 Servlet
类别 |
使用场景 |
HTML |
开发静态资源,无法添加动态资源 |
CSS |
美化页面 |
JavaScript |
给网页添加一些动态效果 |
Servlet |
编写Java 代码,实现后台功能处理 |
JSP |
包含了显示页面技术,也具备Java代码功能 |
快速入门
- 创建一个web项目
- 在web 目录下创建一个 index.jsp 文件
- 在文件中写一句内容为:这是我的第一个jsp
- 部署并启动项目
- 通过浏览器测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
第一个jsp
执行过程
- 客户端浏览器发送请求到Tomcat 服务器
- Tomcat 服务器解析请求地址
- 找到具体的应用
- 找到对应的jsp文件
- 将jsp文件翻译为.java的文件
- 编译Java文件
- 响应给客户端
文件内容介绍
- 生成的Java 文件目录
继承自 HttpJspBase类,而HttpJspBase继承自 HttpServlet(JSP本质上就是一个 Servlet)
jsp显示页面本质上就是通过获取输出流对象并通过write写出
语法
- JSP注释:
<%-- 注释的内容 --%>
- Java代码块:
<% Java代码 %>
- JSP表达式:
<%=表达式%>
- JSP声明:
<%! 声明变量或方法 %>
System.out.println()
:普通输出语句,输出在控制台上
out.println()
:JspWriter 对象,将内容输出在浏览器页面上,不会自动换行
<%="要输出的内容"%>
就相当于out.println("要输出的内容")
在声明中,如果加!
,代表声明的是成员变量;如果不加!
,代表声明的是局部变量;如果是声明方法,就必须加!
指令
- page 指令:
<%@ page 属性名=属性值 属性名=属性值... %>
属性名 |
作用 |
contentType |
响应正文支持的类型和设置编码格式 |
language |
使用的语言,默认是Java |
errorPage |
当前页面出现异常后跳转的页面 |
isErrorPage |
是否抓住异常,如果为true则页面中就可以使用异常对象,默认是false |
import |
导包 import= “java.util.ArrayList” |
session |
是否创建 HttpSession 对象,默认是true |
buffer |
设定 JspWriter 输出jsp内容缓存的大小,默认8kb |
pageEncoding |
翻译jsp时所用的编码格式 |
isEIgnored |
是否忽略EL表达式,默认是false |
- include 指令:可以包含其他页面
<%@ include file=包含的页面 %>
- taglib 指令:可以引入外部标签库
<%@ taglib uri=标签库的地址 prefix=前缀名称 %>
注意事项
- 九大隐式对象(不用创建,可以直接使用)
隐式对象名称 |
代表实际对象 |
request |
javax.servlet.http.HttpServletRequest |
response |
javax.servlet.http.HttpServletResponse |
session |
javax.servlet.http.HttpSession |
application |
javax.servlet.ServletContext |
page |
java.lang.Object |
config |
javax.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
学生管理系统3
登录功能
- 创建一个web目录
- 在web目录下创建一个index.jsp
- 在页面中获取会话域中的用户名,获取到了就显示添加和查看功能的超链接,没获取到就显示登录功能的超链接
- 在web目录下创建一个login.jsp。实现登录页面
- 创建 LoginServlet,获取用户名和密码
- 如果用户名为空,则重定向到登录页面
- 如果不为空,将用户名添加到会话域中,再重定向到首页
<%-- login.jsp --%>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 20:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录
学生信息管理系统--登录
package studentServlet;
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("/login")
public class login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String username = req.getParameter("username");
String password = req.getParameter("password");
resp.setContentType("text/html;charset=UTF-8");
if(null == username || "".equals(username)){
resp.getWriter().write("账号不能为空,请重新输入(2s后返回...)");
resp.setHeader("Refresh","2;URL=/login.jsp");
}else{
if("admin".equals(username) && "abc123".equals(password)){
session.setAttribute("username",username);
resp.sendRedirect("/index.jsp");
}else{
resp.getWriter().write("账号密码不正确,请重新输入(2s后返回...)");
resp.setHeader("Refresh","2;URL=/login.jsp");
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<%-- index.jsp --%>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 19:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
学生信息管理系统
学生信息管理系统
<% if(session.getAttribute("username") == null){ %>
请登录
<% } else { %>
添加学生信息
查看学生信息
<% } %>
<%-- list.jsp --%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="studentServlet.bean.Student" %>
<%--
Created by IntelliJ IDEA.
User: lihao
Date: 2022/2/24
Time: 20:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
查看学生
姓名 |
年龄 |
成绩 |
<%
ArrayList students = (ArrayList) session.getAttribute("students");
for(Student stu : students){
%>
<%=stu.getUsername()%> |
<%=stu.getAge()%> |
<%=stu.getScore()%> |
<% } %>
package studentServlet;
import studentServlet.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 java.io.*;
import java.util.ArrayList;
@WebServlet("/list")
public class list extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\\Java\\code\\StudentServlet\\stu.txt"));
ArrayList<Student> list = new ArrayList<>();
String str;
while((str = br.readLine()) != null){
String[] split = str.split(",");
Student stu = new Student(split[0], Integer.parseInt(split[1]), Integer.parseInt(split[2]));
list.add(stu);
}
req.getSession().setAttribute("students",list);
resp.sendRedirect("/list.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}