Cookie
因为http协议是无状态的,每次都是基于一个请求一个响应.每次请求和响应都跟上次没有关系.
我们需要记录之前对话信息.
cookie技术.是属于客户端(浏览器)保存信息的技术.
让浏览器记住键值对.是向响应头中添加一下头即可:
set-Cookie:name=tom;
浏览器记住之后,向服务器发送键值对,是在请求头中添加下面的信息:
Cookie: name=tom;
Cookie使用方式
- 新建一个cookie(键值对)
Cookie cookie = new Cookie(“name”, “tom”); - 将cookie 添加到响应中
response.addCookie(cookie); - 获得所有浏览器发送的cookie
Cookie[] cookies = request.getCookies(); - 遍历并判断我们要找的cookie
if(cookies!=null && cookies.length>0){
for(Cookie c : cookies){
if(c.getName().equals("name")){
System.out.println("获得的cookie:"+c.getName()+":"+c.getValue());
}
}
}
//AServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie cookie = new Cookie("name", "tom");
response.addCookie(cookie);
response.getWriter().print("send cookie successed!");
}
//BServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0){
for(Cookie c : cookies){
if(c.getName().equals("name")){
System.out.println("获得的cookie:"+c.getName()+":"+c.getValue());
}
}
}
}
//先访问AServlet设置cookie,再设置BServlet获取Cookie
Cookie 有效时间
- 浏览器记多久?
默认是在会话期间有效.(关闭浏览器,cookie就被删除).(有效时间-1) - 有效时间如何设置?
//设置cookie的最大有效时间
1. 设置一个正数,标示最大有效时间.单位是秒
//cookie.setMaxAge(60*60);
2. 设置为-1 , 就是相当于默认有效时间, 浏览器关闭就消失.
//cookie.setMaxAge(-1);
3. 标示cookie的有效时间为0.发送到浏览器就消失了.
//利用有效时间为0 这件事,我们可以做删除cookie的操作.
// 因为同一个路径 ,不能存在相同的cookie(键相同).
// 我们可以通过覆盖的方式,设置有效时间为0. 删除cookie
cookie.setMaxAge(0);
Cookie路径
cookie的默认路径就是发送cookie的servlet所在目录.
访问路径如果是cookie路径的子路径那么,浏览器就会把该cookie告诉服务器.
例如通过/EServlet设置cookie,再次访问EServlet会将cookie添加到请求头中,访问/EServlet/xxx也会将cookie添加到请求头中,但是访问/xxx则不会
浏览历史(例子)
CServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 获得当前访问的品牌
String current = request.getParameter("name");
//2 获得之前访问过的品牌(获得cookie)
Cookie history = null;
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0){
for(Cookie c: cookies){
if(c.getName().equals("history")){
history = c;
}
}
}
//3 将当前访问 加上 之前访问的,创建一个新的cookie.
// "history" = "dell,apple,hasee"
String value = "";
if(history!=null){
value = history.getValue();
if(!history.getValue().contains(current)){ //判断当前访问的是否 之前已经访问过
value +=","+current;
}
}else{//没有获得到之前的cookie,说明是第一次访问.
value = current;
}
Cookie newHistory = new Cookie("history",value);
//4 将cookie添加到响应中
response.addCookie(newHistory);
//5 将商品记录 放置到request域中
request.setAttribute("history",value);
//6 转发到jsp显示
request.getRequestDispatcher("/history/list.jsp").forward(request, response);
}
<body>
<a href="<%=request.getContextPath() %>/CServlet?name=dell" >dell</a> <br>
<a href="<%=request.getContextPath() %>/CServlet?name=lenovo" >lenovo</a><br>
<a href="<%=request.getContextPath() %>/CServlet?name=apple" >apple</a><br>
<a href="<%=request.getContextPath() %>/CServlet?name=acer" >acer</a><br>
<a href="<%=request.getContextPath() %>/CServlet?name=hasee" >hasee</a><br>
浏览历史:
<%=request.getAttribute("history") %>
</body>
记住用户名
<!--Login.jsp-->
<%
//1 获得浏览器发送 过来的cookie
Cookie[] cookies = request.getCookies();
//2 遍历找到保存用户名的
Cookie remeber = null;
if(cookies!=null && cookies.length>0){
for(Cookie c: cookies){
if(c.getName().equals("remeber")){
remeber = c;
}
}
}
//3 如果找到取得它的值
//4把值设置到 用户名所在input
%>
<body>
<form action="/MyTestProject/FServlet" method="post" >
用户名: <input type="text" name="name" value="<%=remeber==null?"":remeber.getValue() %>" /><br>
密码: <input type="password" name="password" /><br>
记住用户名(一周): <input type="checkbox" name="remeber" value="yes" <%=remeber==null?"":"checked" %> /><br>
<input type="submit" value="登录" /> <br>
</form>
</body>
<!--index.jsp-->
<body>
This is my JSP page. <br>
</body>
//DServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 获得用户名
String name= request.getParameter("name");
String remeber = request.getParameter("remeber");
//新建cookie
Cookie cookie = new Cookie("remeber",name);
//2判断remeber .
if(remeber!=null && remeber.equals("yes")){
// "yes" 勾选了 ==> 设置有效时间为 一周
cookie.setMaxAge(60*60*24*7);
}else{
// null 没勾选 ==> 设置cookie的有效时间为0
cookie.setMaxAge(0);
}
//3 将cookie添加到response
response.addCookie(cookie);
//4 跳转到成功页面
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
Session
服务器端保存会话信息的技术.
浏览器第一次访问服务器,服务器会在内存中开辟一个空间(session),并把session对应的ID发送给浏览器.
那么下次浏览器再去访问服务器,会把sessionID 交给服务器,服务器通过sessionID 找到刚才开辟的空间.
以上就是session的原理.
Session相关
- 服务器让浏览器记住sessionID的cookie 默认过期时间是 (-1)==> 关闭浏览器 cookie就丢失 ==> cookie丢失 sessionID就丢失 ==> 找不到服务器的session
- session默认过期时间是30分钟. ==> 在tomcat的web.xml中 配置的.
修改session的过期时间
- 修改在tomcat的web.xml中 ==> 影响服务器中的所有项目
- 在项目的web.xml中 加入 配置.==> 影响的是当前项目
- 通过setMaxInactiveInterval(int interval)方法设置.==> 当前操作的session
操作session方法(除了set,get的四个方法)
- long getCreationTime() 获得创建时间
- String getId() 获得sessionID
- long getLastAccessedTime() 获得最后一次访问时间
- int getMaxInactiveInterval() 获得session的过期时间
- void setMaxInactiveInterval(int interval) 设置session的过期时间
- void invalidate() 让session立即失效
- boolean isNew() 查看当前获得session是否是新创建的(第一次获取session的时候是true)
购物车(例子)
<!--list.jsp-->
<table border=1 align="center">
<tr>
<td><h3>商品名称1</h3><img src="/MyTestProject/img/one.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=1">加入购物车</a><td>
<td><h3>商品名称2</h3><img src="/MyTestProject/img/two.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=2">加入购物车</a><td>
<td><h3>商品名称5</h3><img src="/MyTestProject/img/five.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=5">加入购物车</a><td>
</tr>
<tr>
<td><h3>商品名称3</h3><img src="/MyTestProject/img/three.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=3">加入购物车</a><td>
<td><h3>商品名称4</h3><img src="/MyTestProject/img/four.jpg" width="200" height=200><br/><a href="/MyTestProject/BServlet?name=4">加入购物车</a><td>
</tr>
</table>
<!--car.jsp-->
<%
//1. 获得session
//2. 从session中取出购物车的map
Map<String,Integer> map=(Map<String,Integer>)session.getAttribute("car");
%>
<body>
<h1 align="center">购物车详情</h1>
<table border=1 align="center">
<tr>
<th>商品名称</th>
<th>商品数量</th>
</tr>
<%
//3.遍历显示
if(map!=null&&map.size()>0){
for(Entry<String,Integer> en:map.entrySet()){
%>
<tr><td><%=en.getKey() %></td><td><%=en.getValue() %></td></tr>
<%
}
}else{
out.print("您还没有添加任何商品");
}
%>
</table>
</body>
//BServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.获得要添加的商品(0-4)
String name=request.getParameter("name");
int intName=Integer.parseInt(name);
//2.将数字翻译为中文名称(使用数组)
String[] products=new String[] {"商品名称1","商品名称2","商品名称3","商品名称4","商品名称5"};
String productName=products[intName];
//3.获得session
HttpSession session=request.getSession();
//4.获得session中保存的购物车(Map)
Map<String, Integer>map=(Map<String, Integer>) session.getAttribute("car");
if(map!=null) {
//获得到,则不是第一次访问,继续向Map中添加
Integer count=map.get(productName);
if(count==null) {
//不存在,添加并设置为1
count=1;
}else {
//map已存在此商品,数量加1
count++;
}
map.put(productName, count);
}else {
//没获得,第一次访问
map=new HashMap<String,Integer>();
//创建map,将商品添加并设为1
map.put(productName, 1);
}
//5.将Map操作完放回session
session.setAttribute("car", map);
//6.返回到列表页面(重定向)
response.sendRedirect(request.getContextPath()+"/car/list.jsp");
}
验证码(例子)
ValidateCode.jar 链接: https://pan.baidu.com/s/1mhFdihM 密码: 9est
//login.jsp
<head>
<script type="text/javascript">
function fun1(){
//1 获得img对象
var img = document.getElementById("one");
//2 改变img对象 src属性
img.src = "/MyTestProject/BServlet?abc="+new Date();
}
</script>
</head>
<body>
<form action="/MyTestProject/AServlet" method="post" >
用户名: <input type="text" name="name" /><br>
密码: <input type="password" name="password" /><br>
验证码: <input type="text" name="code" /><img src="/MyTestProject/BServlet" width="150" id="one" onclick="fun1();" />
<a href="javaScript:void(0)" onclick="fun1();" >看不清换一张</a><br>
<input type="submit" value="登录" /> <br>
</form>
<font color="red">
<%=request.getAttribute("error")==null?"":request.getAttribute("error") %>
</font>
</body>
//BServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.生成验证码
ValidateCode code=new ValidateCode(200,80,4,100);
//2. 将验证码保存到session中
request.getSession().setAttribute("code", code.getCode());
//3.将验证码图片输出到浏览器
response.setContentType("image/jpeg");
code.write(response.getOutputStream());
}
//AServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.获得表单提交的验证码
String code1=request.getParameter("code");
//2.获得session中正确的验证码
String code2=(String) request.getSession().getAttribute("code");
//3.比对是否一致
if(code1!=null&&code2!=null&&code1.equals(code2)) {
//正确
response.sendRedirect("/MyTestProject/index.jsp");
}else {
request.setAttribute("error", "验证码输入错误");
request.getRequestDispatcher("/checkcode/login.jsp").forward(request, response);
}
}
URL重写
如果浏览器 禁用cookie功能不能保存任何cookie.那么session技术要是用 cookie来保存sessionID. 没有cookie怎么保存?
使用url重写解决该问题.
将页面中所有的连接 末尾全都加上 cookieid的参数. 这样用户点击连接访问网站,通过url把SeesionID带到了服务器.这样就解决了.但是 互联网行业没有这么干的.
常见问题.
- session标示一次会话. 会话的范围?
1. session的开始 ==> 第一次访问服务器.
2. 结束 第一: 浏览器关闭.(保存sessionID的cookie默认有效时间是-1)
第二: 超过session设置的有效时间.默认30分钟. web.xml =><session-config><sessiont-timeout>
- session能不能跨项目?
不能跨项目. - session在一个项目中可以对项目中的任意路径共享数据吗?
保存sessionID的cookie的路径是 项目==> /Day10