HTTP协议是无状态的,服务端是无法获取用户的身份信息,但是在实际的应用场景中我们需要服务器可以分辨出用户的身份信息于是有人提出用户在第一次访问服务器时可以把用户的一些身份信息返回给浏览器,浏览器下次访问服务器时要在请求中携带服务器返回的用户身份的信息,这样服务器就可以判断出用户的身份了。这个用户的身份信息就是cookie。下面给出官方的定义解释:Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
一、cookie的原理
Cookie的本质是定义了一些HTTP请求头和HTTP响应头,通过这些HTTP头信息使服务器可以与客户进行状态交互。我这里用一张图来表示cookie创建的过程:
(图片来源:https://upload-images.jianshu.io/upload_images/13949989-dcf024be2733e725.png?imageMogr2/auto-orient/strip|imageView2/2/w/400/format/webp)。在java web开发中我们使用HttpServletResponse对象和HttpServletRequest对象来创建和获取cookie。代码如下:
public class TestCookieServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("content-type","text/html;charset=UTF-8"); response.setCharacterEncoding("utf-8"); SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); PrintWriter out = response.getWriter(); Cookie[] cookies = request.getCookies(); if(cookies!=null){ String cookieValue = null; for (Cookie cookie : cookies) { if("last_time".equalsIgnoreCase(cookie.getName())){ cookieValue = cookie.getValue(); break; } } out.print("您上次访问的时间是:"+cookieValue); }else{ out.print("欢迎访问本站!"); } Cookie cookie = new Cookie("last_time",smf.format(new Date())); cookie.setMaxAge(-1); response.addCookie(cookie); out.close(); } }
HttpServletResponse对象通过addCookie(Cookie cookie)方法把cookie信息添加到响应头中,HttpServletRequest对象通过getCookies()方法获取cookie数组。Cookie对象通过构造函数初始化name-value的键值对,通过getValue和getName方法获取cookie的value和name值。这里需要注意的cookie对象的getMaxAge(int i)方法,这个方法是用是设置cookie的过期时间的,如果设置为-1表示该Cookie只是一个临时Cookie,不会被持久化,仅在本浏览器窗口或者本窗口打开的子窗口中有效,关闭浏览器后该Cookie立即失效;如果设置为0表示立即删除该cookie。HttpServletResponse对象并没有提供setCookie这样的方法,如果需要修改cookie的值只需要覆盖即可。上面的代码表示记录用户的上次访问的时间,如果用户是第一次访问则显示欢迎访问本站。
用户第一次访问时会在响应头中添加cookie的信息,当用户第二次访问时:请求头中就会携带cookie的信息了。
最后在使用cookie时一定要注意跨域读写的问题,因为cookie满足同源策略,如果你要跨域读写cookie就需要使用nginx做反向代理了。