一、cookie
cookie的作用:cookie是小段文本信息,Web服务器将它发送给浏览器,然后在访问同一网站或域时,浏览器再将它返回给服务器。这样可以在浏览器端(客户端)保留一些适合保存在客户端的信息(比如用户的用户名、密码,用户访问站点时所使用的模板)。
cookie的好坏?
cookie可以很方便的将一些信息存放于客户端,但是存放于客户端有时候会出现一些安全和隐私方面的问题。简单的说,别人使用了你的电脑去访问一个网站,而由于上次你登录网站时选择了保存我的用户名和密码,这个时候访问的网站就会将一段cookie发送给你的机器。这样当其他人使用你的电脑的时候,网站并会不去关系现在是谁在使用你的电脑(网站的实现只关心它找到的你上次登录的cookie),这样别人登录的时候使用的你的帐号,所以可能会引发一些安全上的问题(尤其是公共场合的计算机)。
cookie虽然可以保存很多东西,但是由于cookie是存放于客户端的,而浏览器一般不会在客户端存放很多的cookie(磁盘也是要钱的!)一般浏览器都会限制每个cookie的大小(一般是4k),同一个站点的cookie的数量(一般是20),以及浏览器保存的所有cookie的数量(一般是300)。所以我们的应用最好不要使用太多的cookie。
cookie的使用很方便。服务器端需要向客户端发送cookies时只需要调用几个简单的函数即可以完成:
Cookie cookie = new Cookie(String name, String value)
构造一个cookie对象,cookie的名字为name,cookie的值为value
cookie.setMaxAge(int expiry) //void setMaxAge(int expiry)
设定一个cookie存在的时间(毕竟不会让它一直存在的),存在于客户端的参数为expiry秒。特殊的是当expiry值为-1的时候,代表关闭当前浏览器即失效。
httpServletResponse.addCookie(cookie) //HttpServletResponse void addCookie(Cookie cookie)
调用这个方法才会将cookie发送至客户端。这样即可以将以name为名字,value为值的cookie保存至客户端。当服务器端需要判断请求的客户是否有以前的cookie时只需要调用 httpServletRequest.getCookies() // HttpServletRequest Cookie[] getCookies()
该方法返回一个request中包含的cookie的数组,当没有cookie存在时,返回值为null。所以对cookies数组做迭代时,还是要先判断一下是否为null;
下面以一个例子(两只Servlet程序)来结束cookie本部的介绍,关于cookie的其他方法可以查看api:
LoginServlet:
LoginControlServlet:
LoginServlet和LoginControlServlet 分别 mapping至 /LoginServlet和/ LoginControlServlet。然后第一次访问http://127.0.0.1:8080/train/LoginServlet登录时不选择don’t ask me again,然后关掉窗口。第二次重新打开上面的url选择don’t ask me again 登录后关掉窗口。第三次访问时则不会再述要输入用户名和密码。PS:用户名、密码随便输入即可
二、session
由于http协议是一种无状态的协议,所以不通过其他手段的话,很难记录用户之前做过哪些事情。记录用户的状态,固然用cookie可以实现,但是cookie的大小和数量是存在限制的,并且还是存放于客户端的(客户端的cookie可以被人为的删除,而且在安全性上也是存在问题)。
session则和cookie的实现不一样,session是存放于服务器端的(基本可以理解成我们想放什么就可以放什么,我们想放多少就放多少)。session的实现机制,session既然是存在于server端的。那么我们当我们访问一个server的时候,server是如何找到我们对应的session的呢? 一般情况下,当server端为一个用户创建一个session之后会将一个cookie,cookie的name为JSESSIONID,对应的值为一个字符串传递给client端,client端再次访问server端的时候,server会根据cookie中的JSESSIONID的值,来找到存放于server端的session。(浏览器禁用cookie的时候,我们可以将jseesionid和其对应的值显示在用户访问的每一个url上,当然用户禁用cookie的情况还是很少的,现在绝大多数浏览器默认页是支持cookie的。故这里不多讨论其实现的方式)
在我们使用session的时候,当然不需要自己用cookie这些东西去实现,我们只需要几个简单的调用即可以完成了。
首先我们需要获取一个session,获取一个session可以调用HttpServletRequest对象的HttpSession getSession()和HttpSession getSession(boolean create)来获取。HttpSession getSession()调用该方法返回一个session。当已经存在client端在server端已经存在session时,即返回已经存在的session。当session不存在时及创建一个新的session。所以这个调用不会给我们返回nullHttpSession getSession(boolean create)当参数create的值为true时,该调用等价于HttpSession getSession()。当参数create的值为false时,则client端在server端已经存在session时,返回已经存在的session,但是如果client端在server端还没有session时,则返回null。(通过这种参数为false的调用,我们可以实现当用户直接访问我们的网站的时候,我们让他直接去登陆页面。。。登录以后才能查看里面的内容)取得session之后使用起来也很简单,基本使用以下几个方法即可
void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)
void setAttribute(String name, Object value)
向session中添加一个名字为name,值为value的键值对(注意了哦,这里的value的类型是Object而不再是String)。当name已经在session中存在时,则替换name对应的值为value。
Object getAttribute(String name)
这个好像没有什么好说的,返回name对应的value。当然name不存在时候会返回null
void removeAttribute(String name)
删除name对应的键值对。
Session其他常用的几个方法:
void setMaxInactiveInterval(int interval)
设置一个session当用户在interval秒内没有活动时即失效 (利用这个我们可以很方便的实现,当用户多长时间没有和我们的网站有任何交互时候让其需要重新登录才能继续浏览),如果不调用这个方法的话会根据容器的默认设置(一般为30分钟)
void invalidate()
将此session对象立即失效(会释放session占用的一些资源)(利用这个方法可以解决我们访问一个网站时,突然需要离开但不想关闭浏览器窗口。如果我离开后不希望别人能继续使用我已经登录的帐号做其他操作则可以提供一个注销的功能给用户,当用户点击注销的时候即调用此方法)。
下面还是一个例子,此例子包含的.java文件可能比较多:
先看下我们用于存放于session中的对象:User类
SessionLogin:
SessionLoginControl:
SessionAttributeShow:
将SessionLogin,SessionLoginControl,SessionAttributeShow分别mapping至/SessionLogin,/SessionLoginControl,/SessionAttributeShow
访问http://127.0.0.1:8080/train/SessionLogin进行测试,输入用户名密码可以在http://127.0.0.1:8080/train/SessionAttributeShow中看到输入内容,但是假如直接访问http://127.0.0.1:8080/train/SessionAttributeShow则会退到http://127.0.0.1:8080/train/SessionLogin要求你进行登录。
session的其他注意点,session中的对象是一直存在的,除非你手动的remove或者session失效,所以我们做应用的时候需要考虑什么东西是我们真的需要存放于session中的,session也需要占用内存和磁盘上的空间,session中存放大量对象将对系统性能产生很大的影响,对内存和资源的消耗也会增加。
由于容器一般会在内存不足时将不常用的session由内存转移(个人习惯叫钝化,反之为锐化)到磁盘。所以存放于session中的对象请实现java.io.Serializable接口,要不可能在特定的情况下因session中对象无法序列化而产生java.io.NotSerializableException
cookie的作用:cookie是小段文本信息,Web服务器将它发送给浏览器,然后在访问同一网站或域时,浏览器再将它返回给服务器。这样可以在浏览器端(客户端)保留一些适合保存在客户端的信息(比如用户的用户名、密码,用户访问站点时所使用的模板)。
cookie的好坏?
cookie可以很方便的将一些信息存放于客户端,但是存放于客户端有时候会出现一些安全和隐私方面的问题。简单的说,别人使用了你的电脑去访问一个网站,而由于上次你登录网站时选择了保存我的用户名和密码,这个时候访问的网站就会将一段cookie发送给你的机器。这样当其他人使用你的电脑的时候,网站并会不去关系现在是谁在使用你的电脑(网站的实现只关心它找到的你上次登录的cookie),这样别人登录的时候使用的你的帐号,所以可能会引发一些安全上的问题(尤其是公共场合的计算机)。
cookie虽然可以保存很多东西,但是由于cookie是存放于客户端的,而浏览器一般不会在客户端存放很多的cookie(磁盘也是要钱的!)一般浏览器都会限制每个cookie的大小(一般是4k),同一个站点的cookie的数量(一般是20),以及浏览器保存的所有cookie的数量(一般是300)。所以我们的应用最好不要使用太多的cookie。
cookie的使用很方便。服务器端需要向客户端发送cookies时只需要调用几个简单的函数即可以完成:
Cookie cookie = new Cookie(String name, String value)
构造一个cookie对象,cookie的名字为name,cookie的值为value
cookie.setMaxAge(int expiry) //void setMaxAge(int expiry)
设定一个cookie存在的时间(毕竟不会让它一直存在的),存在于客户端的参数为expiry秒。特殊的是当expiry值为-1的时候,代表关闭当前浏览器即失效。
httpServletResponse.addCookie(cookie) //HttpServletResponse void addCookie(Cookie cookie)
调用这个方法才会将cookie发送至客户端。这样即可以将以name为名字,value为值的cookie保存至客户端。当服务器端需要判断请求的客户是否有以前的cookie时只需要调用 httpServletRequest.getCookies() // HttpServletRequest Cookie[] getCookies()
该方法返回一个request中包含的cookie的数组,当没有cookie存在时,返回值为null。所以对cookies数组做迭代时,还是要先判断一下是否为null;
下面以一个例子(两只Servlet程序)来结束cookie本部的介绍,关于cookie的其他方法可以查看api:
LoginServlet:
- public class LoginServlet extends HttpServlet {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- Cookie[] cookies = request.getCookies();
- Cookie cookie = null;
- String userName = null;
- String password = null;
- boolean check = false;
- if(cookies != null)
- for(int i = 0; i < cookies.length; ++i) {
- cookie = cookies[i];
- if(cookie.getName().equals("UserName"))
- userName = cookie.getValue();
- if(cookie.getName().equals("Password"))
- password = cookie.getValue();
- if(cookie.getName().equals("Check"))
- check = cookie.getValue().equals("Yes") ? true:false;
- }
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- String docType ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">";
- String title = "Login";
- out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title
- + "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> "
- + "<CENTER> " + "<H1>" + title + "</H1> "
- + "<FORM ACTION=\"LoginControlServlet\" METHOD=\"POST\">"
- +(userName==null? "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\"><BR>" : "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\" VALUE=\"\"+ userName + \"\"><BR>")
- +(password==null? "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\"><BR>" : "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\" VALUE=\"\"+ password + \"\"><BR>")
- +(check ? "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\" CHECKED=\"true\">": "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\">")
- + "Don''t Ask Me Again"
- + "<CENTER><INPUT TYPE=\"SUBMIT\" VALUE=\"Login\"></CENTER>"
- + "</FORM>"
- +"</CENTER></BODY></HTML>");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
LoginControlServlet:
- public class LoginControlServlet extends HttpServlet {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- if(request.getParameter("Check")!= null && request.getParameter("Check").equals("on")) {
- Cookie cookie1 = new Cookie("Check","Yes");
- cookie1.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie1);
- Cookie cookie2 = new Cookie("UserName",request.getParameter("UserName"));
- cookie2.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie2);
- Cookie cookie3 = new Cookie("Password",request.getParameter("Password"));
- cookie3.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie3);
- }
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> ";
- String title = "Login";
- out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title
- + "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> "
- + "<CENTER> " + "<H1>" + title + "</H1> "
- +"UserName:" + request.getParameter("UserName") + "<BR>"
- +"Password:" + request.getParameter("Password") + "<BR>"
- +"</CENTER></BODY></HTML>");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
LoginServlet和LoginControlServlet 分别 mapping至 /LoginServlet和/ LoginControlServlet。然后第一次访问http://127.0.0.1:8080/train/LoginServlet登录时不选择don’t ask me again,然后关掉窗口。第二次重新打开上面的url选择don’t ask me again 登录后关掉窗口。第三次访问时则不会再述要输入用户名和密码。PS:用户名、密码随便输入即可
二、session
由于http协议是一种无状态的协议,所以不通过其他手段的话,很难记录用户之前做过哪些事情。记录用户的状态,固然用cookie可以实现,但是cookie的大小和数量是存在限制的,并且还是存放于客户端的(客户端的cookie可以被人为的删除,而且在安全性上也是存在问题)。
session则和cookie的实现不一样,session是存放于服务器端的(基本可以理解成我们想放什么就可以放什么,我们想放多少就放多少)。session的实现机制,session既然是存在于server端的。那么我们当我们访问一个server的时候,server是如何找到我们对应的session的呢? 一般情况下,当server端为一个用户创建一个session之后会将一个cookie,cookie的name为JSESSIONID,对应的值为一个字符串传递给client端,client端再次访问server端的时候,server会根据cookie中的JSESSIONID的值,来找到存放于server端的session。(浏览器禁用cookie的时候,我们可以将jseesionid和其对应的值显示在用户访问的每一个url上,当然用户禁用cookie的情况还是很少的,现在绝大多数浏览器默认页是支持cookie的。故这里不多讨论其实现的方式)
在我们使用session的时候,当然不需要自己用cookie这些东西去实现,我们只需要几个简单的调用即可以完成了。
首先我们需要获取一个session,获取一个session可以调用HttpServletRequest对象的HttpSession getSession()和HttpSession getSession(boolean create)来获取。HttpSession getSession()调用该方法返回一个session。当已经存在client端在server端已经存在session时,即返回已经存在的session。当session不存在时及创建一个新的session。所以这个调用不会给我们返回nullHttpSession getSession(boolean create)当参数create的值为true时,该调用等价于HttpSession getSession()。当参数create的值为false时,则client端在server端已经存在session时,返回已经存在的session,但是如果client端在server端还没有session时,则返回null。(通过这种参数为false的调用,我们可以实现当用户直接访问我们的网站的时候,我们让他直接去登陆页面。。。登录以后才能查看里面的内容)取得session之后使用起来也很简单,基本使用以下几个方法即可
void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)
void setAttribute(String name, Object value)
向session中添加一个名字为name,值为value的键值对(注意了哦,这里的value的类型是Object而不再是String)。当name已经在session中存在时,则替换name对应的值为value。
Object getAttribute(String name)
这个好像没有什么好说的,返回name对应的value。当然name不存在时候会返回null
void removeAttribute(String name)
删除name对应的键值对。
Session其他常用的几个方法:
void setMaxInactiveInterval(int interval)
设置一个session当用户在interval秒内没有活动时即失效 (利用这个我们可以很方便的实现,当用户多长时间没有和我们的网站有任何交互时候让其需要重新登录才能继续浏览),如果不调用这个方法的话会根据容器的默认设置(一般为30分钟)
void invalidate()
将此session对象立即失效(会释放session占用的一些资源)(利用这个方法可以解决我们访问一个网站时,突然需要离开但不想关闭浏览器窗口。如果我离开后不希望别人能继续使用我已经登录的帐号做其他操作则可以提供一个注销的功能给用户,当用户点击注销的时候即调用此方法)。
下面还是一个例子,此例子包含的.java文件可能比较多:
先看下我们用于存放于session中的对象:User类
- public class User implements Serializable {
- public User() { }
- public User(String name, String password) {
- this.name = name;
- this.password = password;
- }
- private String name = "";
- private String password = "";
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- }
SessionLogin:
- public class SessionLogin extends HttpServlet {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- Cookie[] cookies = request.getCookies();
- Cookie cookie = null;
- String userName = null;
- String password = null;
- boolean check = false;
- if(cookies != null)
- for(int i = 0; i < cookies.length; ++i) {
- cookie = cookies[i];
- if(cookie.getName().equals("UserName"))
- userName = cookie.getValue();
- if(cookie.getName().equals("Password"))
- password = cookie.getValue();
- if(cookie.getName().equals("Check"))
- check = cookie.getValue().equals("Yes") ? true:false;
- }
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> ";
- String title = "Login";
- out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title
- + "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> "
- + "<CENTER> " + "<H1>" + title + "</H1> "
- + "<FORM ACTION=\"SessionLoginControl\" METHOD=\"POST\">"
- +(userName==null? "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\"><BR>" : "UserName:<INPUT TYPE=\"TEXT\" NAME=\"UserName\" VALUE=\"\"+ userName + \"\"><BR>")
- +(password==null? "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\"><BR>" : "Password:<INPUT TYPE=\"PASSWORD\" NAME=\"Password\" VALUE=\"\"+ password + \"\"><BR>")
- +(check ? "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\" CHECKED=\"true\">": "<INPUT TYPE=\"CHECKBOX\" NAME=\"Check\">")
- + "Don''t Ask Me Again"
- + "<CENTER><INPUT TYPE=\"SUBMIT\" VALUE=\"Login\"></CENTER>"
- + "</FORM>"
- +"</CENTER></BODY></HTML>");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
SessionLoginControl:
- public class SessionLoginControl extends HttpServlet {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- if(request.getParameter("Check")!= null && request.getParameter("Check").equals("on")) {
- Cookie cookie1 = new Cookie("Check","Yes");
- cookie1.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie1);
- Cookie cookie2 = new Cookie("UserName",request.getParameter("UserName"));
- cookie2.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie2);
- Cookie cookie3 = new Cookie("Password",request.getParameter("Password"));
- cookie3.setMaxAge(3600 * 24 *30);
- response.addCookie(cookie3);
- }
- HttpSession session = request.getSession();
- session.setAttribute("user", new User(request.getParameter("UserName"),request.getParameter("Password")));
- response.sendRedirect("SessionAttributeShow");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
SessionAttributeShow:
- public class SessionAttributeShow extends HttpServlet {
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- HttpSession session = request.getSession(false);
- if(session == null) {
- response.sendRedirect("SessionLogin");
- return;
- }
- User user = (User)session.getAttribute("user");
- if(user == null) {
- response.sendRedirect("SessionLogin");
- return;
- }
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"> ";
- String title = "Login";
- out.println(docType + "<HTML> " + "<HEAD><TITLE>" + title
- + "</TITLE></HEAD> " + "<BODY BGCOLOR=\"#FDF5E6\"> "
- + "<CENTER> " + "<H1>" + title + "</H1> "
- +"UserName:" + user.getName()+ "<BR>"
- +"Password:" + user.getPassword() + "<BR>"
- +"</CENTER></BODY></HTML>");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request, response);
- }
- }
将SessionLogin,SessionLoginControl,SessionAttributeShow分别mapping至/SessionLogin,/SessionLoginControl,/SessionAttributeShow
访问http://127.0.0.1:8080/train/SessionLogin进行测试,输入用户名密码可以在http://127.0.0.1:8080/train/SessionAttributeShow中看到输入内容,但是假如直接访问http://127.0.0.1:8080/train/SessionAttributeShow则会退到http://127.0.0.1:8080/train/SessionLogin要求你进行登录。
session的其他注意点,session中的对象是一直存在的,除非你手动的remove或者session失效,所以我们做应用的时候需要考虑什么东西是我们真的需要存放于session中的,session也需要占用内存和磁盘上的空间,session中存放大量对象将对系统性能产生很大的影响,对内存和资源的消耗也会增加。
由于容器一般会在内存不足时将不常用的session由内存转移(个人习惯叫钝化,反之为锐化)到磁盘。所以存放于session中的对象请实现java.io.Serializable接口,要不可能在特定的情况下因session中对象无法序列化而产生java.io.NotSerializableException