会话:用户打开浏览器,访问Web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
会话跟踪技术: 一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一服务器,以便在同一次会话的多次请求间共享数据
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享
实现方式:
客户端会话跟踪技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
Cookie cookie=new Cookie("key","value");
response.addCookie(cookie);
一、添加pom依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
二、创建Servlet
package com.GY;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "AServlet", value = "/AServlet")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 发送Cookie
// 1.创建Cookie对象
Cookie cookie=new Cookie("username","GY");
// 2.发送Cookie
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
三、启动服务器,在浏览器中查看Cookie数据
Cookie[] cookies=request.getCookies();
cookie.getName();
cookie.getValue();
一、 创建Servlet
package com.GY.cookie;
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;
@WebServlet(name = "BServlet", value = "/BServlet")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取Cookie
// 1.获取Cookie数组
Cookie[] cookies = request.getCookies();
// 2.遍历数组
for (Cookie cookie : cookies) {
// 3.获取数据
String name = cookie.getName();
if ("username".equals(name)) {
String value = cookie.getValue();
System.out.println(name+":"+value);
break;
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Cookie的实现是基于HTTP协议的
● 响应头: set-cookie
● 请求头: cookie
● Cookie存活时间
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
setMaxAge(int seconds):设置Cookie存活时间
1.正数: 将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除(不会随浏览器的关闭而被销毁)
2.负数: 默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
3.零: 删除对应Cookie
● Cookie存储中文
Cookie不能直接存储中文
如需要存储,则需要进行转码: URL编码
① Cookie存活时间
// 设置存活时间 , 一周(七天)
cookie.setMaxAge(60*60*24*7);
package com.GY.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
@WebServlet(name = "AServlet", value = "/AServlet")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 发送Cookie
// 1.创建Cookie对象
String value="张三";
// URl编码
value=URLEncoder.encode(value,"UTF-8");
System.out.println("存储数据:"+value);
Cookie cookie=new Cookie("username",value);
// 设置存活时间 , 一周(七天)
cookie.setMaxAge(60*60*24*7);
// 2.发送Cookie
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
URL解码
package com.GY.cookie;
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.net.URLDecoder;
@WebServlet(name = "BServlet", value = "/BServlet")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取Cookie
// 1.获取Cookie数组
Cookie[] cookies = request.getCookies();
// 2.遍历数组
for (Cookie cookie : cookies) {
// 3.获取数据
String name = cookie.getName();
if("username".equals(name)) {
String value = cookie.getValue();
// URL解码
value = URLDecoder.decode(value, "UTF-8");
System.out.println(name + ":" + value);
break;
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
服务端会话跟踪技术,将数据保存到服务端
JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能
HttpSession session=request.getSession();
void setAttribute(String name,Object o): 存储数据到Session域中
Object getAttribute(String name): 根据key,获取值
void removeAttribute(String name): 根据key,删除该键值对
一、创建Servlet(存储数据)
package com.GY.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet(name = "A1Servlet", value = "/A1Servlet")
public class A1Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取Session对象
HttpSession session = request.getSession();
// 2.存储数据
session.setAttribute("username","GY");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
二、创建Servlet(获取数据)
package com.GY.session;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "B1Servlet", value = "/B1Servlet")
public class B1Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 从Session中获取数据
// 1.获取对应的Session对象
HttpSession session = request.getSession();
// 2. 获取数据
Object username = session.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
● Session钝化、活化
服务器重启后,Session中的数据是否还在?
钝化: 在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
活化: 再次启动服务器后,从文件中加载数据到Session中
● Session销毁
默认情况下,无操作,30分钟自动销毁(分钟)【可在web.xml中配置】
<session-config>
<session-timeout>30</session-timeout>
</session-config>
调用Session对象的invalidate()方法
Cookie和Session都是来完成一次会话内多次请求间数据共享的
区别:
● 存储位置: Cookie是将数据存储在客户端,Session是将数据存储在服务端
● 安全性: Cookie不安全,Session安全
● 数据大小: Cookie最大3kb,Session无大小限制
● 存储时间: Cookie可以长期存储,Session默认30分钟
● 服务器性能: Cookie不占服务资源,Session占用服务资源
【一般Cookie保证用户未登录的情况下身份识别,Session一般保存用户登录后的数据;不同的需求需具体分析后选择】
需求说明:
1. 完成用户登录功能,如果用户勾选 “记住用户” ,
则下次访问登录页面,自动填充用户名密码
3. 完成注册功能,并实现验证码验证
数据库表数据——user表
数据库数据——tb_brand表
项目资源
链接:https://pan.baidu.com/s/1CVGnG3bHGdq5dSGHBDin9g
提取码:GY66
Mybatis配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.GY.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useServerPrepStmts=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.GY.mapper"/>
mappers>
configuration>
Dao层——BrandMapper
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface BrandMapper {
@Select("select * from tb_brand")
@ResultMap("brandResultMap")
List<Brand> selectAll();
}
Dao层——UserMapper
package com.GY.mapper;
import com.GY.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
@Select("select * from user where username = #{username} and password = #{password}")
User select(@Param("username") String username,@Param("password") String password);
}
Service层——UserService
package com.GY.service;
import com.GY.mapper.UserMapper;
import com.GY.pojo.User;
import com.GY.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class UserService {
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
public User login(String username,String password){
//2. 获取SqlSession
SqlSession sqlSession = factory.openSession();
//3. 获取UserMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//4. 调用方法
User user = mapper.select(username, password);
//释放资源
sqlSession.close();
return user;
}
}
Service层——BrandService
package com.GY.service;
import com.GY.mapper.BrandMapper;
import com.GY.pojo.Brand;
import com.GY.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class BrandService {
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
public List<Brand> selectAll(){
//调用BrandMapper.selectAll()
//2. 获取SqlSession
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
List<Brand> brands = mapper.selectAll();
sqlSession.close();
return brands;
}
}
Web层——LoginServlet类
package com.GY.web;
import com.GY.pojo.User;
import com.GY.service.UserService;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
private UserService service = new UserService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2. 调用service查询
User user = service.login(username, password);
//3. 判断
if(user != null){
//登录成功,跳转到查询所有的BrandServlet(重定向)
// 将登录成功后的User对象,存储到Session
HttpSession session = request.getSession();
session.setAttribute("user",user);
String contextPath = request.getContextPath();
response.sendRedirect("/selectAllServlet");
}else {
// 登录失败,
// 存储错误信息到request
request.setAttribute("login_msg","用户名或密码错误");
// 跳转到login.jsp
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Web层——SelectAllServlet 类
package com.GY.web;
import com.GY.pojo.Brand;
import com.GY.service.BrandService;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.List;
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 调用BrandService完成查询
List<Brand> brands = service.selectAll();
//2. 存入request域中
request.setAttribute("brands",brands);
//3. 转发到brand.jsp(请求转发)
request.getRequestDispatcher("/brand.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}