tags: Servlet


What is conversation technology

Basic concept: a user opens a browser and visits a website. As long as the browser is not closed, no matter how many hyperlinks the user clicks and how many resources the user accesses, until the user closes the browser, the whole process is called a session.


Why do we use session technology?

Session tracking technology can solve many, many of our problems.

  • When you log in to a forum, many times there will be a small box asking you if you want to log in automatically so that you don’t have to enter your password the next time you log in

  • Guess what I like based on what I’ve browsed before


Cookie

Session tracking technologies include Cookie and Session. Cookie technology comes first. Let’s talk about cookies first.

What is a Cookie

Cookie is a mechanism proposed by W3C and first developed by netscape community

  • Web pages interact by transferring data over HTTP, which is a stateless protocol. What does stateless protocol mean? Once the data is submitted, the connection between the browser and the server is closed and a new connection needs to be established when the browser interacts with the server again.
  • The server could not verify the user’s information, so the W3C proposed that each user be given a pass, and that whoever visits should carry a pass, so that the server can verify the user’s information from the pass. A pass is a Cookie


Cookie process: The browser visits the server. If the server needs to record the status of the user, it sends a Cookie to the browser using Response, and the browser saves the Cookie. When the browser visits the server again, the browser sends the requested URL to the server along with the Cookie.

Cookie API

  • The Cookie class creates a Cookie object
  • The Response interface defines an addCookie method, which is used to add a corresponding set-cookie header field to its response header
  • The request interface defines a getCookies method, which is used to getCookies submitted by the client

Common Cookie methods:

  • public Cookie(String name,String value)
  • SetValue and getValue methods
  • SetMaxAge and getMaxAge methods
  • SetPath and getPath methods
  • SetDomain and getDomain methods
  • GetName method

Simply using cookies

  • Create a Cookie object and send a Cookie to the browser,

        // Set the encoding of response
        response.setContentType("text/html; charset=UTF-8");

        // Create a Cookie object with a name and value
        Cookie cookie = new Cookie("username"."zhongfucheng");
        
        // Give a Cookie to the browser
        response.addCookie(cookie);

        response.getWriter().write("I've already sent a Cookie to my browser.");


Copy the code
  • The browser itself does not have any cookies

  • If I go to Servlet1 and go back to the folder, I still don’t find cookies. Why is that? I sent a Cookie to my browser.
  • It turns out that sending cookies to the browser requires setting the Cookie time. Before giving it to the browser, set the time for the Cookie

        // Set the Cookie time
        cookie.setMaxAge(1000);

Copy the code
  • A second visit to the folder has found a Cookie text


Cookie details

Cookies are not cross-domain

  • Many people may have a question when they first learn: when accessing a Servlet, the browser does not take all the cookies to the server, and does not change the cookies of other sites
  • The answer is no. Cookies are not cross-domain. The browser determines whether a web site can handle another web site’s cookies based on the domain name. Therefore, generally speaking, when I visit Baidu, the browser will only bring the Cookie issued by Baidu instead of Google’s Cookie.

Cookie save Chinese

  • Our example above saves English characters. Let’s see what happens if we save Chinese characters.

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

        String name = "China";
        Cookie cookie = new Cookie("country", name);
        cookie.setMaxAge(2000);
        response.addCookie(cookie);

        printWriter.write("I issued a Cookie and the value is stored in Chinese.");

Copy the code
  • Go to Servlet1, okay. Something’s wrong!

  • Chinese characters are Unicode characters, English data ASCII characters, Chinese contains 4 characters or 3 characters, English contains 2 characters.
  • Solution: Unicode characters need to be encoded when cookies use Unicode characters.

        // Encode Unicode characters
        Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));

Copy the code
  • Revisiting Servlet1, the Cookie has been successfully issued to the browser

  • We found that the Chinese data stored in the Cookie’s hard disk was encoded, so we need to decode the Chinese data when we take out the Cookie

        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies ! =null && i < cookies.length; i++) {
            String name = cookies[i].getName();

            // After URLEncoding, URLDecoding is required
            String value = URLDecoder.decode(cookies[i].getValue(), "UTF-8");

            printWriter.write(name + "-- -- -- -- -- -" + value);
        }

Copy the code
  • Retrieves the value stored in the Cookie


Validity period of Cookie

The Cookie validity period is set by setMaxAge().

  • If MaxAge is positive, the browser will write the Cookie to the hard disk, and the Cookie will be valid when you log in to the site (whether the browser is closed or the computer is closed) as long as MaxAge is within seconds.
  • If MaxAge is negative, the Cookie is temporary and only valid within the browser. If the browser is closed, the Cookie is invalid and the Cookie is not written to hard disk. The Cookie defaults to -1. That’s why, in my first example, if I didn’t set the expiration date for the Cookie, I couldn’t find the corresponding file on my hard disk.
  • If MaxAge is 0, the Cookie is deleted. The Cookie mechanism does not provide a method for deleting cookies. Setting MaxAge to 0 is equivalent to deleting cookies

Cookie modification and deletion

  • As we have seen above, the Cookie mechanism does not provide a way to delete cookies. In fact, we can see that the Cookie mechanism does not provide a way to modify cookies. So how do we change the value of the Cookie?
  • Cookies are stored like a Map collection, as shown in the figure below

  • The Cookie has the same name and is added to the browser through response, overwriting the original Cookie.

  • I’m going to save %E4%B8%AD%E5%9B%BD, and I’m going to change it to country again.


        String name = "Like a blog as soon as you read it.";

        // Encode Unicode characters
        Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));

Copy the code
  • When YOU look at the Cookie again, the value has changed, but the file is still the same

  • Now I need to delete the Cookie, set MaxAge to 0, and add it to the browser


        String name = "Like a blog as soon as you read it.";

        // Encode Unicode characters
        Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));

        Don't forget to add it to the browser
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        printWriter.write("I deleted that Cookie.");

Copy the code
  • Access Servlet, can not find Cookie file on hard disk!

  • Note: When deleting or modifying a Cookie, all attributes of the new Cookie except value and maxAge must be the same as the original Cookie. Otherwise, the browser will regard the Cookie as different and will not overwrite it, resulting in deletion and modification failure!

  • Let’s try it out.



        String name = "Like a blog as soon as you read it.";

        // Encode Unicode characters
        Cookie cookie = new Cookie("country", URLEncoder.encode(name, "UTF-8"));

        Don't forget to add it to the browser
        cookie.setMaxAge(10000);
        response.addCookie(cookie);

Copy the code

  • I’m going to create a Cookie, and I’m going to modify the other properties of the Cookie, and then delete it, and see if I can delete the Cookie


        Don't forget to add it to the browser

        cookie.setPath("/ouzicheng");
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        printWriter.write("Delete a Cookie");

Copy the code
  • Turns out the Cookie is still on the hard drive


Cookie domain ###

The domain property of the Cookie determines the domain name to run the access Cookie. Domain is set to. Domain name.

  • The privacy security mechanism of cookies determines that cookies are not cross-domain. In other words, the cookies between www.baidu.com and www.google.com are not exchanged. Even if the same level 1 domain name, different level 2 domain names cannot be exchanged, that is, the cookies of www.goole.com and www.image.goole.com cannot be accessed

  • I 3 virtual host on the local configuration, localhost, www.zhongfucheng.com, www.image.zhongfucheng.com (if you don’t know how to configure, in my blog Tomcat 】

  • I sent a Cookie to the browser using the www.zhongfucheng.com domain name

        Cookie cookie = new Cookie("name"."zhongfucheng");
        cookie.setMaxAge(1000);
        response.addCookie(cookie);

        printWriter.write("Added a Cookie using www.zhongfucheng.com domain name");

Copy the code

  • First, it proves that cookies are not cross-nameable, and the localhost domain cannot get the Cookie issued to the browser by www.zhongfucheng.com

  • Again using the www.image.zhongfucheng.com domain name to access, prove that even if the primary domain name, the same secondary domain name is different, also can’t get to the cookies

  • Of course, using www.zhongfucheng.com will of course fetch the Cookie, which is sent to the server in the request header

  • Now I want cookies on web pages with the same level 1 domain name to be accessible to each other. That is to say www.image.zhongfucheng.com access to the www.zhongfucheng.com Cookie will need to use the domain method.

        Cookie cookie = new Cookie("name"."ouzicheng");
        cookie.setMaxAge(1000);
        cookie.setDomain(".zhongfucheng.com");
        response.addCookie(cookie);

        printWriter.write("Use www.zhongfucheng.com domain name to add a Cookie, as long as the level is zhongfucheng.com can be accessed");
Copy the code
  • Publish a Cookie using www.zhongfucheng.com

  • Using the www.image.zhongfucheng.com domain name to access it. The Cookie is available


The path of the Cookie

The Cookie’s path property determines the path through which the Cookie is allowed to be accessed

  • Typically, cookies are published and the entire web page’s resources are available. For now, I just want Servlet1 to get cookies, but not other resources.

  • Issue a Cookie to the browser using Servlet2 and set the path to “/Servlet1”.


        Cookie cookie = new Cookie("username"."java");
        cookie.setPath("/Servlet1");
        cookie.setMaxAge(1000);
        response.addCookie(cookie);

        printWriter.write("This Cookie is available only to Servlet1");


Copy the code
  • Use Servlet3 to access the server and see if the browser takes the Cookie with it. Obviously, the browser accessing Servlet3 does not take the Cookie with it.

  • Use Servlet1 to access the server and see if the browser takes the Cookie with it. The answer is yes!


The security properties of the Cookie

  • The HTTP protocol is not only stateless, it is insecure! If you do not want the Cookie to be transmitted over non-secure protocols, you can set the secure attribute of the Cookie to true. Therefore, the browser transmits the Cookie only over secure protocols such as HTTPS and SSL.
  • Of course, setting the secure property does not encrypt the contents of the Cookie. If you want to ensure security, it is best to use md5 encryption algorithm [see below].

The application of the Cookie

Displays the last access time of the user

  • In fact, every time you log in, take the value saved by the Cookie, and then update the value of the Cookie.

  • There are two scenarios for visiting Serlvet

    • First visit
    • Already visited
  • The full code is as follows:


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter printWriter = response.getWriter();



        // Get all cookies on the page
        Cookie[] cookies = request.getCookies();

        // Determine whether the value of Cookie is null
        String cookieValue = null;
        for (int i = 0; cookies ! =null && i < cookies.length; i++) {

            // Get a Cookie named time
            if (cookies[i].getName().equals("time")) {
                printWriter.write("The last time you logged in was:");
                cookieValue = cookies[i].getValue();
                printWriter.write(cookieValue);

                cookies[i].setValue(simpleDateFormat.format(new Date()));
                response.addCookie(cookies[i]);
                
                // Now that we have found it, we can break the loop
                break; }}// If the value of the Cookie is empty, then it is the first access
        if (cookieValue == null) {
            // Create a Cookie object with a date of the current time
            Cookie cookie = new Cookie("time", simpleDateFormat.format(new Date()));

            // Sets the lifetime of the Cookie
            cookie.setMaxAge(20000);

            // The response object sends back the Cookie to the browser
            response.addCookie(cookie);

            printWriter.write("It's your first time landing!");
        }

Copy the code
  • In normal logic, the flow of the program would look something like this. A Cookie object is created and sent back to the browser. Iterate over the Cookie again, updating the value of the Cookie.

  • However, the above logic cannot be done! Because the original Cookie is overwritten every time the Servlet is accessed, the value of the Cookie is always the current time, not the last time it was saved.

  • If I do not get the Cookie I want, the value of the Cookie is null, then it is the first login, so there is the above code.

  • Let’s take a look at the effect! When I first logged on

  • Cookies are stored on the hard drive.

  • Visit the Servlet again. Obviously, this is the value of the Cookie


Displays the last item viewed

  • I’ll take books as an example! Start by designing the Book object

    private String id ;
    private String name ;
    private String author;

    public Book(a) {}public Book(String id, String name, String author) {
        this.id = id;
        this.name = name;
        this.author = author; }... Various set and get methodsCopy the code
  • Design a simple database to store data. 1. Use LinkedHashMap instead.


    private static LinkedHashMap<String, Book> linkedHashMap = new LinkedHashMap();
    
    
	// To simplify development, the book id is the same as the commodity ID
    static {
        linkedHashMap.put("1".new Book("1"."javaweb"."zhong"));
        linkedHashMap.put("2".new Book("2"."java"."fu"));
        linkedHashMap.put("3".new Book("3"."oracle"."cheng"));
        linkedHashMap.put("4".new Book("4"."mysql"."ou"));
        linkedHashMap.put("5".new Book("5"."ajax"."zi"));
    }

    // Get all the books
    public static LinkedHashMap getAll(a) {
        return linkedHashMap;
    }


Copy the code
  • Show all books on the page

        printWriter.write("All books on the web:"+"<br/>");

        // Get all the books in the database
        LinkedHashMap<String, Book> linkedHashMap = DB.getAll();
        Set<Map.Entry<String, Book>> entry = linkedHashMap.entrySet();

        // Display all the books on the page
        for (Map.Entry<String, Book> stringBookEntry : entry) {
            Book book = stringBookEntry.getValue();
            printWriter.write(book.getId() +""+ book.getName()+"<br/>");
        }


Copy the code

  • Next, all we need to do is attach a hyperlink to the book that is displayed, and when the user clicks on the book that they want to see, they go to the details page of that book
  • The hyperlink should pass the book ID, otherwise the processing page will not know which book the user wants to see!

        // Display all the books on the page
        for (Map.Entry<String, Book> stringBookEntry : entry) {
            Book book = stringBookEntry.getValue();
            printWriter.write(" + book.getId() + "''target=_blank' +" + book.getName() + "</a>");
            printWriter.write("<br/>");
        }

Copy the code

  • Receive the ID, find out which book the user wants to read, and output the details of the book

        String id = request.getParameter("id");

        // Because the book id is the same as the product ID. Get the book that the user clicked on
        Book book = (Book) DB.getAll().get(id);

        // Print the details of the book
        printWriter.write("The book number is:" + book.getId()+"<br/>");
        printWriter.write("The title of the book is:" + book.getName()+"<br/>");
        printWriter.write("The author is:" + book.getAuthor()+"<br/>");

Copy the code
  • Click on the book you want.

  • Get detailed information about books

  • Since the user clicked on the book, the server should issue a Cookie to the browser to remember that the user clicked on the book

  • Now the question is, what should the value of the Cookie be? If you want to display the books you browse later, it’s best to use the id of the book. With the book ID as the Cookie value in mind, we also need to define some rules!

  • We may have so many books that it is impossible to display all the books the user has viewed. So we defined that only three browsed books could be displayed

  • The id of the book is a number, if you do not make any changes, the number stored in the Cookie may be 231,345,123, so it is very difficult to retrieve a certain ID and later need to determine whether the book exists in the Cookie, so we need to separate the book ID stored in the Cookie. So we define “_” as the separator

  • Based on the above application, our logic should be: first go through the Cookie to see if there is any Cookie we want. If you find the Cookie you want, fetch the value of the Cookie


        String bookHistory = null;
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies ! =null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("bookHistory")) { bookHistory = cookies[i].getValue(); }}Copy the code
  • There are a couple of cases where the Cookie is fetched

    1. The value of Cookie is null
    2. There are three values in the Cookie.
    3. The Cookie value already contains the id passed in.
    4. The Cookie has only one or two values, putting the ID first


        if (bookHistory == null) {
            return id;
        }

        // If the value of the Cookie is not null, then the Cookie is decomposed to get the previous ID.
        String[] strings = bookHistory.split(\ \ "_");

        // To make it easy to add and delete and to determine if the ID exists in the string ----- we use the collection LinkedList to load the decomposed iD
        List list = Arrays.asList(strings);
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.addAll(list);

        if (linkedList.contains(id)) {
            linkedList.remove(id);
            linkedList.addFirst(id);
        }else {
            if (linkedList.size() >= 3) {
                linkedList.removeLast();
                linkedList.addFirst(id);
            } else{ linkedList.addFirst(id); }}Copy the code
  • Now that we’re done, our Cookie value is in our LinkedList collection. Now, all we need to do is take the values from the set and concatenate them into a string


        StringBuffer stringBuffer = new StringBuffer();

        // Walk through the LinkedList collection and add an underscore "_"
        for (String s : linkedList) {
            stringBuffer.append(s + "_");
        }

        // There is no need to underline the last element
        return stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString();


Copy the code
  • Okay, so now we’ve done the Cookie value. Next, set the Cookie life cycle and send it back to the browser

        String bookHistory = makeHistory(request, id);
        Cookie cookie = new Cookie("bookHistory", bookHistory);
        cookie.setMaxAge(30000);
        response.addCookie(cookie);

Copy the code
  • Now that we’ve sent the Cookie back to the browser. Then we will get the value of the Cookie on the home page, showing what products the user has browsed!


        printWriter.write("Items you have browsed:");
        printWriter.write("<br/>");

        // Displays items browsed by the user
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies ! =null && i < cookies.length; i++) {

            if (cookies[i].getName().equals("bookHistory")) {

                // Get a bookHistory of 2_3_1 or something like that
                String bookHistory = cookies[i].getValue();

                // Split into each id value
                String[] ids = bookHistory.split(\ \ "_");

                // Get each id value
                for (String id : ids) {

                    // Find each book by id
                    Book book = linkedHashMap.get(id);

                    printWriter.write(book.getName());
                    printWriter.write("<br/>");

                }
				break; }}Copy the code
  • Ok, let’s try it out!! , the first time to visit the home page, and did not browse the product

  • When I click on javaweb books to return to the home page

  • Click Ajax again and go to the home page

  • Click JavaWeb again and visit the home page

  • Click Oracle and go to the home page

  • Ok, after testing, the program should have no problems!

jdbc

If you find this article helpful, give the author a little encouragement