http协议的特点:称之为`无状态`, 请求与请求之间不会记录状态(状态就包括请求参数等信息)
1. Cookie
本意是小甜点, 可以用来记录多个请求之间的联系,保存服务器的状态
实现一个记住用户名的功能
1.1 创建Cookie
Cookie c = new Cookie("名字", "值"); // 创建cookie
c.setMaxAge(整数); // 设置cookie的寿命,单位是秒,没有设置寿命的是会话cookie浏览器关闭就删除
c.setMaxAge(0); // 设置寿命为0,意味着删除此cookie
response.addCookie(c); // 通过响应对象,把创建的cookie返回给浏览器
浏览器每次发送请求时,就会根据域名进行检查,把该域名下的所有cookie发给服务器
1.2 获取cookie
Cookie[] cookies = request.getCookies(); // 获取请求中所有的cookie
1.3 中文问题
URLEncoder.encode(中文, "utf-8"); // 将编码后的中文存入cookie的值
URLDecoder.decode("编码后的内容", "utf-8"); // 把编码后的内容进行解码
1.4 el表达式获取cookie值
el的语法:
${cookie.cookie的名称.value}
1.5 cookie的限制
浏览器每个域名下能够包含30~50个cookie
每个cookie的长度大约是4k左右
2.session 会话
session也是用来存储多次请求之间的状态信息,session是把这些信息存在服务器的内容当中
2.1 session创建
HttpSession session = request.getSession();
// 首次调用getSession方法就是创建session对象
// 后续再调用getSession方法是获取第一次创建好的session对象
存入内容
session.setAttribute("变量名", 任意信息);
获取内容
Obejct 信息 = session.getAttribute("变量名");
删除内容
Obejct 信息 = session.removeAttribute("变量名");
让session失效(会清空session中所有内容)
session.invalidate();
2.2 典型应用-用户登录
login.jsp:
<body>
<h1 style="color: red;">${sessionScope.msg}</h1>
<form action="/deptServlet" method="post">
<input type="text" name="method" value="login" style="display: none">
<input type="text" name="uname" placeholder="请输入用户名">
<input type="text" name="upwd" placeholder="请输入密码">
<input type="submit" value="登录">
</form>
</body>
servlet:
private void login(HttpServletRequest req, HttpServletResponse resp) {
String uname = req.getParameter("uname");
String upwd = req.getParameter("upwd");
try{
boolean log = deptService.login(uname,upwd);
if(log){
req.getSession().setAttribute("uname",uname);
resp.sendRedirect("index.jsp");
}else {
req.getSession().setAttribute("msg","登录失败,请重新登录");
resp.sendRedirect("/jsp/login.jsp");
}
}catch (Exception e){
e.printStackTrace();
}
}
service:
public boolean login(String uname,String upwd) {
boolean log= false;
User user = deptDao.login(uname);
if(user != null){
if(user.getUpwd().equals(upwd)){
log = true;
}
}
return log;
}
dao:
public User login(String uname) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
User user = null;
try {
conn = JDBCUtil.getConnection();
String sql="select * from user where uname = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1,uname);
rs = stmt.executeQuery();
if(rs.next()){
user = new User(rs.getInt("id"),
rs.getString("uname"),
rs.getString("upwd"));
}
return user;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally {
JDBCUtil.close(stmt,conn);
}
}
2.3 典型应用-用户注销(安全退出)
private void logout(HttpServletRequest req, HttpServletResponse resp)throws ServletException,
IOException {
req.getSession().invalidate();// 让session失效(让内容全部清空)
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
2.4 jsp页面获取session中的变量
${sessionScope.变量名}
2.5 session实现的原理
session 必须针对同一个浏览器,才能实现在请求存储信息,在之后的请求获取信息的效果
每个用户访问服务器时,服务器会为他们创建一个独立的session
1) 首次创建session时,tomcat会产生一个名为`JSESSIONID=session的唯一标识` 的特殊cookie
这个`JSESSIONID=1`就会随着响应返回给浏览器
2) 浏览器会记录这个cookie。之后的所有请求会把此cookie发送给服务器。
服务器根据cookie的值找到对应的session
3) jsessionid 这个cookie属于会话cookie,浏览器关闭就会消失
对比session和cookie
1) session是将信息存储于服务器端,cookie是将信息存储于浏览器端
2) session与cookie相比,更为安全
3) session的生命周期相对较短,
两次请求间隔超过30分钟,服务器会销毁session
调用session.invalidate方法时,会立刻销毁
cookie
会话cookie是浏览器关闭就销毁
setMaxAge的cookie会根据设置的寿命存活一段时间
4) 存储的信息量上
cookie 每个最大大小是4k左右
session 理论上没有限制,但session要占用服务器内存,所以不太适合存储太多的内容
信息要永久存储,还是需要使用数据库
5) cookie里数据都得是字符串,而session里可以存储任意类型
3. 重定向请求
请求转发:
request.getRequestDispatcher("目录路径").forward(request,response);
请求重定向:
response.sendRedirect("目录路径");
请求转发与重定向的区别:
1) 请求转发时,地址栏不会改变(是第一个servlet的地址)
重定向,地址栏会发生变化(是最后一个servlet的地址)
2) 请求转发是一次请求,跳转发生在服务器内部
重定向是两次请求,第一次请求会返回302的状态码和目标地址,
浏览器根据目标地址发送第二次请求,才完成整个流程
3) 重定向是两次请求,所以不能利用request作用域存值取值
但可以使用session作用域来存值取值
请求转发因为是同一次请求,所以可以使用request作用域存值取值
4) 请求转发的目标只能是本项目的servlet或jsp
重定向跳转的目标可以是任意的
应用场景:
查询
servlet --> jsp // 关系密切的跳转使用请求转发 forward()
删除
删除servlet --> 查询列表servlet // 关系不密切的跳转使用重定向 redirect()