Employee management system
1. Preparation
-
Import html and front page first
-
Establish two entity classes: Department and Employee
Department:
package com.dary.sweb.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; //Department table @Data @AllArgsConstructor @NoArgsConstructor public class Department { private Integer id; private String departmentName; }
Employee:
package com.dary.sweb.pojo; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; //Employee table @Data @NoArgsConstructor public class Employee { private Integer id; private String lastName; private String email; private Integer gender;//0: female 1: Male private Department department; private Date birth; public Employee(Integer id, String lastName, String email, Integer gender, Department department) { this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; this.department = department; //Default creation date this.birth = new Date(); } }
-
Writing dao layers: DepartmentDao and EmployeeDao
DepartmentDao:
package com.dary.sweb.dao; import com.dary.sweb.pojo.Department; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.HashMap; import java.util.Map; //Department dao @Repository public class DepartmentDao { @Autowired //Simulate data in database private static Map<Integer, Department> departments = null; static { departments = new HashMap<Integer, Department>();//Create a department table departments.put(101,new Department(101,"Teaching Department")); departments.put(102,new Department(102,"Marketing Department")); departments.put(103,new Department(103,"Teaching and Research Department")); departments.put(104,new Department(104,"Operation Department")); departments.put(105,new Department(105,"Logistics Department")); } //Get all department information public Collection<Department> getDepartments(){ return departments.values(); } //Get department by id public Department getDepartmentById(Integer id){ return departments.get(id); } }
EmployeeDao:
package com.dary.sweb.dao; import com.dary.sweb.pojo.Department; import com.dary.sweb.pojo.Employee; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.HashMap; import java.util.Map; //Employee Dao @Repository public class EmployeeDao { //Simulate data in database private static Map<Integer,Employee> employees = null; //Department to which the employee belongs @Autowired private DepartmentDao departmentDao; static { employees = new HashMap<Integer, Employee>();//Create a department table employees.put(1001,new Employee(1001,"AA","1111111@qq.com",0,new Department(101,"Teaching Department"))); employees.put(1002,new Employee(1002,"BB","2222222@qq.com",1,new Department(102,"Marketing Department"))); employees.put(1003,new Employee(1003,"CC","3333333@qq.com",0,new Department(103,"Teaching and Research Department"))); employees.put(1004,new Employee(1004,"DD","4444444@qq.com",1,new Department(104,"Operation Department"))); employees.put(1005,new Employee(1005,"EE","5555555@qq.com",0,new Department(105,"Logistics Department"))); } //The primary key increases automatically! private static Integer initId = 1006; //Add an employee public void add(Employee employee){ if(employee.getId()==null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId())); employees.put(employee.getId(),employee); } //Query all employee information public Collection<Employee> getAll(){ return employees.values(); } //Query employee by Id public Employee getEmployeeById(Integer id){ return employees.get(id); } //Delete employee public void delete(Integer id){ employees.remove(id); } }
2. Home page implementation
Note: the static resources of all pages need to be taken over by thymeleaf@ {}
-
First write a config class: MyMvcConfig:
package com.dary.sweb.config; //Fully expand MVC import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); } }
-
Then modify the page code and import static resources
index.html:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" action="dashboard.html"> <img class="mb-4" th:src="@{img/bootstrap-solid.svg}" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label class="sr-only">Username</label> <input type="text" class="form-control" placeholder="Username" required="" autofocus=""> <label class="sr-only">Password</label> <input type="password" class="form-control" placeholder="Password" required=""> <div class="checkbox mb-3"> <label> th:text="#{login.username} </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm">chinese</a> <a class="btn btn-sm">English</a> </form> </body>
3. Page internationalization
3.1 preparation
First, uniformly set the encoding of properties in the IDEA!
Write an internationalization configuration file and extract the internationalization page messages that need to be displayed on the page. We can go to the login page to see what we need to write international configuration!
3.2 preparation of configuration file
1. We create a new i18n directory under the resources resource file to store the internationalization configuration files
2. Create a login Properties file and a login_zh_CN.properties; It is found that IDEA automatically identifies the internationalization operation we want to do; The folder has changed!
3. We can create a new file on it;
The following page pops up: let's add another one in English;
This is much faster!
4. Next, let's write the configuration. We can see another view under the idea;
In this view, we can directly add attributes by clicking the + sign; Let's create a new login Tip, you can see that there are three file boxes on the side for input
Let's add the content of the home page!
Then add other page contents in turn!
Then check our configuration file;
login.properties: default
login.btn=Sign in login.password=password login.remember=Remember me login.tip=Please login login.username=user name
english:
login.btn=Sign in login.password=Password login.remember=Remember me login.tip=Please sign in login.username=Username
chinese:
login.btn=Sign in login.password=password login.remember=Remember me login.tip=Please login login.username=user name
OK, the configuration file steps are completed!
3.3 research on the effectiveness of configuration file
Let's take a look at SpringBoot's automatic configuration of internationalization! Another class is involved here: MessageSourceAutoConfiguration
There is a method. It is found that SpringBoot has automatically configured the component ResourceBundleMessageSource for managing our international resource files;
// Get the value passed from properties to judge @Bean public MessageSource messageSource(MessageSourceProperties properties) { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); if (StringUtils.hasText(properties.getBasename())) { // Set the basic name of the internationalization file (excluding the language country code) messageSource.setBasenames( StringUtils.commaDelimitedListToStringArray( StringUtils.trimAllWhitespace(properties.getBasename()))); } if (properties.getEncoding() != null) { messageSource.setDefaultEncoding(properties.getEncoding().name()); } messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale()); Duration cacheDuration = properties.getCacheDuration(); if (cacheDuration != null) { messageSource.setCacheMillis(cacheDuration.toMillis()); } messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat()); messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage()); return messageSource; }
Our real situation is that it is placed in the i18n directory, so we need to configure the path of messages;
spring.messages.basename=i18n.login
3.4 configure page internationalization value
Go to the page to get the internationalization value, check the Thymeleaf document, and find the message value. The operation is: #{...}. Let's go to the page test:
IDEA also has tips, very intelligent!
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" > <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" action="dashboard.html"> <img class="mb-4" th:src="@{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> <label class="sr-only">Username</label> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only">Password</label> <input type="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" > [[#{login.remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" >[[#{login.btn}]]</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm">chinese</a> <a class="btn btn-sm">English</a> </form> </body> </html>
But we want better! You can automatically switch between Chinese and English according to the button!
3.5 configuration internationalization analysis
There is information in the internationalization area of Spring E; There is a parser called LocaleResolver (get area information object)!
Let's go to our webmvc automatic configuration file and look for it! See the default configuration of SpringBoot:
@Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.mvc", name = "locale") public LocaleResolver localeResolver() { // If there is no self configuration in the container, use the user configuration if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this.mvcProperties.getLocale()); } // Receiver header internationalization decomposition AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(this.mvcProperties.getLocale()); return localeResolver; }
There is a method in the AcceptHeaderLocaleResolver class
public Locale resolveLocale(HttpServletRequest request) { Locale defaultLocale = this.getDefaultLocale(); // The default is to obtain the Locale for internationalization according to the regional information brought by the request header 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 { return defaultLocale != null ? defaultLocale : requestLocale; } } else { return requestLocale; } } }
If we want to click the link to make our international resources effective now, we need to make our own Locale effective!
Let's write our own LocaleResolver, which can carry regional information on the link!
Modify the jump connection of the front page:
<!-- The parameter passed in here does not need to be used? Use( key=value)--> <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">chinese</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
Let's write a component class for processing!
package com.dary.component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.LocaleResolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale; //You can carry area information on the link public class MyLocaleResolver implements LocaleResolver { //Parse request @Override public Locale resolveLocale(HttpServletRequest request) { String language = request.getParameter("l"); Locale locale = Locale.getDefault(); // If you don't get it, use the system default //If the request link is not empty if (!StringUtils.isEmpty(language)){ //Split request parameters String[] split = language.split("_"); //Country, region locale = new Locale(split[0],split[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } }
In order for our regionalized information to take effect, we need to configure this component again! Add bean s under our own mvcconfig;
@Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); }
We restart the project and visit it. We found that clicking the button can achieve successful switching! Finish!
Summary:
-
We need a configuration i18n file
-
If we need to perform automatic button conversion in the project, we need to customize a component LocaleResolver
-
Remember to configure the component written by yourself into the spring container @ Bean
-
#{}
4. Realization of login function
-
Modify index html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" > <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" th:action="@{/user/login}"> <img class="mb-4" th:src="@{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 msg If the value of is empty, no message is displayed--> <p style="color: red" th:text="${msg}" th:if="@{not #string.isEmpty(msg)}"></p> <label class="sr-only">Username</label> <input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only">Password</label> <input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" > [[#{login.remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" >[[#{login.btn}]]</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">chinese</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a> </form> </body> </html>
-
Create a LoginController class under a controller
package com.dary.sweb.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class LoginController { @RequestMapping("/user/login") public String login(@RequestParam("username")String username, @RequestParam("password")String password, Model model){ //Specific business: if(!StringUtils.isEmpty(username) && "123456".equals(password)){ return "redirect:/main.html"; }else { //Tell the user that your login failed! model.addAttribute("msg","Wrong user name or password!"); return "index"; } } }
-
Add redirection in MyMvcConfig
package com.dary.sweb.config; //Fully expand MVC 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.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); registry.addViewController("/main.html").setViewName("dashboard"); } @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } }
5. Login interceptor
-
Create an Interceptor: LoginHandlerInerceptor
package com.dary.sweb.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's session Object loginUser = request.getSession().getAttribute("loginUser"); if(loginUser==null){//No login request.setAttribute("msg","No permission, please login first"); request.getRequestDispatcher("/index.html").forward(request,response); return false; }else { return true; }} }
-
Modify MyMvcConfig
package com.dary.sweb.config; //Fully expand MVC 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.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); registry.addViewController("/main.html").setViewName("dashboard"); } @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()). addPathPatterns("/**"). excludePathPatterns("/index.html","/","/user/login","/css/*","/js/**","/img/**"); } }
-
Modify index html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" > <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" th:action="@{/user/login}"> <img class="mb-4" th:src="@{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 msg If the value of is empty, no message is displayed--> <p style="color: red" th:text="${msg}" th:if="@{not #string.isEmpty(msg)}"></p> <label class="sr-only">Username</label> <input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only">Password</label> <input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" > [[#{login.remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" >[[#{login.btn}]]</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">chinese</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a> </form> </body> </html>
6. Show employee list
-
Extract public pages
-
If you want to pass parameters, you can directly use () to pass parameters and accept judgment!
-
-
List circular display
-
First create a common package under templates, and then create a new common Html is used to store the public display interface
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" > <!--Head navigation bar--> <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar"> <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> [[${session.loginUser}]]</a> <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> <ul class="navbar-nav px-3"> <li class="nav-item text-nowrap"> <a class="nav-link" href="http://getbootstrap. COM / docs / 4.0 / examples / Dashboard / # "> sign out</a> </li> </ul> </nav> <!--sidebar --> <nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column"> <li class="nav-item"> <a th:class="${active=='main.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"> <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path> <polyline points="9 22 9 12 15 12 15 22"></polyline> </svg> home page <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path> <polyline points="13 2 13 9 20 9"></polyline> </svg> Orders </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"> <circle cx="9" cy="21" r="1"></circle> <circle cx="20" cy="21" r="1"></circle> <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path> </svg> Products </a> </li> <li class="nav-item"> <a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"> <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path> <path d="M16 3.13a4 4 0 0 1 0 7.75"></path> </svg> Employee management </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bar-chart-2"> <line x1="18" y1="20" x2="18" y2="10"></line> <line x1="12" y1="20" x2="12" y2="4"></line> <line x1="6" y1="20" x2="6" y2="14"></line> </svg> Reports </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"> <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon> <polyline points="2 17 12 22 22 17"></polyline> <polyline points="2 12 12 17 22 12"></polyline> </svg> Integrations </a> </li> </ul> <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted"> <span>Saved reports</span> <a class="d-flex align-items-center text-muted" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg> </a> </h6> <ul class="nav flex-column mb-2"> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Current month </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Last quarter </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Social engagement </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Year-end sale </a> </li> </ul> </div> </nav> </html>
-
Create a new EmployeeController class
package com.dary.sweb.controller; import com.dary.sweb.dao.EmployeeDao; import com.dary.sweb.pojo.Employee; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Collection; @Controller public class EmployeeController { //Call dao layer @Autowired EmployeeDao employeeDao; @RequestMapping("/emps") public String list(Model model){ Collection<Employee> employees = employeeDao.getAll(); model.addAttribute("emps",employees); return "emp/list"; } }
-
Create a new emp package under templates, and then list HTML in it
-
Modify dashboard HTML and list HTML, which optimizes the common part and displays the database content
dashboard.html:
<!DOCTYPE html> <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <div th:replace="~{common/commons::topbar}"></div> <div class="container-fluid"> <div class="row"> <!--Pass parameters to components--> <div th:replace="~{common/commons::sidebar(active='main.html')}"></div> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"> <div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"> <div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div> </div> <div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"> <div style="position:absolute;width:200%;height:200%;left:0; top:0"></div> </div> </div> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom"> <h1 class="h2">Dashboard</h1> <div class="btn-toolbar mb-2 mb-md-0"> <div class="btn-group mr-2"> <button class="btn btn-sm btn-outline-secondary">Share</button> <button class="btn btn-sm btn-outline-secondary">Export</button> </div> <button class="btn btn-sm btn-outline-secondary dropdown-toggle"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> This week </button> </div> </div> <canvas class="my-4 chartjs-render-monitor" id="myChart" width="1076" height="454" style="display: block; width: 1076px; height: 454px;"></canvas> </main> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js" ></script> <script type="text/javascript" src="asserts/js/popper.min.js" ></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js" ></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js" ></script> <script> feather.replace() </script> <!-- Graphs --> <script type="text/javascript" src="asserts/js/Chart.min.js" ></script> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'line', data: { labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], datasets: [{ data: [15339, 21345, 18483, 24003, 23489, 24092, 12034], lineTension: 0, backgroundColor: 'transparent', borderColor: '#007bff', borderWidth: 4, pointBackgroundColor: '#007bff' }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: false } }] }, legend: { display: false, } } }); </script> </body> </html>
list.html:
<!DOCTYPE html> <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <div th:replace="~{common/commons::topbar}"></div> <div class="container-fluid"> <div class="row"> <div th:replace="~{common/commons::sidebar(active='list.html')}"></div> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <h2>Section title</h2> <div class="table-responsive"> <table class="table table-striped table-sm"> <thead> <tr> <th>id</th> <th>lastName</th> <th>email</th> <th>gender</th> <th>department</th> <th>birth</th> <th>operation</th> </tr> </thead> <tbody> <tr th:each="emp:${emps}"> <td th:text="${emp.getId()}"></td> <td th:text="${emp.getLastName()}"></td> <td th:text="${emp.getEmail()}"></td> <td th:text="${emp.getGender()==0?'female':'male'}"></td> <td th:text="${emp.getDepartment().getDepartmentName()}"></td> <td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH::mm::ss')}"></td> <td> <button class="btn btn-sm btn-primary">edit</button> <button class="btn btn-sm btn-danger">delete</button> </td> </tr> </tbody> </table> </div> </main> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js"></script> <script type="text/javascript" src="asserts/js/popper.min.js"></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js"></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js"></script> <script> feather.replace() </script> <!-- Graphs --> <script type="text/javascript" src="asserts/js/Chart.min.js"></script> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'line', data: { labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], datasets: [{ data: [15339, 21345, 18483, 24003, 23489, 24092, 12034], lineTension: 0, backgroundColor: 'transparent', borderColor: '#007bff', borderWidth: 4, pointBackgroundColor: '#007bff' }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: false } }] }, legend: { display: false, } } }); </script> </body> </html>
7. Increase staff to achieve
-
Button submit
-
Jump to add page
-
Employee added successfully
-
Return to home page
-
Create an add. Under the emp package html
<!DOCTYPE html> <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <div th:replace="~{common/commons::topbar}"></div> <div class="container-fluid"> <div class="row"> <div th:replace="~{common/commons::sidebar(active='list.html')}"></div> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <form th:action="@{/emp}" method="post"> <div class="form-group"> <label>name</label> <input type="text" class="form-control" placeholder="dary" name="lastName"> </div> <div class="form-group"> <label>mail</label> <input type="email" class="form-control" placeholder="1234567456@qq.com" name="email"> </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gebder" value="1"> <label class="form-check-label">male</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gebder" value="0"> <label class="form-check-label">female</label> </div> </div> <div class="form-group"> <label>department</label> <select class="form-control" name="department.id"> <option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option> </select> </div> <div class="form-group"> <label>birthday</label> <input type="text" class="form-control" placeholder="2000/11/11" name="birth"> </div> <button class="btn btn-sm btn-success" type="submit">add to</button> </form> </main> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js"></script> <script type="text/javascript" src="asserts/js/popper.min.js"></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js"></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js"></script> <script> feather.replace() </script> <!-- Graphs --> <script type="text/javascript" src="asserts/js/Chart.min.js"></script> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'line', data: { labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], datasets: [{ data: [15339, 21345, 18483, 24003, 23489, 24092, 12034], lineTension: 0, backgroundColor: 'transparent', borderColor: '#007bff', borderWidth: 4, pointBackgroundColor: '#007bff' }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: false } }] }, legend: { display: false, } } }); </script> </body> </html>
-
Add jump operation in EmployeeController class
package com.dary.sweb.controller; import com.dary.sweb.dao.DepartmentDao; import com.dary.sweb.dao.EmployeeDao; import com.dary.sweb.pojo.Department; import com.dary.sweb.pojo.Employee; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Collection; @Controller public class EmployeeController { //Call dao layer @Autowired EmployeeDao employeeDao; @Autowired DepartmentDao departmentDao; @RequestMapping("/emps") public String list(Model model){ Collection<Employee> employees = employeeDao.getAll(); model.addAttribute("emps",employees); return "emp/list"; } @GetMapping("/emp") public String toAddpage(Model model){ Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("departments",departments); return "emp/add"; } @PostMapping("/emp") public String addEmp(Employee employee){ System.out.println("add"+employee); employeeDao.add(employee);//Save employee information //Add action return "redirect:/emps"; } }
8. Modify employee information
-
First, create a new update under the emp package html
<!DOCTYPE html> <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link th:href="@{/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <div th:replace="~{common/commons::topbar}"></div> <div class="container-fluid"> <div class="row"> <div th:replace="~{common/commons::sidebar(active='list.html')}"></div> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <form th:action="@{/updateEmp}" method="post"> <input type="hidden" name="id" th:value="${emp.getId()}"> <div class="form-group"> <label>name</label> <input th:value="${emp.getLastName()}" type="text" class="form-control" placeholder="dary" name="lastName"> </div> <div class="form-group"> <label>mail</label> <input th:value="${emp.getEmail()}" type="email" class="form-control" placeholder="1234567456@qq.com" name="email"> </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input th:checked="${emp.getGender()==1}" class="form-check-input" type="radio" name="gebder" value="1"> <label class="form-check-label">male</label> </div> <div class="form-check form-check-inline"> <input th:checked="${emp.getGender()==0}" class="form-check-input" type="radio" name="gebder" value="0"> <label class="form-check-label">female</label> </div> </div> <div class="form-group"> <label>department</label> <select class="form-control" name="department.id"> <option th:selected="${dept.getId()==emp.getDepartment().getId()}" th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option> </select> </div> <div class="form-group"> <label>birthday</label> <input th:value="${emp.getBirth()}" type="text" class="form-control" placeholder="2000/11/11" name="birth"> </div> <button class="btn btn-sm btn-success" type="submit">modify</button> </form> </main> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js"></script> <script type="text/javascript" src="asserts/js/popper.min.js"></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js"></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js"></script> <script> feather.replace() </script> <!-- Graphs --> <script type="text/javascript" src="asserts/js/Chart.min.js"></script> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'line', data: { labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], datasets: [{ data: [15339, 21345, 18483, 24003, 23489, 24092, 12034], lineTension: 0, backgroundColor: 'transparent', borderColor: '#007bff', borderWidth: 4, pointBackgroundColor: '#007bff' }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: false } }] }, legend: { display: false, } } }); </script> </body> </html>
-
Add modification page Jump in EmployeeController class
//Go to the employee modification interface @GetMapping("/emp/{id}") public String toUpdateEmp(@PathVariable("id")Integer id,Model model){ //Find out the original data Employee employee = employeeDao.getEmployeeById(id); model.addAttribute("emp",employee); Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("departments",departments); return "emp/update"; } @PostMapping("/updateEmp") public String updateEmp(Employee employee){ employeeDao.add(employee); return "redirect:/emps"; }
9. Deletion, 404 processing and cancellation
-
Modify list Delete statement in HTML
<a class="btn btn-sm btn-danger" th:href="@{/delemp/}+${emp.getId()}">delete</a>
-
Add the deletion function in the EmployeeController class
//Delete employee @GetMapping("/delemp/{id}") public String deleteEmp(@PathVariable("id")int id){ employeeDao.delete(id); return "redirect:/emps"; }
-
404: create an error package under templates and drag the 404 interface into it
-
Logout function:
-
Modify Commons Logout statement in HTML
<a class="nav-link" th:href="@{/user/logout}">cancellation</a>
-
Add logout interface conversion in LoginController class
@RequestMapping("/user/logout") public String logout(HttpSession session){ session.invalidate(); return "redirect:/index.html"; }
-
Summary: how to build a project quickly
-
Front end: what does the page look like, data
-
Design database (difficulties in database design)
-
The front-end allows him to run automatically and independently
-
How to connect data interfaces: json, object all in one
-
Front and rear end joint commissioning test
Backend template: X-admin