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