[Thực hành] Lưu tên người dùng sử dụng Cookie

10. Session&Cookie

Mục tiêu

Luyện tập thao tác với Cookie trong ứng dụng Spring MVC.

Mô tả

Trong phần này, chúng ta sẽ phát triển một tính năng cho phép người dùng đăng nhập vào ứng dụng và ghi nhận lại tên của người dùng nếu đăng nhập thành công.

Nếu lần sau quay lại đăng nhập thì tên của người dùng sẽ được tự động điền vào.

Các bước hoạt động của tính năng này bao gồm:

  1. Người dùng đăng nhập vào hệ thống
  2. Người dùng đăng xuất khỏi hệ thống (bằng cách nhấn nút đăng xuất hoặc tắt trình duyệt)
  3. Người dùng mở trang đăng nhập, tên của người dùng đã được nhập sẵn

Để hoàn thành bài thực hành, học viên cần:

  • Đưa mã nguồn lên GitHub
  • Dán link của repository lên phần nộp bài trên CodeGymX

Hướng dẫn

Bước 1: Tạo dự án Spring MVC.

Để tạo mới dự án, các bạn chọn File -> New -> Project.

Sau đó chọn Gradle -> Tích chọn Java, Web -> Chọn Next

Bạn nhập thông tin vào GroupId, và ArtifactId. Sau đó nhấn Next:

Màn hình sau đó bạn tiếp tục nhấn Next:

Nhập vào Project name, Project location. Sau đó nhấn Finish.

Bước 2: Tạo cấu trúc của dự án.

Bạn tạo cấu trúc của dự án như sau. Nhớ xóa file index.jsp trong trong thư mục webapp.

Bước 3: Cấu hình dependency trong build.gradle:

configurations {
    provided
    provided.extendsFrom(compile)
}

dependencies {
    compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.17.RELEASE'
    compile group: 'javax.servlet', name: 'jstl', version: '1.2'
    compile group: 'taglibs', name: 'standard', version: '1.1.2'
    providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
    provided group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '2.3.1'
    compile group: 'org.thymeleaf', name: 'thymeleaf-spring4', version: '3.0.4.RELEASE'
}

Bước 4: Cấu hình cho ứng dụng

4.1. Tạo class AppConfiguration trong thư mục com.codegym

package com.codegym;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;

@Configuration
@ComponentScan("com.codegym.controller")
@EnableWebMvc
public class AppConfiguration implements ApplicationContextAware {

    @Bean
    public SpringResourceTemplateResolver templateResolver(){
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    @Bean
    public TemplateEngine templateEngine(){
        TemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        return templateEngine;
    }

    @Bean
    public ViewResolver viewResolver(){
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        return viewResolver;
    }
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

4.2. Tạo class AppInitializer trong thư mục com.codegym

package com.codegym;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{AppConfiguration.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[0];
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

Bước 5: Tạo lớp User trong thư mục model

package com.codegym.model;

public class User {
    private String email;
    private String password;

    public User() {
    }

    public User(String email, String password) {
        this.email = email;
        this.password = password;

    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


}

Trong class User, chúng ta khai báo thuộc tính email, password sử dụng để điền thông tin vào form đăng nhập.

Bước 6: Xây dựng lớp LoginController

package com.codegym.controller;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import com.codegym.model.User;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@SessionAttributes("user")
public class LoginController {

    /*add user in model attribute*/
    @ModelAttribute("user")
    public User setUpUserForm() {
        return new User();
    }

    @RequestMapping("/login")
    public String Index(@CookieValue(value = "setUser", defaultValue = "") String setUser, Model model) {
        Cookie cookie = new Cookie("setUser", setUser);
        model.addAttribute("cookieValue", cookie);
        return "login";
    }

    @PostMapping("/dologin")
    public String doLogin(@ModelAttribute("user") User user, Model model, @CookieValue(value = "setUser", defaultValue = "") String setUser,
                          HttpServletResponse response, HttpServletRequest request) {
        //implement business logic
        if (user.getEmail().equals("admin@gmail.com") && user.getPassword().equals("12345")) {
            if (user.getEmail() != null)
                setUser = user.getEmail();

            // create cookie and set it in response
            Cookie cookie = new Cookie("setUser", setUser);
            cookie.setMaxAge(24 * 60 * 60);
            response.addCookie(cookie);

            //get all cookies
            Cookie[] cookies = request.getCookies();
            //iterate each cookie
            for (Cookie ck : cookies) {
                //display only the cookie with the name 'setUser'
                if (ck.getName().equals("setUser")) {
                    model.addAttribute("cookieValue", ck);
                    break;
                } else {
                    ck.setValue("");
                    model.addAttribute("cookieValue", ck);
                    break;
                }
            }
            model.addAttribute("message", "Login success. Welcome ");
        } else {
            user.setEmail("");
            Cookie cookie = new Cookie("setUser", setUser);
            model.addAttribute("cookieValue", cookie);
            model.addAttribute("message", "Login failed. Try again.");
        }
        return "login";
    }
}

Trong đó:

Annotation @SessionAttributes(“user”) được sử dụng để lưu trữ thông tin của model attribute có tên là user.

Đoạn mã sau đây sẽ add User vào trong model attribute:

@ModelAttribute("user")
    public User setUpUserForm() {
        return new User();
    }

Annotation @ModelAttribute(“user”) sẽ nhận user trả về từ view, sau đó đưa vào session:

@ModelAttribute("user") User user

model sẽ trả message về cho view trong trường hợp login thành công hoặc thất bại.

Annotation @CookieValue để ràng buộc giá trị của cookie HTTP với tham số phương thức trong controller.

response sẽ trả cookie về cho view sử dụng phương thức: response.addCookie(cookie);

if (user.getEmail().equals("admin@gmail.com") && user.getPassword().equals("12345")) {
            if (user.getEmail() != null)
                setUser = user.getEmail();

            // create cookie and set it in response
            Cookie cookie = new Cookie("setUser", setUser);
            cookie.setMaxAge(24 * 60 * 60);
            response.addCookie(cookie);

Đoạn mã trên sẽ so sánh email truyền vào có bằng với “admin@gmail.com” và password truyền vào có bằng với “12345” hay không. Nếu đúng sẽ thực hiện các công việc sau:

  • Gán email truyền vào cho biến setUser
  • Tạo cookie và trả về cho client
Cookie[] cookies = request.getCookies();
//iterate each cookie
for (Cookie ck : cookies) {
    //display only the cookie with the name 'setUser'
    if (ck.getName().equals("setUser")) {
        model.addAttribute("cookieValue", ck);
        break;
    } else {
        ck.setValue("");
        model.addAttribute("cookieValue", ck);
        break;
    }
}

Đoạn mã trên sẽ duyệt danh sách cookie và lấy cookie có tên ‘setUser’ sau đó truyền vào model.

Bước 7: Xây dựng view 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Cookie Demo</title>
</head>
<body>
<h1>User Login</h1>
<form action="#" th:action="@{/dologin}" th:object="${user}" method="post">
    <table border="0">
        <tr>
            <td><label>Email</label></td>
            <td><input type="text" id="email" name="email"
                       th:value="${cookieValue.value}"/></td>
        </tr>
        <tr>
            <td><label>Password</label></td>
            <td><input type="password" th:field="*{password}"/></td>
        </tr>
    </table>
    <input type="submit" value="Login"/>
</form>
<br>
<span th:text="${message}"></span>
<span th:text="${user.email}"></span>
</body>
</html>

Cú pháp gán giá trị cookie vào textbox như sau:

<input type="text" id="email" name="email"
           th:value="${cookieValue.value}"/>

Trong đó:

  • th:value = “${cookieValue.value}” để gán giá trị cookie có tên ‘setUser’ cho value của textbox

Bước 8: Cấu hình Artifact và Tomcat

Bước 9: Chạy ứng dụng

Chạy ứng dụng, nhập vào thanh địa chỉ như sau: http://localhost:8080/dologin

Nhập Email: admin@gmail.com. Password: 12345 và nhấn Login.

Tắt trình duyệt, sau đó bật lại trình duyệt và truy cập lại vào: http://localhost:8080/login

Email đã được nhập sẵn trong textbox.

Mã nguồn tham khảo: https://github.com/codegym-vn/java-spring-save-user

Leave a Reply

Your email address will not be published. Required fields are marked *