已经开始学javaEE了,也是工作中最常用到的技术。浏览器在于服务器进行数据交互的时候需要保持联系信息,即浏览器向服务器提交数据的时候要让服务器知道是在和哪个浏览器(客户)进行交流,因为需要保持浏览器和服务器之间的连接。而HTTP协议是一种无连接的协议,即浏览器向服务器请求一次连接就断了,当浏览器下一次请求服务器时服务器就“忘记”了上一次是谁给他发过信息。当然,技术上是可以一直保持浏览器和服务器之间的连接的,但实际上这会占用服务器大量的资源,让服务器“累死”(宕机),所以实际上也不能这样操作。
有一句话叫做解决问题的方法总比问题多嘛,哈哈,既然我们现在能如此享受互联网带来的好处,那前人们肯定早有了比较好的解决方法咯,那就是Cookie技术和Session技术。
Cookie是一种在客户端保持HTTP状态信息的技术。
Cookie是在浏览器访问WEB服务器端的某个资源时,由WEB服务器在HTTP应答头中附带传送给浏览器的一个数据,WEB服务器传送给各个客户端浏览器的数据可以是各不相同的。
一是WEB浏览器保存了某个Cookie,那么它以后每次访问服务器端时,都应在请求头传回给服务器端。
课堂练习:使用Cookie 保持登陆状态信息
当我在登录一个网站时,如新浪网,CSDN等,我们第一次登录时若勾选了保存登录信息的话,我们在一定的时间内就可以不用再重复登录了。我们每天都要访问很多的网站,我们基本上都有他们网站上的帐户,访问一次就要登录一次真是太麻烦了,其实网站就是用Cookie技术帮我们“再次”登录了网站。
FireFox 4下的我们登录过网站的Cookie
通过Firebug抓到的消息头中附带的Cookie
登录小测试
如果用户不勾选“两周内不再登录”,那么用户每次都需要重新登录,当然如果勾选了,用户的登录信息将把Cookie保存到用户的硬盘中两周时间,以后用户登录访问该网站时浏览器就会把Cookie信息放到消息头中一并发给服务器,服务器取到这个Cookie就知道是哪一个浏览器(用户)了。
当不勾选“两周内不再登录”时,始终显示第1次登录
勾选后的效果
当然这里我用了两个Cookie,一个记录登录用户,一个记录该用户的登录时间,实现记录用户的信息的关键就在于设置Cookie的保存时常,即它的setMaxAge方法,如果参数为0,那么用户关闭浏览器后Cookie信息就消失了,这称为会话Cookie,参数设为一个合理的时间数,就能保存到用户硬盘上了,称为持久化Cookie。
部分源码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String user = null;
String time = GetDate.getDateAsNow();//利用工具类生成当前时间
user = request.getParameter("username");
String pwd = request.getParameter("password");
if(user != null && !"".equals(user.trim())){
if(pwd != null && !"".equals(pwd.trim())){
if("kevin".equals(user) && "123".equals(pwd)){
Cookie[] cookies = request.getCookies();
if(cookies == null){//第一次登录
Cookie cookie = new Cookie(user,time);
Cookie viewCount = new Cookie("viewCount","1");
//勾选了“两周内不再登录” if("yes".equals(request.getParameter("remember"))){
//设置用户Cookie保存时间
cookie.setMaxAge(60*60*24*14);
//设置用户登录时间Cookie保存时间
viewCount.setMaxAge(60*60*24*14);
}else{
cookie.setMaxAge(0);
viewCount.setMaxAge(0);
}
response.addCookie(cookie);
response.addCookie(viewCount);
out.print("欢迎<font color=red fontsize=16>" + user + "</font>,这是您第<font color=red>1</font>次登录 ! <a href='login.html'>重新登录</a>");
}else{
String lastTime = null;
String count = null;
for(Cookie ck : cookies){
if("viewCount".equals(ck.getName())){
int temp =Integer.parseInt(ck.getValue());;
count = ""+(temp + 1);
ck.setValue(count);
ck.setMaxAge(60*60*24*14);
response.addCookie(ck);
}
if(user.equals(ck.getName())){
lastTime = ck.getValue();
ck.setValue(time);
ck.setMaxAge(60*60*24*14);
response.addCookie(ck);
}
}
out.print("欢迎<font color=red fontsize=16>" + user + "</font>,这是您第<font color=red>"+count+"</font>次访问本页面!上次登录时间:" + lastTime + "<a href='login.html'>重新登录</a>");
}
}else{
out.print("登录失败!" + "<a href='login.html'>重新登录</a>");
return;
}
}else{
out.print("密码错误!" + "<a href='login.html'>重新登录</a>");
return;
}
}else{
out.print("用户名错误!" + "<a href='login.html'>重新登录</a>");
return;
}
Cookie已经为我们解决了保持浏览器与服务器间连接状态的问题,但它也有自身的缺陷,即它存在安全问题,既然用户信息保存到了用户硬盘中,这些信息都是很敏感的,容易被不法分子利用破解等手段窃取到用户信息,而且我们的浏览器都有禁用Cookie的功能,如果Cookie被禁用了,我们程序中所设置的Cookie技术也就无用武之地了,因此,我们还需要另外的更加安全而有效的技术来对Cookie技术进行补充。Session该上场了:
Session是指在一段时间内,单个客户访问与Web服务器的一连串相关交互过程。在一个session中,客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源。
在java中,在ServletAPI中定义了javax.servlet.http.HttpSession接口,Servlet容器必须实现这一个接口。但要注意的是,个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
课堂小练习:利用Session模拟购物车功能
当客户选择了要购买的书籍和购买数量后,我们就把它存在Session中,我们还可以从Session中删除购买(准确的说是放在购物车中准备买)的书籍。
添加书籍效果
删除“java编程思想”效果
部分源码如下:
加添书籍
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String bookName = request.getParameter("bookitem");
String strBookNum = request.getParameter("quantity");
int bookNum = 0;
if("".equals(bookName)){
out.print("【提示】还没有选择要添加的书名哦<a href='books.html'>重新添加</a>");
return;
}
try {
bookNum = Integer.parseInt(strBookNum);
if(bookNum < 0){
out.print("【提示】输入的购买数量不正确!<a href='books.html'>返回</a>重新输入!");
return;
}
} catch (NumberFormatException e) {
out.print("【提示】输入的购买数量有误,<a href='books.html'>返回</a>重新输入!");
return;
}
HttpSession session = request.getSession();
Integer tempNum = (Integer)session.getAttribute(bookName);
if(tempNum == null){
session.setAttribute(bookName, bookNum);
out.print("【提示】<font color=red>"+bookName + "</font>共<font color=blue>"+bookNum+"</font>本添加成功!");
}else{
session.setAttribute(bookName, bookNum + tempNum);
out.print("【提示】<font color=red>"+bookName + "</font>又添加<font color=blue>"+bookNum+"</font>本成功!");
}
out.print("<table border=1><tr><th>书名</th><th>数量</th></tr>");
Enumeration<String> ens = session.getAttributeNames();
while(ens.hasMoreElements()){
String name = (String)ens.nextElement();
Integer count = (Integer)session.getAttribute(name);
out.print("<tr><td>"+name+"</td><td>"+count+"</td></tr>");
}
out.print("</table><br />");
out.print("<a href='books.html'>添加</a> ");
out.print("<a href='booksremove.html'>删除</a>");
}
删除书籍
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String bookName = request.getParameter("bookitem");
if("".equals(bookName)){
out.print("【提示】还没有选择要删除的书名哦 <a href='booksremove.html'>返回</a>");
return;
}
HttpSession session = request.getSession();
Integer bookNum = (Integer)session.getAttribute(bookName);
if(bookNum == null){
out.print("【提示】您没有购买过这种书,不能删除哦! <a href='booksremove.html'>返回</a>");
return;
}else{
session.removeAttribute(bookName);
out.print("【提示】<font color=red>"+bookName + "</font>共<font color=blue>"+bookNum+"</font>本删除成功!");
}
out.print("<table border=1><tr><th>书名</th><th>数量</th></tr>");
Enumeration<String> ens = session.getAttributeNames();
while(ens.hasMoreElements()){
String name = (String)ens.nextElement();
Integer count = (Integer)session.getAttribute(name);
out.print("<tr><td>"+name+"</td><td>"+count+"</td></tr>");
}
out.print("</table><br />");
out.print("<a href='books.html'>添加</a> ");
out.print("<a href='booksremove.html'>删除</a>");
}
老师说Cookie和Session是会被经常使用到的,老师还给我们讲解了URL重写技术来跟踪Session, 如果在浏览器不支持Cookie或者关闭了Cookie功能的情况下,WEB服务器还要能够与浏览器实现有状态的会话,就必须对所有可能被客户端访问的请求路径(包括超链接、form表单的action属性设置和重定向的URL)进行URL重写。