Home  >  Article  >  Java  >  A brief introduction to cookies in servlets in Java (pictures and text)

A brief introduction to cookies in servlets in Java (pictures and text)

黄舟
黄舟Original
2017-07-26 15:06:061642browse

Since the birth of Cookie technology, it has become a focus of debate among Internet users and Web developers. The following article mainly introduces you to the relevant information about the introduction of cookies in servlets. The introduction in the article is very detailed. Friends in need can refer to it. Let’s take a look together.

First, let’s understand what a “session” is. Session is a term in web technology. It can be simply understood as: the user opens a browser, clicks on multiple hyperlinks, accesses multiple web resources on the server, and then closes the browser. This process is called a session.

If you open a browser to visit a page, and then open a browser to visit the same page, then there are two sessions; and after opening a browser to visit a page, through the page If a hyperlink is opened from a new browser, it still only counts as one session.

Each user will inevitably generate some data during the conversation between the browser and the server, and the program must find a way to save this data for each user. For example, if a user clicks on a hyperlink to purchase a product through a product Servlet, the program should find a way to save the product so that when the user clicks on the payment hyperlink, he can see the product from the payment Servlet and pay for it.

It is impossible to save data using the Request object, because the Servlets for clicking on goods and paying are sending two different Request request objects, and using the ServletContext object will cause thread safety issues for multiple users. Use The forwarding function is theoretically possible, but the user experience will be greatly reduced. Every time you click on an item, you will be asked to pay. Therefore, based on the above requirements, there are two technologies to save the data generated during the session: one is Cookie, and the other is Session. Session technology will be introduced in subsequent chapters.

This article mainly talks about Cookie technology in Servlet. Cookie technology is a client-side technology, and the program writes each user's data to the user's respective browser in the form of a cookie. When the user uses the browser to access the server, they will bring their own data with them, so that the web server processes the user's own data.

The following figure is a simple process of setting a cookie with the last access time during a session:

 

Creating a Cookie object is just like creating a Java object normally. Just as simple:

 

When using the constructor, just pass in the key-value pair of the cookie name and value. We need to get the cookie sent from the browser on the server side. Data can use the request.getCookies method of the request object to obtain a Cookie array, and when we want to output Cookies to the browser, we can use the response.addCookie(Cookie) method of the response object.

At the same time, the Cookie object also has the following methods:

 

The getName method is used to obtain the name of a Cookie object.

The setValue method and getValue method are used to set and get the value of a Cookie object respectively.

 setMaxAge(int expires) method is to set the validity period of the Cookie. Without this code, the validity period of the Cookie is one session time (that is, closing the browser, the Cookie will no longer exist). When the validity period of the cookie is set, the cookie will be saved in the hard disk file specified by the browser. At the same time, during this period, the cookie will be carried with it every time you visit the server. If this method parameter is set to "0", the server will instruct the browser to delete the cookie.

The setPath method is a valid path to set Cookie. Indicates that cookies will only be carried when visiting certain specific URLs. Suppose a web application is [myservlet]. If we set the parameter in the setPath method to "/myservlet", then accessing all resources under the web application will cause the browser to send cookies; and if we set the parameter in the setPath method If the parameter is set to "/myservlet/pages", then only accessing the resources under [pages] in the web application will bring the cookie, and accessing other resources in the web application will not bring the cookie to the server. If we do not set the setPath method, the effective path of the cookie defaults to the directory where the current program that created the cookie object is located. Note that the cookie path is used by the browser (see "Servlet Learning Web Path Issues" for details)

The setDomain method is to set the effective domain name of the Cookie, such as: .sina.com(note there is a dot at the front). Indicates that the cookie will be carried when the browser accesses the domain name. But now browsers basically completely block this function that may be considered unsafe, so it has almost been abandoned.

  举例:我们访问某个Servlet,而在访问这个Servlet时会将当前访问时间作为Cookie中的值返回给客户端,同时下次再次访问该Servlet时,会显示上一次客户端来访问的时间:


public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=utf-8");
  
  PrintWriter writer = response.getWriter();
  writer.write("您上次访问的时间是:");
  //获取用户上一次的访问时间并显示
  Cookie[] cookies = request.getCookies();   //从请求中获取客户端发来的Cookie
  for(int i=0;cookies!=null && i<cookies.length;i++) {
   if(cookies[i].getName().equals("lastAccessTime")) { //获取最后访问时间的Cookie
    Long mTime = Long.parseLong(cookies[i].getValue());  
    String lastAccessTime = new Date(mTime).toLocaleString();
    writer.write(lastAccessTime);
   }
  }
  //将本次登录时间重新装载进Cookie中并返回给客户端
  Cookie timeCookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
  timeCookie.setMaxAge(1*24*60*60); //将Cookie有效期置为一天
  response.addCookie(timeCookie);  //将Cookie传回客户端
 }

第一次访问是没有Cookie的,所以看不到访问时间:

  

但是我们通过HttpWatch观察Response响应包中的内容已经有了“Set-Cookie”响应头:

  

刷新后的第二次访问就可以看到了:

  

同时观察HttpWatch中Request请求包的“Cookie”请求头可以发现:

  

  现在我们再来通过一个案例来学习Cookie,这是一个很常见的案例,比如我们在访问购物网站的时候经常会发现当浏览了这个网站内的某个商品的时候,下次继续来访问这个网站,会有一个上次浏览物品的显示。

  如果我们不是用登录后将记录保存在服务器端,而是使用Cookie技术来将记录保存在客户端的浏览器中(现实生活中当然很少这样使用,这里只是作为案例学习),那么我们应该怎么做呢?

  首先我们必须在服务器要有两个Servlet,一个在用户眼中是用来显示所有商品的,一个是用来显示点击某个商品之后详细信息的。

  ⑴.用来显示所有商品的Servlet需要完成如下功能:

   ①     在一个部分以超链接形式将数据库中所有的商品显示在该Servlet上。

   ②     在另一个部分获取用户请求中的Cookie将之前浏览过的商品(通过Cookie中的商品id)显示在该Servlet上。

  ⑵.   用来显示点击某个商品之后详细信息的Servlet需要完成如下功能:

   ①     在页面上通过超链接的URL跟随的参数(即商品id)来获取该商品对象,同时将该商品对象的详细信息输出到Servlet页面上。

   ②     如果是用户首次访问,将用户浏览商品的id作为Cookie直接返回,而如果是用户再次访问,则需要根据一定的条件来将这些Cookie的值进行调整,以便易于显示和满足用户体验。

   当然,在这之前我们还需要做些准备工作,我们需要建立商品对象,这里简单的以书为商品建立对象:


public class Product {
 
 private String id;
 private String name;
 private String author;
 
 public Product() {
  super();
  
 }
 public Product(String id, String name, String author) {
  super();
  this.id = id;
  this.name = name;
  this.author = author;
 }
 
 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;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
}

我们还需要一个数据库来保存商品,这里我们先用一个类来来保存(数据库还没学嘛T_T!),保存数据采用Map集合,这是因为如果有检索会方便:


public class ProductDatabase {
 
 private static Map<String,Product> map = new HashMap<String, Product>();
 
 static{
  map.put("1", new Product("1","《Java编程思想》","JB"));
  map.put("2", new Product("2","《Java核心技术》","fdaf"));
  map.put("3", new Product("3","《Java并发编程》","什么鬼"));
  map.put("4", new Product("4","《Head first 设计模式》","老王"));
  map.put("5", new Product("5","《HTML5权威手册》","hhaa"));
 }
 
 public static Map<String,Product> getMap() {
 
  return map;
 }
 
}

做完了这两步,那么我们可以安心的去搞Servlet了,首先是在显示所有商品的Servlet:


response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=utf-8");
  
  PrintWriter writer = response.getWriter();
  //从数据库中取出要显示在购物网站首页的商品
  Map<String,Product> map = ProductDatabase.getMap();
  if(map == null) {
   writer.print("您访问的宝贝已下架");
   return ;
  }
  for(Map.Entry<String, Product> en : map.entrySet()) {
   writer.print("<a href=&#39;/CookieProductProject/servlet/DetailGoodServlet?id="+en.getKey()+"&#39; target=&#39;_blank&#39; >"
              +en.getValue().getName()+" <br/>");
  }
  
  
  //显示用户之前浏览过的商品,要从用户发送的请求中的Cookie里取得
  writer.print("<br/><br/>");
  writer.print("您最近浏览过的商品: <br/>");
  
  Cookie[] cookies = request.getCookies();
  for(int i=0;cookies!=null && i<cookies.length;i++ ) {
   if(cookies[i].getName().equals("productHistory")) {
    Cookie cookie = cookies[i];
    String productId = cookie.getValue();
    String[] splitId = productId.split("\\_");
    for(String sId:splitId) {
     Product book = ProductDatabase.getMap().get(sId);
     writer.print(book.getName()+"<br/>");
    }
   }
  }
}

最后是点击某个商品显示详细信息的Servlet:


response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter writer = response.getWriter();

  //通过用户点击商品的超链接而跟随URL来的ID参数来获取商品的详细信息
  String productId = request.getParameter("id");
  Map<String, Product> map = ProductDatabase.getMap();
  Product book = map.get(productId);
  writer.print("商品名:"+book.getName()+"<br />");
  writer.print("作者:"+book.getAuthor());
  
  //同时通过Cookie将用户观看的商品以Cookie的形式回传给用户浏览器 
  Cookie[] allCookies = request.getCookies();
  
  Cookie cookie = creCookie(book.getId(),allCookies);
  cookie.setMaxAge(24*60*60);
  response.addCookie(cookie);

其中creCookie(String,Cookie[])是自定义方法,用于获取用户的cookie并添加本次浏览商品id再作为cookie返回:


private Cookie creCookie(String id, Cookie[] cookies) {
  Cookie cookie = null;
  
  if(cookies == null) { //如果cookies为空,说明用户首次访问
   cookie = new Cookie("productHistory", id);
   System.out.println(cookie.getValue());
   return cookie;
  }
  for(int i=0; i<cookies.length; i++) {
   if(cookies[i].getName().equals("productHistory")){
    cookie = cookies[i];
   }
  }
  
  String historyStr = cookie.getValue(); //此时获取到的之前浏览过数据的历史记录,有多种情况
  String[] produIds = historyStr.split("\\_");
  
  //为了检测数组中是否有包含当前的id,建议使用集合,而且是使用链表结构的集合
  LinkedList<String> list = new LinkedList<String>(Arrays.asList(produIds));
  if(list.contains(id)) {
   list.remove(id);
  }
  else if(list.size()>=3){
    list.removeLast();
  }
  
  list.addFirst(id);
  
  StringBuilder sb = new StringBuilder();
  for(String sId :list) {
   sb.append(sId+"_");
  }
  sb.deleteCharAt(sb.length()-1); 
  cookie.setValue(sb.toString());
  System.out.println(cookie.getValue());
  return cookie;
}

我们在浏览器中进行首次访问:

  

随便点击个连接,可以看到该商品的详细信息(其实浏览器也偷偷将该商品的id以cookie传回了浏览器):

  

我们访问商品显示页面再次【刷新】就可以看到刚才浏览过的商品了:

  

总结

The above is the detailed content of A brief introduction to cookies in servlets in Java (pictures and text). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn