2024.5.7 Tuesday
Continuing from 【WEEK11】 【DAY1】Employee Management System Part 2【English Version】
Contents
- 10.4. Login Functionality
- 10.4.1. Modify index.html
- 10.4.2. Main Page Style Missing After Login Failure
- 10.4.3. Create LoginController.java
- 10.4.4. Username and Password Displayed in URL After Login
- 10.4.5. Restart and Access
- 10.4.5.1. When Incorrect Username or Password is Entered
- 10.4.5.2. Existing Issues
- 10.4.6. Login Interceptor
- 10.4.6.1. Create LoginHandlerInterceptor.java
- 10.4.6.2. Modify LoginController.java
- 10.4.6.3. Modify MyMvcConfig.java
- 10.4.6.4. Restart and Run
- 10.4.6.5. Modify dashboard.html
10.4. Login Functionality
10.4.1. Modify index.html
Modify lines 16, 20, 22, and add two lines after line 18, to prompt users in case of incorrect username or password input.
The modifications, along with those from 10.4.2., for lines 10 to 24 are as follows:
<link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<!--Lines that need to be modified for Thymeleaf: 2,10,13,17-->
<body class="text-center">
<form class="form-signin" th:action="@{/user/login}"><!--Clicking login on the page will redirect to /user/login-> which is the address pointed to by the LoginController file-->
<img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!--If the value of msg is empty, do not display an error message-->
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
<label class="sr-only" th:text="#{login.username}">Username</label>
<input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required="">
10.4.2. Main Page Style Missing After Login Failure
Reason: The style links in the index did not start with a slash -> Solution: Add a slash
All @{/}
in the HTML should be prefixed with “/css/xxx.js”
10.4.3. Create LoginController.java
You can first test it out
package com.P14.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginController {
@RequestMapping("/user/login")
@ResponseBody
public String logi(){
return "ok";
}
}
At this point, only the 16th line of index.html has been modified
<form class="form-signin" th:action="@{/user/login}">
The completed modifications are:
package com.P14.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.thymeleaf.util.StringUtils;
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String logi(@RequestParam("username") String username,
@RequestParam("password") String password,
Model model){
//The specific business logic
if (!StringUtils.isEmpty(username) && "123456".equals(password)){
//Login successful, redirect to /main (which has been set in MyMvcConfig to direct to dashboard.html)
return "redirect:/main.html";
}else {
//Prompt that login has failed
model.addAttribute("msg","Incorrect username or password");
return "index";
}
}
}
10.4.4. Username and Password Displayed in URL After Login
Modify MyMvcConfig.java
Simply add one line
registry.addViewController("/main.html").setViewName("dashboard");
Overall:
package com.P14.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//@EnableWebMvc // This imports a class, DelegatingWebMvcConfiguration, which acquires all the webMvcConfig from the container
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Redirect the following two URLs to the index page file
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
// Make the custom internationalization component effective
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
10.4.5. Restart and Access
http://localhost:8080/
Automatically redirected to http://localhost:8080/main.html
10.4.5.1. When Incorrect Username or Password is Entered
10.4.5.2. Existing Issues
Directly entering http://localhost:8080/main.html also allows access to the dashboard.html page
10.4.6. Login Interceptor
10.4.6.1. Create LoginHandlerInterceptor.java
Override (Ctrl+O)
package com.P14.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// After successful login, there should be a user session
Object loginUser = request.getSession().getAttribute("loginUser"); // From parameters passed by LoginController
if (loginUser==null){ // Not logged in
request.setAttribute("msg","Unauthorized access, please login first");
request.getRequestDispatcher("/index.html").forward(request,response);
return false; // Do not allow access
} else {
return true; // Allow access
}
}
}
10.4.6.2. Modify LoginController.java
package com.P14.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String logi(@RequestParam("username") String username,
@RequestParam("password") String password,
Model model,
HttpSession session){
// Specific business logic
if (!StringUtils.isEmpty(username) && "123456".equals(password)){
session.setAttribute("loginUser",username);
// Login successful, redirect to /main (which has been set in MyMvcConfig to direct to dashboard.html)
return "redirect:/main.html";
}else {
// Prompt that login has failed
model.addAttribute("msg","Incorrect username or password");
return "index";
}
}
}
10.4.6.3. Modify MyMvcConfig.java
Configure to register as a bean
Add interceptors
package com.P14.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//@EnableWebMvc // This imports a class, DelegatingWebMvcConfiguration, which acquires all the webMvcConfig from the container
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Redirect the following two URLs to the index page file
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
// Make the custom internationalization component effective
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login");
}// /static/* can also be included
}
10.4.6.4. Restart and Run
Now, access to http://localhost:8080/main.html is restricted when not logged in.
10.4.6.5. Modify dashboard.html
On line 46, make the “company name” displayed after login to be the username used during login
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>