JSP/Servlet | Sessions and Cookies | Basic Cookie Operations and Usage

On the web, all data exists across the network. In the past, browsers could not keep much data locally. With HTML5, many kinds of data can now be stored, and the shape of the web has changed significantly. Until HTML5 appeared, the only browser feature that could store data was the cookie.

Cookies let you store a small amount of data in the browser. That is their basic role. Their value is that they can exchange information between the browser and the server. Since data can be stored separately for each client, or web browser, cookies can be used in many ways. For example, you can assign an ID to identify each client, or store information such as the last access time.

Recently, HTML5 has made it possible to store various information locally, but because the necessary information can only be extracted through JavaScript, using it from the server side is quite troublesome. There are also still browsers that do not support HTML5. Cookies are still highly useful as client-side data that can be exchanged smoothly between client and server.

Let’s summarize how to use cookies. Cookies are provided as a class named Cookie. Create an instance as follows.

Cookie variable = new Cookie(name, value);

A cookie consists of the value to store and the name attached to it. This lets you organize and store multiple values by name. How do you save and retrieve these cookies?

response.addCookie(cookie);

Receiving cookies

Cookie[] variable = request.getCookies();

Saving a cookie is done by calling a method on the object named response. This object manages information about the response to the client. Execute the addCookie method with the Cookie instance to save as its argument.

Receiving cookies is a little more troublesome. JSP does not provide a feature for retrieving only a specific cookie. The available method is only getCookies on the request object. It obtains all cookies stored for the relevant site as a Cookie array. You can extract the stored name and value from each Cookie as follows.

String variable = cookie.getName();
String variable = cookie.getValue();

Therefore, although it is a little complex, you must obtain all cookies with getCookies, loop through them, take each Cookie in order, and check its name with getName to find the cookie you need.

Setting an expiration period

cookie.setMaxAge(seconds);

One more thing to remember is this method. It sets how long a cookie is stored. With this, you can specify until when the cookie is retained. If you do not set it, the cookie disappears when the browser is closed.

Trying cookies

Now let’s actually use cookies to store data on the client and retrieve it.

Here is a sample that stores a simple message and the number of page loads in cookies. The following is the JSP source code.

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.net.*"%>
<%
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    req = request;
    String input = request.getParameter("input");
    if (input == null)
        input = "";
    Cookie msg = getCookie("message");
    Cookie count = getCookie("count");
    if (msg == null) {
        input = URLEncoder.encode(input, "utf-8");
        msg = new Cookie("message", input);
        response.addCookie(msg);
    }
    if (count == null) {
        count = new Cookie("count", "0");
        response.addCookie(count);
    } else {
        String num = count.getValue();
        int n = Integer.parseInt(num);
        n++;
        count = new Cookie("count", String.valueOf(n));
        response.addCookie(count);
    }
    if (!input.equals("")) {
        input = URLEncoder.encode(input, "utf-8");
        msg = new Cookie("message", input);
        response.addCookie(msg);
        count = new Cookie("count", "1");
        response.addCookie(count);
    }
%>
<%!HttpServletRequest req;

    Cookie getCookie(String s) {
        Cookie[] cookies = req.getCookies();
        Cookie res = null;
        if (cookies != null) {
            for (Cookie c : cookies) {
                if (s.equals(c.getName())) {
                    res = c;
                    break;
                }
            }
        }
        return res;
    }%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sample jsp</title>
<style>
h1 {
    font-size: 16pt;
    background: #AAFFAA;
    padding: 5px;
}
</style>
</head>
<body>
    <h1>Sample jsp page</h1>
    <p>This page is a sample.</p>
    <p><%=count.getValue() + ": " + URLDecoder.decode(msg.getValue(), "utf-8")%></p>
    <form method="post" action="hello8.jsp">
        <table>
            <tr>
                <td>Input</td>
                <td><input type="text" id="input" name="input"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="Send"></td>
            </tr>
        </table>
    </form>
</body>
</html>

When you access this JSP page, a form with one input field appears. If you write text there and send it, the message is stored in a cookie and displayed on the page when you access it. If you reload several times, you can see that the sent message is remembered and displayed correctly.

The counter also increases each time you refresh. The last counter value is stored in a cookie, and the value plus 1 is stored again to update it. If you send a new message and change it, the counter is reset and starts over.

Here, a method named getCookie is defined to retrieve a Cookie by name. This method gets an array of all Cookies with getCookies and checks the names in a loop. The point to watch here is how the implicit object HttpServletRequest is handled.

The getCookie method obtains the Cookie array with req.getCookies();, but this req is not an implicit object. In fact, implicit objects cannot be used inside this kind of method definition. Implicit objects can be used only inside code written in <% %>, generally called a script. Therefore, a global variable is prepared in advance and request is assigned to it.

Another point to note is the text stored in cookies. Cookies can store only ordinary ASCII text, or alphanumeric characters. Korean and similar text cannot be stored as-is.

How should Korean text be stored, then? Encode it into a form that can be represented as ASCII text. This is URL encoding. Convert the text to this format before storing it, and decode it again after retrieving it.

URL-encoding text

String variable = URLEncoder.encode(value, encodingName);

URL-decoding text

String variable = URLDecoder.decode(value, encodingName);

URLEncoder.encode returns URL-encoded text, and URLDecoder.decode returns encoded text restored to the original text. By using these to encode text before storing it in a cookie and decode it after retrieving it, Korean text can also be stored in cookies without problems.

In addition, the following statements are executed at the beginning to set text encoding for the request and response.

request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");

Setting the encoding properly helps prevent garbled Korean characters. This was not done in the earlier form submission examples, but when using Korean text, it is better to set these values. Remember this here.