Cookie技术简介:
1,简介
Cookie技术,会话保存数据在浏览器端
Cookie对象,保存会话数据
2,Cookie对象的使用:
创建Cookie对象,用于保存会话数据
new Cookie(java.lang.String name, java.lang.String value)
把Cookie数据发送给浏览器保存
response. addCookie(Cookie cookie) 发送cookie数据
服务器接收浏览器cookie数据
request. getCookies() 获取cookie信息
3.Cookie的原理
1)服务器创建Cookie对象,把会话保存到Cookie对象中
new Cookie("name","value");
2)服务器发送cookie到浏览器,通过响应头(set-cookie)
response.addCookie(cookie);
Set-Cookie: name=eric (响应头)
3)浏览器保存cookie数据,然后在下次访问时,会带着cookie数据访问服务器,通过请求头 (cookie)
Cookie: name=eric (请求头)
4)服务器接收到浏览器发送的cookie数据
request.getCookies();
3.4 Cookie细节
1)Cookie只能保存字符串类型的会话数据,不能保存对象类型
2)浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB
3)cookie不适合保存敏感数据。
4)void setPath(java.lang.String uri) 设置cookie的有效路径。有效路径是指浏览器在访问服务器时,只会携带当前有效路径下的cookie数据。
5)void setMaxAge(int expiry) 设置cookie的有效时长。
正整数:把cookie信息存放到浏览器的硬盘缓存目录中。只有当超过整数值的时间(秒), cookie就会丢失。
负整数:把cookie信息存放到浏览器内存中。只有当关闭浏览器,cookie才会丢失。
零:删除同名的cookie
6)setValue(java.lang.String newValue) 设置cookie的值。
Cookie案列
显示浏览过的商品
Product类,封装商品对象
public class Product {
private int id ;
private String prodName;
private String prodType;
private double price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProdName() {
return prodName;
}
public void setProdName(String prodName) {
this.prodName = prodName;
}
public String getProdType() {
return prodType;
}
public void setProdType(String prodType) {
this.prodType = prodType;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Product [id=" + id + ", prodName=" + prodName + ", prodType="
+ prodType + ", price=" + price + "]";
}
public Product(int id, String prodName, String prodType, double price) {
super();
this.id = id;
this.prodName = prodName;
this.prodType = prodType;
this.price = price;
}
public Product(){
}
}
下面是处理商品数据类:
/**
* 商品的dao类
*
*/
public class ProductDao {
//静态数据
private static List<Product> datas = new ArrayList<Product>();
public ProductDao(){
}
static{
//初始化数据,没有数据库,先用静态数据。
for (int i = 0; i <= 10; i++) {
datas.add(new Product(i, "笔记本"+i, "型号"+i, 30+i));
}
}
/**
* 查询所有商品信息
*/
public List<Product> findAll(){
return datas;
}
/**
* 根据商品id查询数据
* @param id
* @return
*/
public Product findById(int id){
for (Product prod : datas) {
if(prod.getId() == id)
return prod;
}
return null;
}
}</span>
然后到展示商品信息Servlet
<span style="font-size:14px;">/**
* 显示商品列表
*/
public class ListProdServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//解决编码问题
response.setContentType("text/html;charset=UTF-8");
//从"数据库"取出商品列表
ProductDao dao = new ProductDao();
List<Product> list = dao.findAll();
//显示给用户(浏览器)
PrintWriter writer = response.getWriter();
String html="";
html += "<html>";
html += "<head><title>商品列表页面</title>";
html += "</head>";
html += "<body><table border='1' align='center'" +" width='600px'>";
html+="<tr><th>编号</th><th>商品名称</th><th>型号</th><th>价格</th></tr>";
if(list != null){
for(Product prod : list){
html+="<tr>";
html+="<td>"+prod.getId()+"</td>";
//访问DetailProdServlet且传递一个名为id值为id 的参数
html+="<td><a href='"+request.getContextPath()+"/DetailProdServlet?id="+prod.getId()+"'>"+prod.getProdName()+"</a></td>";
html+="<td>"+prod.getProdType()+"</td>";
html+="<td>"+prod.getPrice()+"</td>";
html+="</tr>";
}
}
html+="</table>";
/**
* 显示浏览过的商品
*/
html+="<hr/>";
html+="最近浏览过的商品<br/>";
//去除浏览器发送过来的cookie名称为prodHist
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("prodHist")){
String prodHist = cookie.getValue();
String [] ids = prodHist.split(",");
for(String id1 : ids){
Product prod1 = dao.findById(Integer.parseInt(id1));
html += " "+prod1.getId()+" "+prod1.getProdName()+" "+prod1.getPrice()+"</br>";
}
break;
}
}
}
html+="</body></html>";
writer.write(html);
html="";
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是商品详情信息Servlet:
/**
* 商品详情
* @author Jam
*
*/
public class DetailProdServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//接收编号
String idStr = request.getParameter("id");
//创建数据处理对象
ProductDao dao = new ProductDao();
//获取输出流对象
PrintWriter writer = response.getWriter();
//构造字符串
String html = "";
if(idStr !=null && !idStr.equals("")){
int id = Integer.parseInt(idStr);
//查询商品
Product prod = dao.findById(id);
html+="<html><head><title>商品列表页面</title>" +
"</head><body>";
html+="<table border='1' align='center'" +
" width='250px'>";
if(prod != null){
html+="<tr><th>编号</th><td>"+prod.getId()+"</td></tr>";
html+="<tr><th>商品名称</th><td>"+prod.getProdName()+"</td></tr>";
html+="<tr><th>型号</th><td>"+prod.getProdType()+"</td></tr>";
html+="<tr><th>价格</th><td>"+prod.getPrice()+"</td></tr>";
}
html+="</table>";
html+="<center><a href='/HistoryProduct/ListProdServlet'>[返回商品列表]</a></center>";
html+="</body></html>";
writer.write(html);
//创建Cookie对象,把当前商品对象保存到cookie中
Cookie cookie = new Cookie("prodHist", getCookieValue(idStr,request));
cookie.setMaxAge(30*24*60*60); //保存一个月
//把Cookie发送到浏览器
response.addCookie(cookie);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* 返回一个最终的cookie值
*/
private String getCookieValue(String id,HttpServletRequest request){
Cookie[] cookies = request.getCookies();
String s = id;
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("prodHist")){
String prodHist = cookie.getValue();
String [] ids = prodHist.split(",");//从cookie获取id数组
for(String i :ids){
if(!i.equals(s)){ //cookie里面有当前浏览商品,就不要那个id,直接跳过
id += ","+i;
}
}
if(ids.length<3){//表示cookie携带的id数不超过3个
return id;
}else{
id = id.substring(0, 5);
}
}
}
}
return id;
}
}
上面的例子展示了Servlet通过Cookie保存信息,显示浏览过的商品。
Session对象
HttpSession 是服务器技术,创建于服务器,每个浏览器都有自己独立的HttpSession,不共享。
Cookie和Session都是解决服务器和客户端的数据保存,Cookie是基于浏览器的缓存,属于客户端技术,相对来说,不太安
全,通常存一些无关紧要的数据。
Session是给予服务器的技术,存于服务器中,收web服务器的限制.
response.getSeesion 表示获取session对象,没有该对象会自动创建转发和重定向情况下,都可多个Servlet可共享
HttpSessionyu域对象
Request何时创建销毁?
创建的场景
一次请求到大web服务器,request和response都创建了
销毁的场景
一次请求响应后,原request和response对象都销毁
ServletContext创建销毁时间?
web发布到web服务器启动时创建的,在web服务器停止时销毁,或者重新部署web应用到服务器
Session创建和销毁
创建:
1.如果是Servlet的话,通过request.getSession()创建
2.如果是JSP的话,默认访问JSP,服务器自动创建Session
销毁:
1. web服务器停止
2. 重新部署web应用到服务器
3. 设置session的有效时间,默认为30分钟
4. 强行代码销毁
修改HttpSession的有效方法有2种
session.setMaxInactiveInterval(int second);
修改配置文件web.xml ,单位为分钟
<session-congif>
<session-timeout>
1
</session-timeout>
</session-config>
以代码优先
Session和Cookie的主要区别在于:
Cookie是把用户的数据写给用户的浏览器。 Session技术把用户的数据写到用户独占的session中。 Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
多个servlet中共享session问题
服务器创建session后,在响应中提交了一个cookie jsessionid ,该cookie不会缓存到浏览器
然后浏览器访问另一个servlet的时候发送过去,servlet通过cookie提供的jsessionid找到该session
禁用浏览器cookie情况下,session在不同servlet中共享问题?
解决方案:URL重写
response. encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。
response. encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写
就算浏览器重新可以接收Cookie了,依然可以用RRL重写
第一次访问,他采用URL重写,第二次发现请求头cookie有效,那么就不采用URL重写了。