1,会话:一次会话中包含多次请求和响应。一次会话,即浏览器第一次给服务器资源发送请求,会话建立,直到一方断开为止。
2,功能:在一次会话的范围内多次请求间共享数据。
3,方式:
客户端会话技术:cookie;
服务端会话技术:session.
1,概念:客户端会话技术,将数据保存到客户端。
2,入门
(1),创建cookie对象,绑定数据;
new Cookie(String name, String value)
(2),发送cookie对象;
response.addCookie(Cookie cookie)
(3),获取cookie对象,拿到数据。
Cookie[] request.getCookies()
@WebServlet("/cookieDemo1")
public class CookieDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "hello");
Cookie cookie2 = new Cookie("name", "张三");
//20s后清除该cookie消息
//cookie.setMaxAge(300);
//删除浏览器中该cookie消息
//cookie.setMaxAge(0);
response.addCookie(cookie);
response.addCookie(cookie2);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
@WebServlet("/cookieDemo2")
public class CookieDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cs = request.getCookies();
for (Cookie c : cs) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
/*
msg:hello
name:张三
Pycharm-360fce62:285bf332-1657-478a-a3bf-ccb521740439
Idea-a77fa8ec:bf922fbc-6589-4632-9a1c-c2788ffca99f
*/
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
3,实现原理:基于响应头set-cookie和请求头cookie实现。
4,cookie技术细节
(1) 一次可不可以发送多个cookie?
可以,创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
(2) cookie在浏览器中保存多长时间?
(3),cookie能不能存中文?
在tomcat 8 之前 cookie中不能直接存储中文数据,需要将中文数据转码—一般采用URL编码(%E3);
在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析.
(4), cookie共享问题?
1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
默认情况下cookie不能共享, setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录,即如果要共享,则可以将path设置为"/"
2.不同的tomcat服务器间cookie共享问题?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享;
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享。
5,cookie特点及作用
特点:
(1),cookie在客户端浏览器存储数据;
(2),浏览器对于单个cookie大小有限制(4kb),以及同一个域名下总cookie数量也有限制(20个)。
作用:
(1),cookie一般用于存储少量不太敏感的数据;
(2),在不登录的情况下,完成服务器对客户端的识别。
6,cookie应用案例:记住上一次访问时间
需求:
@WebServlet("/cookieVisit")
public class CookieVisit extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
response.setContentType("text/html;charset=utf-8");
boolean flag = false;
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if ("time".equals(name)) {
flag = true;
String timeVal = cookie.getValue();
timeVal = URLDecoder.decode(timeVal, "utf-8");
Date day = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = df.format(day);
//cookie值包含特殊字符,需要进行URL编解码
time = URLEncoder.encode(time, "utf-8");
cookie.setValue(time);
response.addCookie(cookie);
response.getWriter().write("欢迎回来!您上次登录的时间为: " + timeVal);
break;
}
}
}
if (flag == false || cookies == null) {
Date day = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = df.format(day);
time = URLEncoder.encode(time, "utf-8");
Cookie timeCookie = new Cookie("time", time);
response.addCookie(timeCookie);
response.getWriter().write("欢迎您首次登陆!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
1,概念:Java Server Pages,java服务端页面,是一个特殊的页面,既可以定义HTML标签,也可以定义java代码,用于简化书写。
2,原理:本质上是一个Servlet。
3,JSP脚本
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>index页面</h1>
<%
System.out.println("hello,jsp");
int i = 1;
%>
<%!
int i = 2;
%>
<%=
i
%>
<%
out.print("out输出");
%>
<%
response.getWriter().write("response输出");
%>
<%--response输出--%>
<%--index页面--%>
<%--1 out输出--%>
</body>
</html>
4,jsp内置对象
概念:在jsp页面中不需要获取和创建,可以直接使用的对象。如以下三个:
(1)request
(2)response
(3)out:字符输出流对象。可以将数据输出到页面上,和response.getWriter()类似。
response.getWriter()和out.write()的区别:
在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据,所以response.getWriter()数据输出永远在out.write()之前。
5,通过jsp改造Cookie案例
<%@ page import="java.net.URLDecoder" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %><%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2020/7/5
Time: 12:23
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>
<%
Cookie[] cookies = request.getCookies();
response.setContentType("text/html;charset=utf-8");
boolean flag = false;
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if ("time".equals(name)) {
flag = true;
String timeVal = cookie.getValue();
timeVal = URLDecoder.decode(timeVal, "utf-8");
Date day = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = df.format(day);
//cookie值包含特殊字符,需要进行URL编解码
time = URLEncoder.encode(time, "utf-8");
cookie.setValue(time);
response.addCookie(cookie);
%>
<h1>"欢迎回来!您上次登录的时间为: <%= timeVal%>"</h1>
<%
break;
}
}
}
if (flag == false || cookies == null) {
Date day = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = df.format(day);
time = URLEncoder.encode(time, "utf-8");
Cookie timeCookie = new Cookie("time", time);
response.addCookie(timeCookie);
%>
<h1>"欢迎您首次登陆!"</h1>
<%
}
%>
<h3>登录表单1</h3>
<form action="">
账号:<input type="text">
密码:<input type="password">
<input type="submit" value="登录">
</form>
</body>
</html>
1,概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象HttpSession中。
2,入门:
(1)获取session对象:request.getSession();
(2)使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
3,原理:session的实现是依赖于cookie的。
4,session技术细节
(1)当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
默认情况下不是。如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
@WebServlet("/sessionDemo3")
public class SessionDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println(session);
//设置cookie值,关闭浏览器后访问的session对象是同一个
Cookie c = new Cookie("JSESSIONID", session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
(2)客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
(a)session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上;
(b) session的活化: 在服务器启动后,将session文件转化为内存中的session对象即可。
(3)session什么时候被销毁?
(a) 服务器关闭
(b) session对象调用invalidate() 。
(c)session默认失效时间 30分钟,可选择性配置修改
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5,session的特点
(a)session用于存储一次会话的多次请求的数据,存在服务器端;
(b) session可以存储任意类型,任意大小的数据。
6, session与Cookie的区别
(a)session存储数据在服务器端,Cookie在客户端;
(b)session没有数据大小限制,Cookie有;
(c) session数据安全,Cookie相对于不安全。
案例需求:
1. 访问带有验证码的登录页面login.jsp
2. 用户输入用户名,密码以及验证码。
* 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
* 如果验证码输入有误,跳转登录页面,提示:验证码错误
* 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
window.onload = function () {
document.getElementById("checkcode").onclick = function () {
this.src = "/day5/checkCodeDemo1?" + new Date().getTime();
}
}
</script>
<style>
.error{
color: red;
}
</style>
</head>
<body>
<table>
<form action="/day5/login" method="post">
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td class="error"><%=request.getAttribute("up_error") == null ? "" : request.getAttribute("up_error")%></td>
</tr>
<tr>
<td>验证码:</td>
<td>
<input type="text" name="checkcode">
</td>
</tr>
<tr>
<td class="error"><%=request.getAttribute("ccode_error") == null ? "" : request.getAttribute("ccode_error")%></td>
</tr>
<tr>
<td colspan=20>
<img id="checkcode" src="/day5/checkCodeDemo1" alt="">
</td>
</tr>
<tr>
<td colspan=20>
<input type="submit" value="登录">
</td>
</tr>
</form>
</table>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3><%=request.getSession().getAttribute("username")%>登录成功</h3>
</body>
</html>
@WebServlet("/login")
public class login 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");
String session_code = (String)request.getSession().getAttribute("session_code");
if (session_code != null && session_code.equalsIgnoreCase(checkcode)){
//验证码匹配
if ("张三".equals(username) && "123".equals(password)){
//用户名和密码正确
request.getSession().setAttribute("username",username);
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else{
//用户名和密码错误
request.setAttribute("up_error","用户名或密码错误!请重试");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}else{
//验证码错误
request.setAttribute("ccode_error","验证码错误!请重试");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
@WebServlet("/checkCodeDemo1")
public class CheckCodeDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
int width = 160;
int height = 80;
//创建图片对象
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//美化图片
Graphics gh = image.getGraphics();
gh.setColor(Color.PINK);
gh.fillRect(0,0,width,height);
gh.setColor(Color.BLUE);
gh.drawRect(0,0,width-1,height-1);
Random rd = new Random();
String s = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
StringBuilder session_ckcode = new StringBuilder();
for (int i = 1; i <= 4; i++) {
int index = rd.nextInt(s.length());
char ch = s.charAt(index);
session_ckcode.append(ch);
gh.drawString(ch+"",width/5*i,height/2);
}
//将验证码存储到session当中
String session_code = session_ckcode.toString();
HttpSession session = request.getSession();
session.setAttribute("session_code",session_code);
gh.setColor(Color.GREEN);
for (int i = 0; i < 10; i++) {
int x1 = rd.nextInt(width);
int x2 = rd.nextInt(width);
int y1 = rd.nextInt(height);
int y2 = rd.nextInt(height);
gh.drawLine(x1,y1,x2,y2);
}
//将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
this.doPost(request,response);
}
}