1. Detailed explanation of SpringBoot
1. Initial Spring Boot
SpringBoot is a javaweb development framework
With the core idea of convention being greater than configuration, SpringBoot helps us make many settings by default, and most SpringBoot applications only need a small amount of Spring configuration. It integrates a large number of third-party library configurations
2. The first SpringBoot program
- You can create a project on https://start.spring.io/official website
- Create projects directly in idea (recommended)
- New project Spring Initializr.
- Spring Boot 2.7.7 (Spring Boot 3.0 uses Java 17 as minimum version)
- SDK version 1.8
- java version 8
- Create a controller at the same level as the project main program XXXApplication.java
Change the project port number:
Change server.port=8081 in the application.properties configuration file
Change the banner:
In the resources directory, create banner.txt, the content of which is the banner to be displayed
3. The principle of automatic assembly
3.1 pom.xml
- The spring-boot-dependencies core dependency is in the parent project
- When we introduce springboot dependencies, we don't need to specify the version, because the corresponding version number is configured in the pom of the parent project
3.2 Launcher
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
-
The starter is the startup scene of springboot
-
For example, spring-boot-starter-web helps us automatically import all dependencies in the web environment
-
springboot will turn all functional scenarios into starters
-
Starter https://docs.spring.io/spring-boot/docs/2.7.7/reference/html/using.html#using
3.3 Main program
//This annotation is required @SpringBootApplication public class SpringBoot01Application { public static void main(String[] args) { //Use this statement to start the springboot project SpringApplication.run(SpringBoot01Application.class, args); } }
annotation:
@SpringBootApplication @SpringBootConfiguration//configuration of springboot @Configuration//spring configuration class @Component//Description is a component @EnableAutoConfiguration//automatic configuration @AutoConfigurationPackage//auto-configuration package @Import({Registrar.class})//Import, automatically configure the internal class Registrar of this class @Import({AutoConfigurationImportSelector.class})//import, auto-configuration imports selector classes
The core configuration file for auto-configuration:
META-INF/spring.factories file under the jar package of spring-boot-autoconfigure-2.7.7 (deprecated in version 2.7)
SpringApplication does four things:
- Infer whether the type of application is a normal project or a web project
- Find and load all available initializers and set them in the initializers property
- Find all application listeners and set them to the listeners property
- Infer and set the definition class of the main method, and find the running main class
4. Yaml explanation
The global configuration file of springboot
- application.properties
- key=value
- application.yaml
- key: space value
server: port: 8080
#Ordinary key-value name: lisa #object student: name: lisa age: 3 #object inline student1: {name: lisa,age: 3} #array pets: - cat - dog - pig #Array inline writing pets1: [cat,dog,pig]
yaml can assign values to entity classes
Dog.java
@Component public class Dog { private String name; private int age; }
Person.java
@Component @ConfigurationProperties(prefix = "person") public class Person { private String name; private Integer age; private Boolean happy; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; }
application.yaml
person: name: lisa${random.uuid} age: 32 happy: false birth: 2013/2/3 maps: {k1: v1,k2: v2} lists: - code - music - read dog: name: Awang age: 3
test class
@SpringBootTest class Springboot02ConfigApplicationTests { @Autowired private Person person; @Test void contextLoads() { System.out.println(person); } }
5. Configuration file location
Configuration file reference configuration address: https://docs.spring.io/spring-boot/docs/2.7.7/reference/html/application-properties.html#appendix.application-properties
Where to place configuration files (in order of priority):
- file:./config/ (under the config folder under the project root directory)
- file:./ (under the project root directory)
- classpath:/config/ (under the config folder under the resources directory)
- classpath:/ (under the resources directory)
Mainly pay attention to XXXAutoConfiguration and XXXProperties, two kinds of files, refer to and configure in the configuration file
6. Spring Boot Web Development
6.1 Static resource import
source code:
public void addResourceHandlers(ResourceHandlerRegistry registry) { //If there is a custom configuration, the default path will fail if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/"); this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (this.servletContext != null) { ServletContextResource resource = new ServletContextResource(this.servletContext, "/"); registration.addResourceLocations(new Resource[]{resource}); } }); } }
Import method one (not recommended):
Use webjars
classpath:/META-INF/resources/
What is webjars: It means to introduce the jar package of the web in the form of maven, and the address /webjars/ is mapped to /META-INF/resources/webjars/ when accessing
Import method 2: (the static file 1.js is placed in the following directory, which can be accessed directly at http://localhost:8080/1.js)
classpath is the resources in the root directory of the project
- classpath:/resources/
- classpath:/static/
- classpath:/public/
6.2 Home page and icon customization
index.html in the static resource directory will be regarded as the home page
Pages under templates can only be accessed through the controller
-
When using files under templates, you need to use thymeleaf dependencies, otherwise an error will be reported
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
Icons are placed under the static folder
Introduce <link rel="icon" href="favicon.ico"> to web pages that require icons
6.3 thymeleaf template engine
Documentation: https://www.thymeleaf.org/documentation.html
Package needs to be imported before use
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
Secondly, you need to import the namespace xmlns:th="http://www.thymeleaf.org" in html
thymeleaf syntax
- Simple expression:
- Variable Expressions: ${...}
- Selection Variable Expressions: *{...}
- Message Expressions: #{...}
- Link URL Expressions: @{...}
- Fragment Expressions: ~{...}
- Literals
- Text literals: 'one text', 'Another one!',...
- Number literals: 0, 34, 3.0, 12.3,...
- Boolean literals: true, false
- Null literal: null
- Literal tokens: one, sometext, main,...
- Text operations:
- String concatenation: +
- Literal substitutions: |The name is ${name}|
- Arithmetic operations:
- Binary operators: +, -, *, /, %
- Minus sign (unary operator): -
- Boolean operations:
- Binary operators: and, or
- Boolean negation (unary operator): !, not
- Comparisons and equality:
- Comparators: >, <, >=, <= (gt, lt, ge, le)
- Equality operators: ==, != (eq, ne)
- Conditional operators:
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- Default: (value) ?: (defaultvalue)
<p>[[${msg}]]</p> <p th:text="${msg}"></p> <p th:utext="${msg}"></p> <h1 th:each="item:${list}" th:text="${item}"></h1> code reuse <div th:fragment="sidebar">a bunch of code</div>Define the sidebar, the code is located in file 1.html <div th:insert="~{1.html::sidebar}"></div>insert sidebar,The code is located in file 2.html
6.4 Extended MVC configuration
- Write a class annotated with @Configuration
- This class implements the WebMvcConfigurer interface
- And the @EnableWebMvc annotation cannot be marked
- The general configuration class is written under the config package
package com.daban.config; 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 { //View jump, jump to test page through kk request @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/kk").setViewName("test"); } }
7. Employee management system
7.1 Create a page to simulate database data
-
pojo.Department.java
-
package com.daban.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Department { private Integer id; private String departmentName; }
-
-
pojo.Employee.java
-
package com.daban.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; @Data @NoArgsConstructor public class Employee { private Integer id; private String lastName; private String email; private Integer gender; 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; this.birth = new Date(); } }
-
-
dao.DepartmentDao.java
-
package com.daban.dao; import com.daban.pojo.Department; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.HashMap; import java.util.Map; @Repository public class DepartmentDao { private static Map<Integer, Department> department = null; static { department = new HashMap<Integer, Department>(); department.put(101,new Department(101,"Education Department")); department.put(102,new Department(102,"Marketing Department")); department.put(103,new Department(103,"Department of Teaching and Research")); department.put(104,new Department(104,"Operations")); department.put(105,new Department(105,"logistics department")); } //Get all department information public Collection<Department> getDepartment(){ return department.values(); } //Get department by id public Department getDepartmentById(Integer id){ return department.get(id); } }
-
-
dao.EmployeeDao.java
-
package com.daban.dao; import com.daban.pojo.Department; import com.daban.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; @Repository public class EmployeeDao { private static Map<Integer, Employee> employees = null; @Autowired private DepartmentDao departmentDao; static { employees = new HashMap<Integer, Employee>(); employees.put(101,new Employee(1001,"AA","12345@qq.com",1,new Department(101,"Education Department"))); employees.put(102,new Employee(1002,"BB","12345@qq.com",0,new Department(102,"Marketing Department"))); employees.put(103,new Employee(1003,"CC","12345@qq.com",0,new Department(103,"Department of Teaching and Research"))); employees.put(104,new Employee(1004,"DD","12345@qq.com",1,new Department(104,"Operations"))); employees.put(105,new Employee(1005,"EE","12345@qq.com",0,new Department(105,"logistics department"))); } //primary key auto increment private static Integer initId = 1006; //add an employee public void addEmployee(Employee employee){ if(employee.getId()==null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId())); employees.put(employee.getId(),employee); } //Query all employees public Collection<Employee> getAll(){ return employees.values(); } //Query employees by id public Employee getEmployeeById(Integer id){ return employees.get(id); } //delete employee public void delete(Integer id){ employees.remove(id); } }
-
-
paging file
- https://github.com/twbs/bootstrap/releases/download/v5.3.0-alpha1/bootstrap-5.3.0-alpha1-examples.zip
- After downloading, unzip the dashboard and sign-in in the file
7.2 Home page
The home page uses the configuration class to do it
@Configuration public class MyMvcConfig implements WebMvcConfigurer { //view jump @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index").setViewName("index"); } }
7.3 Page internationalization (multilingual)
-
Create each language file
-
Create an i18n folder under the resources folder, and create three files in it
-
#Configure internationalization parameters in the global configuration file application.properties spring.messages.basename=i18n.login
-
#Create the following three files, and you can edit the three files synchronously in the Resource Bundle of the idea #login.properties login.signin=log in login.password=password login.remember=remember me login.tip=please login login.username=username #login_zh_CN.properties login.signin=sign in login.password=password login.remember=Remember me login.tip=please sign in login.username=username #login_en_US.properties login.signin=log in login.password=password login.remember=remember me login.tip=please login login.username=username
-
-
html file binding
-
Use #{} in the html file to bind the corresponding field
-
<h1 class="h3 mb-3 fw-normal" th:text="#{login.tip}">Please sign in</h1> <label for="floatingInput" th:text="#{login.username}">Username</label> <label for="floatingPassword" th:text="#{login.password}">Password</label> <button class="w-100 btn btn-lg btn-primary" type="submit" th:text="#{login.signin}">Sign in</button> <span th:text="#{login.remember}">Remember me</span>
-
-
Set Chinese and English switching buttons
-
<a class="btn btn-sm" th:href="@{/index(l='zh_CN')}">Chinese</a> <a class="btn btn-sm" th:href="@{/index(l='en_US')}">English</a>
-
-
Create a class MyLocaleResolver
-
package com.daban.config; import org.springframework.web.servlet.LocaleResolver; import org.thymeleaf.util.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale; public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest request) { String language = request.getParameter("l"); Locale locale = Locale.getDefault(); if(!StringUtils.isEmpty(language)){ String[] s = language.split("_"); locale = new Locale(s[0], s[1]); } return locale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { } }
-
-
Register in the MyMvcConfig class
-
For the MyMvcConfig class, see "6.4 Extended MVC Configuration"
-
@Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); }
-
7.4 Login function
login controller
package com.daban.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.thymeleaf.util.StringUtils; @Controller public class LoginController { @RequestMapping("/login") public String login(String username, String password, Model model){ System.out.println(username+password); if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){ model.addAttribute("msg","Username or password cannot be empty"); return "index"; } else if (username.equals("admin") && password.equals("123")){ session.setAttribute("loginUser",username); return "redirect:main.html"; }else { model.addAttribute("msg","The username or password entered is incorrect"); return "index"; } } }
address mapping
package com.daban.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.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MyMvcConfig implements WebMvcConfigurer { //view jump @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index").setViewName("index"); registry.addViewController("/main.html").setViewName("dashboard"); } //Custom internationalization takes effect @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } }
7.5 Login Interceptor
Write an interceptor class
package com.daban.config; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor 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","You are not logged in"); request.getRequestDispatcher("/index").forward(request,response); return false; }else { return true; } } }
Added in MyMvcConfig class
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") //Filter without passing through the interceptor .excludePathPatterns("/index","/","/login","/css/**","/js/**","/img/**"); }
7.6 Display employee list
1. Extract public pages
-
code reuse <div th:fragment="sidebar">a bunch of code</div>Define the sidebar, the code is located in file 1.html <div th:insert="~{1.html::sidebar}"></div>insert sidebar,The code is located in file 2.html or<div th:replace="~{1.html::sidebar}"></div>insert sidebar,The code is located in file 2.html
2. If you want to pass parameters
Use () to <div th:replace="~{1.html::sidebar(active="list.html")}"></div>
3. Use the passed parameters
<a th:class="${active=='list.html'?'nav-link active': 'nav-link'}"/>
means that if active==list.html, the class attribute is nav-link active, otherwise it is nav-link
4. List cycle display
<tr th:each="item:${emps}"> <td th:text="${item.getId()}"></td> <td th:text="${item.getLastName()}"></td> <td th:text="${item.getEmail()}"></td> <td th:text="${item.getGender()==0?'Female':'male'}"></td> <td th:text="${item.getDepartment().getDepartmentName()}"></td> <td th:text="${#dates.format(item.getBirth(),'yyyy-MM-dd')}"></td> <td> <a class="btn btn-sm btn-primary" th:href="">edit</a> <a class="btn btn-sm btn-danger" th:href="">delete</a> </td> </tr>
7.7 Adding staff
Main points:
-
In the global configuration file spring.mvc.format.date=yyyy/MM/dd, set the time format
-
The form field is an object, just pass the id
-
<div class="form-group"> <label>department</label> <select name="department.id" class="form-control"> <option th:each="item:${departments}" th:text="${item.getDepartmentName()}" th:value="${item.getId()}"> </option> </select> </div>
-
7.8 Modify employee information
Main points:
-
link passing parameters
-
<a class="btn btn-sm btn-primary" th:href="@{/toUpdate(id=${item.getId()})}">edit</a>
-
-
The data echo of the radio button
-
<input type="radio" th:checked="${emps.getGender()==0}" class="form-check-input" name="gender" value="0">
-
-
Drop-down box data echo
-
<select name="department.id" class="form-control"> <option th:selected="${item.getId() ==emps.getDepartment().getId()}" th:each="item:${departments}" th:text="${item.getDepartmentName()}" th:value="${item.getId()}"> </option> </select>
-
-
Form hidden field submission
-
<input type="hidden" th:value="${emps.getId()}" name="id" class="form-control">
-
7.9 Delete employee and 404
delete:
@RequestMapping("/delete") public String delete(Integer id){ //Employee employee = employeeDao.getEmployeeById(id); employeeDao.delete(id); return "redirect:/emps"; }
404:
The 404 function is to create an error folder in the templates directory, and place 404.html in it. Other 500s are similar
Logout:
@RequestMapping("/logout") public String logout(HttpSession session){ session.invalidate(); return "redirect:index"; }