第01章:Cookie入门
-
什么是会话
打开浏览器,输入服务器的URL地址,在浏览器中多次访问服务器的资源,
最后关闭浏览器的整个过程,我们叫会话 -
解决保存客户端信息有二种可行方案,分别是:
- 客户端技术Cookie,存在客户端
- 服务器技术HttpSession
-
什么是Cookie
Cookie是用来保存服务器向每个客户端响应的数据,它存在于客户端 -
Cookie有什么作用
Cookie能够让服务器知道该客户端之前有哪些私有数据 -
Cookie原理图
响应头:set-cookie: name=HTML
请求头:cookie :name=HTML
第02章:Cookie常用API
-
Cookie常用的API如下:
new Cookie(String,String) Cookie.setValue()和getValue() Cookie.setMaxAge() Cookie.getName() Cookie.setPath()可省,默认本web应用发送的,即/day13 Request.getCookies()
演示Cookie常用的API:Demo01.java
public class Demo01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie c : cookies) {
pw.write(c.getName() + "----" + c.getValue());
}
} else {
Cookie cookie = new Cookie("NAME", "JACK");
cookie.setMaxAge(1 * 24 * 60 * 60);
cookie.setPath("/day13");
response.addCookie(cookie);
pw.write("存入Cookie了");
}
pw.flush();
pw.close();
}
}
记录用户上一次访问的时间:Demo02.java
public class Demo02 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
//获取客户端所有Cookie形成的数组
Cookie[] cookies = request.getCookies();
//如果客户端有Cookie的话
if (cookies != null && cookies.length > 0) {
Cookie timeCookie = null;
//查询
for (Cookie cookie : cookies) {
//查询名为time的Cookie
if ("time".equals(cookie.getName())) {
timeCookie = cookie;
break;
}
}
//如果找到了名为time的Cookie
if (timeCookie != null) {
//获取该Cookie的值
String strTime = timeCookie.getValue();
//创建Cookie
Cookie cookie = new Cookie("time", new Date().toLocaleString());
//设置Cookie来源于本网站
cookie.setPath(request.getContextPath());
//设置Cookie在客户端的有效时间为1天
cookie.setMaxAge(1 * 24 * 60 * 60);
//将Cookie发送到客户端
response.addCookie(cookie);
//在浏览器显示
pw.write("欢迎你再次访问我们网站,你上次访问我们网站的时间为:" + strTime);
}
} else {
//创建Cookie
Cookie cookie = new Cookie("time", new Date().toLocaleString());
//设置Cookie来源于本网站
cookie.setPath(request.getContextPath());
//设置Cookie在客户端的有效时间为1天
cookie.setMaxAge(1 * 24 * 60 * 60);
//将Cookie发送到客户端
response.addCookie(cookie);
//在浏览器显示
pw.write("欢迎你首次访问我们网站");
}
pw.flush();
pw.close();
}
}
第03章:Cookie特点
-
一个Cookie只能标识一种信息,且Cookie的值只能是String类型
-
一个Web网站可以给一个Web浏览器发送多个Cookie,
一个Web浏览器也可以存储多个Web网站的Cookie -
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB
-
如果创建了一个Cookie,并将他发送到浏览器,默认情况下它是一个会话级别的Cookie(即存储
在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该Cookie存储在磁盘上,则需要使用setMaxAge()),并给出一个以秒为单位的时间。将最大时效设为0,则该Cookie无效,无效的Cookie,服务器是读取不到的。 -
浏览器可以禁用Cookie,但不建议这样做
-
Cookie创建于服务器,保存于客户端(例如:IE的缓存目录,每个浏览器缓存目录都不一样)
-
服务器只能都取本Web网站的Cookie,且只能读取时间有效的Cookie,不能都取无效时间的Cookie
-
服务器只能读取相同客户端的Cookie,即如果客户端用IE访问的话,那么服务端只能读取IE浏览器中的所有Cookie,此时是不能读取Google浏览器中的Cookie的,反之相同
第04章:用Cookie来记录用户浏览图书的轨迹
Demo03.java和Demo04.java,先访问Demo03.java
public class Demo03 extends HttpServlet {
private Map<String, Book> map;
@Override
public void init() throws ServletException {
map = DB.getMap();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write("<table border='2' align='center' width='50%'>");
pw.write("<tr>");
pw.write("<th>编号</th>");
pw.write("<th>书名</th>");
pw.write("<th>操作</th>");
pw.write("</tr>");
pw.write("<tbody>");
for (Map.Entry<String, Book> entry : map.entrySet()) {
pw.write("<tr>");
pw.write("<td>" + entry.getKey() + "</td>");
pw.write("<td>" + entry.getValue().getName() + "</td>");
String url = request.getContextPath() + "/Demo04?id=" + entry.getKey();
pw.write("<td><a target='_blank' href='" + url + "' style='text-decoration:none'>查看</a></td>");
pw.write("</tr>");
}
pw.write("</tbody>");
pw.write("</table>");
pw.write("<hr/>");
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
Cookie bookCookie = null;
for (Cookie cookie : cookies) {
if ("bookHistroy".equals(cookie.getName())) {
bookCookie = cookie;
break;
}
}
if (bookCookie != null) {
String bookHistroy = bookCookie.getValue();
String[] ids = bookHistroy.split("_");
pw.write("<ol>");
for (String id : ids) {
Book book = map.get(id);
pw.write("<li>" + book.getName() + "</li>");
}
pw.write("</ol>");
}
}
pw.flush();
pw.close();
}
}
class Book {
private String id;
private String name;
public Book(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class DB {
private static Map<String, Book> map = new LinkedHashMap<String, Book>();
static {
map.put("1", new Book("1", "HTML"));
map.put("2", new Book("2", "CSS"));
map.put("3", new Book("3", "JavaScript"));
map.put("4", new Book("4", "XML"));
map.put("5", new Book("5", "Tomcat"));
map.put("6", new Book("6", "Servlet"));
}
public static Map<String, Book> getMap() {
return map;
}
}
Demo04.java
public class Demo04 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
Cookie bookCookie = null;
for (Cookie cookie : cookies) {
if ("bookHistroy".equals(cookie.getName())) {
bookCookie = cookie;
break;
}
}
if (bookCookie != null) {
String bookHistroy = bookCookie.getValue();
/*
* bookHistroy id 结果
* 1 4 4_1
* 1_4 4 4_1_4
* 1_3 4 4_1_3
* 1_2_4 4 4_1_2
* 1_2_3 4 4_1_2
*/
Cookie cookie = new Cookie("bookHistroy", makeId(id, bookHistroy));
cookie.setPath(request.getContextPath());
cookie.setMaxAge(1 * 24 * 60 * 60);
response.addCookie(cookie);
}
} else {
Cookie cookie = new Cookie("bookHistroy", id);
cookie.setPath(request.getContextPath());
cookie.setMaxAge(1 * 24 * 60 * 60);
response.addCookie(cookie);
}
}
private String makeId(String id, String bookHistroy) {
//"1_2_3"
String[] ids = bookHistroy.split("_");
//[1][2][3]
List<String> stringList = Arrays.asList(ids);
//[1][2][3]
LinkedList<String> stringLinkedList = new LinkedList(stringList);
//[1]--[2]--[3]
if (stringLinkedList.size() < 3) {
stringLinkedList.addFirst(id);
} else if (stringLinkedList.contains(id)) {
stringLinkedList.remove(id);
stringLinkedList.addFirst(id);
} else {
stringLinkedList.removeLast();
stringLinkedList.addFirst(id);
}
StringBuffer sb = new StringBuffer();
//[4]--[1]--[2]
for (String strId : stringLinkedList) {
sb.append(strId + "_");
}
//4_1_2_
sb.deleteCharAt(sb.length() - 1);
//4_1_2
return sb.toString();
}
}
第05章:HttpSession入门
-
什么是会话
打开浏览器,输入服务器的URL地址,在浏览器中多次访问服务器的资源,
最后关闭浏览器的整个过程,我们叫会话 -
解决保存客户端信息有二种可行方案,分别是:
- 客户端技术Cookie
- 服务器技术HttpSession,保存在服务器中
-
什么是HttpSession
HttpSession是用来保存服务器向每个客户端响应的私有数据,它存在于服务器端
Cookie是用来保存服务器向每个客户端响应的私有数据,它存在于客户端 -
HttpSession有什么作用
HttpSession能够让服务器知道该客户端之前购买了什么商品 -
HttpSession与Cookie的关系
本质上HttpSession是基于Cookie技术的,只是该Cookie不会存于浏览器缓存中 -
HttpSession原理图
响应头:set-cookie: jsessionid=123
请求头:cookie :jsessionid=123
服务器会进行jsessionid比较,如果相同的话,就能找到客户端在服务器对应的HttpSession了 -
HttpSession适用场景
购物车,表单验证码,等等
第06章:HttpSession域对象
-
为什么需要有HttpSession域对象呢
Request域对象生命周期太短,只在一次请求中有效;而ServletContext域对象生命周期
太长,只要Web服务器不停止,它都存在。有时我们却希望在同一个浏览器中
的多次会话间能共享一个域对象,例如:网上购物,每个用户打开自己的浏览器,有着自己
独立的购物车,装着不同的商品,但都属于同一个Web应用。为了实现上述需要,一个新的域对象诞生了,它就是HttpSession域对象。 -
创建HttpSession域对象
访问Servlet且调用Request.getSession()
注意:打开浏览器,并没有创建HttpSession域对象 -
HttpSession作为域对象常用的API如下:
setAttribute(String,Object) getAttribute(String) removeAttribute(String)
-
销毁HttpSession域对象
- Web服务器停止
- 在不停止Web服务器的前提下,重新部署Web应用
- HttpSession域对象默认的30分钟有效期结束,当然也可以设置有效期时间,分钟为单位
web.xml
<session-config> <session-timeout>1</session-timeout> </session-config>
Demo04.java
public class Demo04 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
HttpSession session = request.getSession();
pw.write(session.getId()+"#"+new Date().toLocaleString());
}
}
- 调用invalidate()方法强行销毁HttpSession域对象安全退出,就用invalidate()
Demo04.java
public class Demo04 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
HttpSession session1 = request.getSession();
pw.write(session1.getId()+"#"+new Date().toLocaleString()+"<br/>");
session1.invalidate();
HttpSession session2 = request.getSession();
pw.write(session2.getId()+"#"+new Date().toLocaleString()+"<br/>");
}
}
第07章:URL重写
-
什么是URL重写
将数据跟在URL后面,传递给客户端,不存入客户端,下次发送请求时,数据依然跟在URL后面带到服务器,这些形式叫URL重写 -
为什么要URL重写
如果客户端禁用Cookie了,服务器的数据无法以Cookie形式保存在客户端,这样下次访问服务器时,服务器就无法得知上次客户端的私有数据了。为了解决这个问题,只能将数据跟在URL后面,每次请求和响应都带着这些客户端私有数据,这样服务器就可以知道上次客户端的私有数据了,URL后面跟着HttpSession的ID号。 -
在哪里用URL重写
当客户端禁用Cookie后,服务器也想得知客户端的私有数据,这时可以使用URL重写 -
如何用URL重写
重定向:
url =response.encodeRedirectURL(url);
response.sendRedirect(url);
非重定向:即转发,超链接
url =response.encodeURL(url); -
细节:
上述URL重写API,会根据客户端请求中是否有cookie请求头,来加jsessionid这个字符串
如果浏览器禁用Cookie,请求中则无cookie请求头,就加jsessionid在URL后
如果浏览器可用Cookie, 请求中则有cookie请求头, 就不加jsessionid在URL后,
这套API会智能判断是否进行URL重写
第08章:用HttpSession来实现简单购物车V1
Demo06.java和Demo07.java和Demo08.java,先访问Demo06.java
Demo06.java
public class Demo06 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write("<OL>");
String url1 = "/day13/Demo07?id=1&name=HTML";
url1 = response.encodeURL(url1);
pw.write("<LI><a href='"+url1+"' style='text-decoration:none'>HTML</a></LI>");
String url2 = "/day13/Demo07?id=2&name=CSS";
url2 = response.encodeURL(url2);
pw.write("<LI><a href='"+url2+"' style='text-decoration:none'>CSS</a></LI>");
String url3 = "/day13/Demo07?id=3&name=JS";
url3 = response.encodeURL(url3);
pw.write("<LI><a href='"+url3+"' style='text-decoration:none'>JS</a></LI>");
String url4 = "/day13/Demo07?id=4&name=XML";
url4 = response.encodeURL(url4);
pw.write("<LI><a href='"+url4+"' style='text-decoration:none'>XML</a></LI>");
String url5 = "/day13/Demo07?id=5&name=AJAX";
url5 = response.encodeURL(url5);
pw.write("<LI><a href='"+url5+"' style='text-decoration:none'>AJAX</a></LI>");
pw.write("</OL>");
pw.flush();
pw.close();
}
}
Demo07.java
public class Demo07 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String id = request.getParameter("id");
String name = request.getParameter("name");
HttpSession session = request.getSession();
List<String> shopcar = (List<String>) session.getAttribute("SHOPCAR");
if(shopcar==null){
shopcar = new ArrayList<String>();
session.setAttribute("SHOPCAR",shopcar);
}else{
}
shopcar.add(name);
//重定向到Demo08
String url = "/day13/Demo08";
url = response.encodeRedirectURL(url);
response.sendRedirect(url);
}
}
Demo08.java
public class Demo08 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
HttpSession session = request.getSession();
List<String> shopcar = (List<String>) session.getAttribute("SHOPCAR");
if(shopcar!=null && shopcar.size()>0){
pw.write("我的购物车商品如下:<br/>");
pw.write("<OL>");
for(String str : shopcar){
pw.write("<LI>"+str+"</LI>");
}
pw.write("</OL><br/><br/>");
} else {
pw.write("查无商品<br/><br/>");
}
String url = "/day13/Demo06";
url = response.encodeURL(url);
pw.write("<a href='"+url+"' style='text-decoration:none'>返回</a>");
pw.flush();
pw.close();
}
}