Page setup
After downloading the bootstrap template, place the HTML files in the templates folder and the results folder with CSS, IMG, JS files in the static folder.
The home page of the template I downloaded:
Internationalization Settings
Internationalization means that the language of the page will change according to the different language. For example, in the above example, the display language is English. Here we can change it to Chinese:
Before setting internationalization, set the character set in IDEA to UTF-8
Create a new i18n folder under the Resources folder and create a login.properties file in it, then create a new login_zh_cn.properties file, IDEA will automatically place the two files in a Resource Bundle ‘login’ folder.
Create a new en_US file
Click on the login.properties file and click on the + symbol to create login.tip:
We want to internationalize these five parts:
Then add to the main configuration file application.properties:
spring.messages.basename=i18n.login
Copy the code
Here we want to internationalize index.html, so add
<html lang="en" xmlns:th="http://www.thymeleaf.org">
Copy the code
Add the corresponding configuration with #{}
The home page ended up looking like what I showed you before. Then we want to click on the Chinese part of the page and the English part will jump to a different part of the page, so we need to customize a parser.
In the MVC auto-configuration class WebMvcAutoConfiguration, there is a method to resolve the locale:
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
prefix = "spring.mvc",
name = {"locale"})public LocaleResolver localeResolver(a) {
// If we have configured the local regionalization information, we return the user-configured information
if (this.mvcProperties.getLocaleResolver()==org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleReslvr.FIX ED) {return new FixedLocaleResolver(this.mvcProperties.getLocale());
} else { // Otherwise use the default locale parser
AcceptHeaderLocaleResolver localeResolver = newAcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
returnlocaleResolver; }}Copy the code
This is the default locale parser:
public class AcceptHeaderLocaleResolver implements LocaleResolver {
public Locale resolveLocale(HttpServletRequest request) {
// Get the default locale
Locale defaultLocale = this.getDefaultLocale();
// If the default environment is not empty and the accept-language header field is empty,
// Use the default locale
if(defaultLocale ! =null && request.getHeader("Accept-Language") = =null) {
return defaultLocale;
} else {
Locale requestLocale = request.getLocale();
List<Locale> supportedLocales = this.getSupportedLocales();
if(! supportedLocales.isEmpty() && ! supportedLocales.contains(requestLocale)) { Locale supportedLocale =this.findSupportedLocale(request, supportedLocales);
if(supportedLocale ! =null) {
return supportedLocale;
} else {
returndefaultLocale ! =null? defaultLocale : requestLocale; }}else {
returnrequestLocale; }}}}Copy the code
Let’s write a custom parser just like this:
public class MyLocalResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
String chooseLanguage = httpServletRequest.getParameter("language");
Locale locale = Locale.getDefault();
// stringutils. isBlank(String STR) determines whether a String is empty or has a length of 0 or consists of whitespace
STR ==null or str.length()==0
if(! StringUtils.isEmpty(chooseLanguage)) {//zh_CN
String[] languages = chooseLanguage.split("_");
// The parameters are language and environment
locale = new Locale(languages[0], languages[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {}}Copy the code
The custom internationalized components are then added to the container
@configuration public class MyMVCConfig implements WebMvcConfigurer {@bean // Adds the component MyLocalResolver public to the container LocaleResolverlocaleResolver() {
returnnew MyLocalResolver(); }}Copy the code
Here’s the link to the request:
Click “English” to switch to the page of the corresponding region
logon
First, set the name value corresponding to the entered account name and password on the login page and set the prompt message:
Then there is the Controller that handles the request:
@Controller
public class UserController {
@RequestMapping("/user/login")
public String login(@RequestParam("uname") String uname, @RequestParam("password") String password,
Model model, HttpSession session) {
if(! StringUtils.isEmpty(uname) &&"123".equals(password)) {
session.setAttribute("loginUser", uname);
/* Here we define a custom view parser to handle requests to main.html. Its request to the dashboard. The HTML page request In fact we are not the main HTML page This is to cover up the fallen after landing address bar appears similar to http://localhost:8080/user/login? Uname =123&password=123 (Forward :/main.html cannot hide the input information) */
return "redirect:/main.html";
}else {
model.addAttribute("msg"."Wrong username or password");
return "index"; }}}Copy the code
But in order to prevent the user is not login by entering the address http://localhost:8080/main.html to access the page directly, we need a blocker to detect whether visitors log in:
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
if(loginUser == null) {
request.setAttribute("msg"."Please login first.");
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
}else {
return true; }}}Copy the code
Finally, customize the jump page and start the interceptor in the configuration class,
@Configuration
public class MyMVCConfig implements WebMvcConfigurer {
// View converter
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
System.out.println("addViewControllers");
registry.addViewController("/main.html").setViewName("dashboard");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// All requests except to access the home page, login, and static resources must pass through the interceptor
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/ * *").excludePathPatterns("/index.html"."/"."/user/login"."/asserts/*");
}
@Bean // Inject the custom internationalization component MyLocalResolver into the container
public LocaleResolver localeResolver(a) {
return newMyLocalResolver(); }}Copy the code
After the operation whether directly enter http://localhost:8080/dashboard.html or http://localhost:8080/main.html, will go to the login page and tip need to log in:
After login, you can jump to the page:
Here are the two messages redirect sends:
The background is set
Here we take the employee management system as an example of add, delete, change and check.
We can omit the get/set constructor of the bean class using the Lombok tool.
First import dependencies:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
Copy the code
Then add related plug-ins to IDEA and enable them.
Then there are the two bean classes:
@Data // Provide get and set methods for all attributes of the class, as well as equals, canEqual, hashCode, and toString methods.
@NoArgsConstructor // No arguments
@AllArgsConstructor // There are parameters
public class Department {
private Integer id;
private String name;
}
Copy the code
@Data @NoArgsConstructor public class Employee { private Integer id; private String lastName; private String email; private Integer sex; private Department department; private Date birth; public Employee(Integer id, String lastName, String email, Integer sex, Department department) { this.id = id; this.lastName = lastName; this.email = email; this.sex = sex; this.department = department; this.birth = new Date(); // Default date}}Copy the code
Dao layer, where we use HashMap to simulate two tables in the database without storing records in the database
@Repository
public class EmployeeDao {
// Simulate employee table
private static Map<Integer, Employee> employees = null;
@Autowired
private DepartmentDao departmentDao;
static {
employees = new HashMap<Integer, Employee>();
employees.put(1001.new Employee(1001."AA"."[email protected]".1.new Department(101."Teaching Department")));
employees.put(1002.new Employee(1002."BB"."[email protected]".0.new Department(101."Marketing Department")));
employees.put(1003.new Employee(1003."CC"."[email protected]".0.new Department(101."Operations department")));
employees.put(1004.new Employee(1004."DD"."[email protected]".1.new Department(101."Teaching and Research Department")));
employees.put(1005.new Employee(1005."EE"."[email protected]".1.new Department(101."Logistics department")));
}
// Simulate primary key increment
private static Integer selfIncreaseId = 1006;
// Since we are treating the HashMap as a staff table,
// Therefore, adding/updating employee information is the same method
public void save(Employee employee) {
if(employee.getId() == null) {
employee.setId(selfIncreaseId++);
}
// Set the department before adding the new employee record. The department information is obtained from the new employee information.
employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
// Simulate adding the new record to the employee table
employees.put(employee.getId(), employee);
}
// Query all employee information
public Collection<Employee> getAll(a) { returnemployees.values(); }public Employee getById(Integer id) { return employees.get(id); }
public void deleteById(Integer id) { employees.remove(id); }}Copy the code
@Repository
public class DepartmentDao {
// Simulate the department table
private static Map<Integer, Department> departments = null;
// Department table initial record
static {
departments = new HashMap<Integer, Department>();
departments.put(101.new Department(101."Teaching Department"));
departments.put(102.new Department(101."Marketing Department"));
departments.put(103.new Department(101."Operations department"));
departments.put(104.new Department(101."Teaching and Research Department"));
departments.put(105.new Department(101."Logistics department"));
}
public Collection<Department> getDepartments(a) { return departments.values(); }
public Department getDepartmentById(Integer id) { returndepartments.get(id); }}Copy the code
Finally, the project page structure is given:
Add operation
Start by setting the date format in the main configuration file application.properties:
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
Copy the code
Log in on the Index page and click on the employee management option to make a request
The request goes to the toAddPage method of the EmployeeController class:
@Controller
public class EmployeeController {
// The Controller layer should call the Service layer, so we call the DAO layer directly
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
@RequestMapping("/getEmps")
public String list(Model model) {
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("emps", employees);
return "emp/list";
}
@GetMapping("/addEmp")
public String toAddPage(Model model) {
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("departments", departments);
return "emp/add";
}
@PostMapping("/addEmp")
public String addEmp(Employee employee) {
System.out.println(employee);
employeeDao.save(employee);
// (1) If the value is forward, the system jumps to the employee information list after adding the employee information for the first time
// A record is added each time the page is refreshed.
// (2) cannot return "getEmps"
return "redirect:/getEmps"; }}Copy the code
Then go to the Add page:
After filling in the information, submit it, go to addEmp method, and then jump to the list page under emP folder:
rendering
The update operation
Log in on index page, click Employee Management to go to List page, click Edit button,
The toUpdatePage method under EmployeeController then processes the request
/* Jump to the update page */
@GetMapping("/emp/{id}")
public String toUpdatePage(@PathVariable("id")Integer id, Model model) {
Employee employee = employeeDao.getById(id);
System.out.println(employee);
model.addAttribute("emp", employee);
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("departments", departments);
return "emp/update";
}
@PostMapping("/updateEmp")
public String updateEmp(Employee employee) {
System.out.println(employee);
employeeDao.save(employee);
return "redirect:/getEmps";
}
Copy the code
The UPDATE page in the EMP folder is displayed
UpdateEmp then processes and jumps to the List page.
rendering
Delete operation
Click the Delete option on the List page, and EmployeeController processes the request
@GetMapping("/delEmp/{id}")
public String deleteEmp(@PathVariable("id")Integer id) {
employeeDao.deleteById(id);
return "redirect:/getEmps";
}
Copy the code
Finally, go to the List page
rendering
Other operating
404 pages
Put pages like 404,505 that need to display errors on the newly created error page
registered
Invalidate HttpSession using the invalidate method under UserController and go to the login page
@RequestMapping("/user")
@Controller
public class UserController {
@RequestMapping("/login")
public String login(@RequestParam("uname") String uname, @RequestParam("password") String password,
Model model, HttpSession session) {
if(! StringUtils.isEmpty(uname) &&"123".equals(password)) {
session.setAttribute("loginUser", uname);
System.out.println("Forward request main.html");
return "redirect:/main.html";
}else {
model.addAttribute("msg"."Wrong username or password");
return "index"; }}@RequestMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/index.html"; }}Copy the code