会话技术Session

 一、概念

Session:服务器端会话技术,在一次会话中的多次请求间共享数据,将数据保存在服务器端的对象中
获取HttpSession对象
HttpSession sessionrequest.getSession()
使用HttpSession对象:主要介绍以下三个方法
Object getAttribute(String name)
void removeAttribute(String name)
void setAttribute(String name,Object value)
新建两个servlet:
@WebServlet("/ServletSessionDemo1")
public class ServletSessionDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用Session共享数据

// 1.获取session
HttpSession session = request.getSession();
// 2.存储数据
session.setAttribute("msg","hello session");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
@WebServlet("/ServletSessionDemo2")
public class ServletSessionDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// 获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

先访问Demo1,再访问Demo2

Session只能进行一次对话,如果再一次访问demo2,就访问不到

二、原理分析

总结:
session一定是依赖于cookie的;
在一次会话的范围内,多次获取的Session对象是同一个。

三、细节问题

1.当客户端关闭后,服务器不关闭,两次获取的session是同一个吗?
回答:默认不是同一个
解决方法:新建一个cookie对象

 

@WebServlet("/ServletSessionDemo3")
public class ServletSessionDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取Session
HttpSession session = request.getSession();
System.out.println(session);
// 希望客户端关闭以后,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

回答:基本不是同一个对象,但是要确保数据不丢失

Session的钝化:在服务器关闭前,将session对象序列化到硬盘里

Session的活化:在服务器启动后,将session文件转化为内存中的session对象即可

3.session的失效时间

服务器关闭

session对象调用invalid()方法

session默认有效时间30分钟(如果想要修改)

可以在Apache-tomcat文件的conf文件中找到web.xml文件,里面有标签<session-config>可以修改时间。

四、session的特点

1.session用于存储一次会话的多次请求数据,存在服务器端;

2.session可以存储任意类型,任意大小的数据;

session和cookie的区别:

session没有数据大小限制,cookie有;

session数据安全;

session存储数据在服务器端。

 五、验证码的案例

需求:

1.访问一个有验证码的登陆页面login

2.用户输入用户名,密码以及验证码

如果输入有误,跳转登陆页面,提示:用户名或者密码有误

如果验证码输入有误,则跳转到主页success.jsp,显示:用户名,欢迎

<head>
<title>login</title>
</head>
<body>
<form action="/day05/loginServlet" method="post">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="checkCode"></td>
</tr>
<tr>
<td colspan="2"><img src="/day05/ServletCheckCode"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登陆"></td>
</tr>
</table>
</form>
</body>
</html>

 为了能让验证码刷新,我们需要在验证码的图片上加时间戳:

<head>
<title>login</title>
<script>
window.onload = function () {
document.getElementById("img").onclick = function () {

this.src = "/day05/ServletCheckCode?time="+new Date().getTime();
}
}
</script>
</head>

以下新建两个servlet

第一个是验证码的设置

@WebServlet("/ServletCheckCode")
public class ServletCheckCode extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
// 1.创建对象,在内存中画图(验证码的图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
// 2.美化图片
// 2.1 填充背景
Graphics g = image.getGraphics();// 画笔对象
g.setColor(Color.PINK);// 设置笔画颜色
g.fillRect(0,0,width,height);
// 2.2 画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width-1,height-1);

String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // 列出验证码所有可能出现的情况

// 生成随机角标
Random ran = new Random();
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < 4;i++){
int index = ran.nextInt(str.length());
// 获取字符
char ch = str.charAt(index); // 随机字符
sb.append(ch);
// 2.3 写验证码
g.drawString(ch+"",width/5*i,height/2);// 验证码字母的位置 20/40/60/80
}
String checkCode_session = sb.toString();
// 将验证码存入session
request.getSession().setAttribute("checkCode_session",checkCode_session);
// 画干扰线
g.setColor(Color.GREEN);
// 随机生成坐标点
for(int i = 0 ;i< 10;i++){
int i0 = ran.nextInt(width);
int i1 = ran.nextInt(width);
int i2 = ran.nextInt(width);
int i3 = ran.nextInt(width);
g.drawLine(i0,i1,i2,i3);
}


// 3.图片输出
ImageIO.write(image,"jpg",response.getOutputStream());
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

第二个是登陆session的设置

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置request编码
request.setCharacterEncoding("utf-8");
// 获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
// 获取生成的验证码
HttpSession session = request.getSession();
String checkCode_session = (String)session.getAttribute("checkCode_session");
// 判断验证码是否正确
if(checkCode_session.equalsIgnoreCase(checkCode)){
// 忽略大小写比较
// 验证码正确
if("zhangsan".equals(username) && "123".equals(password)){// 需要查询数据库
// 登陆成功
// 存储信息
session.setAttribute("user",username);
// 重定向到success.jsp
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else{
// 失败
// 存储信息到request
request.setAttribute("login_error","用户名或者密码错误");
// 转发到登陆页面
request.getRequestDispatcher("login.jsp").forward(request,response);
}

}else{
//验证码不正确,存储信息到request
request.setAttribute("cc_error","验证码有误");
// 转发到登陆目录
request.getRequestDispatcher("/login.jsp").forward(request,response);

}

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

测试结果:验证码输入错误后跳转回登陆页面

 测试结果:输入错误用户名和密码

 成功:

 

细节修改:

1.不想输出是空值null

修改login.jsp

<div><%=request.getAttribute("cc_error") == null? "" : request.getAttribute("cc_error")%></div>
<div><%=request.getAttribute("login_error") == null? "" :request.getAttribute("login_error") %></div>

2.登陆成功后退出去,再用原来的验证码,会出错

在这里增加session的删除功能即可,再加上判断验证码是否为空

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值