1. 编写QQ空间数据类(QQS.java)

public class QQS {
private static LinkedHashMap<Integer, String> qqs =
new LinkedHashMap<Integer, String>();
static{
qqs.put(, "张三");
qqs.put(, "李四");
qqs.put(, "王五");
qqs.put(, "赵六");
qqs.put(, "田七");
qqs.put(, "焦八");
qqs.put(, "侯九");
qqs.put(, "柳十");
qqs.put(, "小二");
}
public static LinkedHashMap<Integer, String> getQqs() {
return qqs;
}
}

2. 编写一个现实QQ数据和浏览记录的页面(ListServlet.java)

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 获取Session对象
HttpSession session = request.getSession();
// 设置中文数据
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取输出流
PrintWriter out = response.getWriter();
// 获取QQS数据
LinkedHashMap<Integer, String> qqs = QQS.getQqs();
Set<Map.Entry<Integer, String>> set = qqs.entrySet();
Iterator<Map.Entry<Integer, String>> it = set.iterator();
// 输出页面结构
out.println("<html><head><title>QQ列表</title><style>a{margin-right:20px;}</style></head><body>");
out.println("<hr/><br/>");
out.println("<h3>QQ列表</h3>");
out.println("<hr/><br/>");
// 循环输出QQ空间的超链接
while(it.hasNext()){
Map.Entry<Integer, String> entry = it.next();
Integer num = entry.getKey();
String name = entry.getValue();
out.println("<a href=\"/day08/store?num="+num+"\">"+name+"</a>");
}
// 输出浏览的记录信息
out.println("<hr/><br/>");
out.println("<h3>QQ浏览记录</h3>");
out.println("<hr/><br/>");
// 获取访问记录数据
String history = (String) session.getAttribute("history");
if(history == null){
out.println("<font color=\"red\">对不起,目前没有访问记录...</font>");
}else{
// 循环遍历用户访问的记录数据
String[] nums = history.split(",");
for(String num:nums){
String name = QQS.getQqs().get(Integer.parseInt(num));
out.println(name+" ,");
}
}
// 关闭页面结构
out.println("</body></html>");
}

3. 编写一个存储浏览QQ空间的页面(StoreQQServlet.java)

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 获取Session对象
HttpSession session = request.getSession(false);
// 获取请求参数
String num = request.getParameter("num");
// 获取Session中的数据
String history = (String) session.getAttribute("history");
// 判断数据
if(history == null){
// 第一次访问
session.setAttribute("history", num); // history=10001
}else{
// 访问多次
session.setAttribute("history", history+","+num);
// 设置num的数量和显示的顺序
String[] qqs = history.split(",");
// 将数组转换为方便操作的集合
List<String> list = Arrays.asList(qqs);
// 将List转换为LinkedList便于操作数据
LinkedList<String> linked_list = new LinkedList<String>();
linked_list.addAll(list);
// 判断出现的QQ次数
if(qqs.length < ){
if(linked_list.contains(num)){ // history=10002,1003
// 如果包含
linked_list.remove(num);
linked_list.addFirst(num);
}else{ // history=1004,10002,1003
// 不包含
linked_list.addFirst(num);
}
}else{ // >= 3
if(linked_list.contains(num)){
// history=10002,10003,10004 10004
// 如果包含
linked_list.remove(num);
linked_list.addFirst(num);
}else{ // history= 10005 ,10002,10003
// 不包含
linked_list.removeLast();
linked_list.addFirst(num);
}
}
// 次数好了,顺序好了的访问记录linked_list
StringBuffer sb = new StringBuffer();
for(String new_num:linked_list){
sb.append(new_num+",");
}
String new_history = sb.toString();
session.setAttribute("history", new_history);
}
// 重定向到QQ列表页面
response.sendRedirect("/day08/list");
}

以上的代码将用户的浏览记录存储在了session对象中,但是该对象是在服务器内存中的,且有有效的时间限制,如果时间到了,那么session就会被销毁。

默认的时间为半个小时(30分钟)。

4  配置Session的有效时间

在每一个网站的web.xml中可以配置该网站创建的session对象的有效时间。注意的是配置时单位是分钟。

Thread.slessp(毫秒单位)、Cookie.setMaxAge(秒单位)、session(分钟单位)

  <session-config>
<session-timeout></session-timeout>  单位是分钟
</session-config>

5  Cookie的禁用

Cookie可以利用客户端存储会话数据。

HttpSession可以利用Cookie存储SessionID信息。

其实在浏览器的设置中可以拒绝网站发送回来的Cookie信息。

此时再访问以上的案例就会导致空指针异常出现。如果需要将网站修复,那么必须使用URLRewriting技术。

URLRewritting

分析以上问题的原因:

服务器创建好了Session对象,但是由于浏览器禁止了Cookie的接收,那么服务器无法将创建好的Session的ID值以Set-Cookie的响应头方式发送给浏览器进行存储,那么在第二访问的时候也就不会懈怠SessionID,因此无法找到Session。

常用的方法

String encodeRedirectURL(String url)      给指定的重定向路径后添加Sessionid信息
String encodeURL(String url)  给普通的URL地址添加Sessionid信息

实施的原则:

“将页面中的所有的URL地址全部使用以上方法进行重新编码”

1 修改以上程序

1 ListServlet.java

String path = "/day08/store?num="+num;
path = response.encodeURL(path);
out.println("<a href='"+path+"'>"+name+"</a>");

2. StoreQQServlet.java

String path = "/day08/list";
path = response.encodeRedirectURL(path);
response.sendRedirect(path);

java学习笔记—使用HttpSession实现QQ的访问记录(31)的更多相关文章

  1. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  2. Java学习笔记之---Servlet

    Java学习笔记之---Servlet (一)如何实现Servlet 1.实现javax.servlet.Servlet接口: 2.继承javax.servlet.GenericServlet类: 3 ...

  3. java学习笔记(1)java的基础介绍 、JDK下载、配置环境变量、运行java程序

    java工程师是开发软件的 什么是软件呢? 计算机包括两部分: 硬件: 鼠标.键盘.显示器.主机箱内部的cpu.内存条.硬盘等 软件: 软件包括:系统软件和应用软件 系统软件:直接和硬件交互的软件:w ...

  4. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  5. 0035 Java学习笔记-注解

    什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...

  6. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  7. 0032 Java学习笔记-类加载机制-初步

    JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...

  8. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  9. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

随机推荐

  1. oracle中bulk collect into用法

    通过bulk collect减少loop处理的开销 采用bulk collect可以将查询结果一次性地加载到collections中. 而不是通过cursor一条一条地处理. 可以在select in ...

  2. sql日期查询

    select getdate() ,getdate()) ,getdate()) ) ,getdate())) ,getdate())) Select datename(weekday, getdat ...

  3. struts2配置默认首页

    配置struts2 默认欢迎页的几种办法: 1.首先需要明确的是struts过滤器配置映射的模式是路径匹配还是扩展匹配,如果url-pattern配置为/*,如果不做特殊处理,是不会转到welcome ...

  4. 让 IE6支持max-height

    min-height min-height:100px; _height:100px max-height max-height:200px; overflow:auto;/*超出部分显示滚动条*/ ...

  5. grep 过滤.svn文件

    [grep 过滤.svn文件] 问题: 在repository搜索代码时,常常会搜索到.svn的代码,如果不想搜索.svn目录下的相关代码怎么办?    1.使用管道进行双层“过滤”,其中第二次gre ...

  6. linux sudo 系统环境变量 用户环境变量

    1. sudo就是普通用户临时拥有root的权限.好处在于,大多数时候使用用户自定义的配置,少数情况可以通过sudo实现root权限做事. 故而,需要注意的一点是,在你使用了sudo后,你临时不再是原 ...

  7. Qt Read and Write Csv File

    This page discusses various available options for working with csv documents in your Qt application. ...

  8. golang之map数据类型

    先上代码…… package main import "fmt" func testMap() { //两种声明map方式,切记,必须初始化才能用,否则panic //var a ...

  9. Android应用程序的基本组件介绍

    1.Activity和View Activity是Android应用中负责与用户交互的组件,它只能通过setContentView(View)来显示指定组件. View组件是所有UI控件.容器空间的基 ...

  10. Devexpress VCL Build v2013 vol 13.2.3 发布

    继续修修补补,大过年的,就不吐槽了. What's New in 13.2.3 (VCL Product Line)   New Major Features in 13.2 What's New i ...