Tag Archives: spring boot

Error parsing lifecycle processing instructions

Create a simple Maven project, modify pom.xml to add Spring Boot-related starter, as follows:

	<parent>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-parent</artifactId>
	    <version>1.5.9.RELEASE</version>
	</parent>
	<dependencies>
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web</artifactId>
	    </dependency>
	</dependencies>

This is the focus, but I found that I made a mistake when adding the Spring-boot-starter parent, with the following information: Error parsing processing instructions jump to definition in parent POm. Refer to the following figure:

Maybe maven got mad again. Using Alt +F5 to force update the maven project, it still reported an error. Finally, the jar package under the directory org/springframework/boot in the maven repository was deleted, and the error will not be reported when updating the maven project.

How to Fix Spring Boot OTS parsing error: Failed to convert WOFF 2.0

In order to facilitate the configuration in the project, often use the properties file save configuration information, project started, need to open maven filtering with the properties of the attribute value replace placeholders in the configuration file, for example, I used in the project of c3p0.. the properties file database connection information, so that every time I need to change the database connection information, only need to modify the c3p0. The properties of the file, Using the ${} read value in mybatis config. XML (see figure below), using maven’s Resource plug-in to turn Filtering on, replaces ${} in the XML file with the contents of Properties at compile time.


When I was using Spring Boot, all the files related to my page were placed in the SRC /resource/ directory. After starting the project, the icon of the page (font-awesome is used) could not be used. I have checked the official document and explained as follows: means that turning on The Filtering function using Maven’s Resource plug-in destroys files with binary content.
According to the official document needs to modify the configuration as follows (this project is an example) :

<resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>static/fonts/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>static/fonts/**</include>
                </includes>
            </resource>
        </resources>

Static directory part content:


After the project is compiled, the files will not be corrupted.

Springboot project startup exception – required a single bean, but 2 were found

springboot project startup exception – required a single bean, but 2 were found

    • description
    • detailed error message
    • error analysis
    • why
    • solution

    problem description

    springboot+mybatis, write interface and implementation classes, and use @autowired injection controller, start exception: required a single bean, but 2 were found

    controller interface:

    @RestController
    @RequestMapping("/api/sys/statistic")
    public class StatisticController {
    
        @Autowired
        private ISysAccessLogService iSysAccessLogService;
        
    }
    

    interface and implementation class

    detail error

    APPLICATION FAILED TO START
    Description:

    Field iSysAccessLogService in com.msb.sys.controller.StatisticController required a single bean, but 2 were found:
    – sysAccessLogServiceImpl: defined in file [/Users/ronghuilin/java/msbjava/target/classes/com/msb/sys/service/impl/SysAccessLogServiceImpl.class]
    – ISysAccessLogService: defined in file [/Users/ronghuilin/java/msbjava/target/classes/com/msb/sys/service/ISysAccessLogService.class]

    Action:

    Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

    Disconnected from the target VM, address: ‘127.0.0.1:61739’, transport: ‘socket’

    error analysis

    if you’re prompted, there’s no way to automatically inject iSysAccessLogService at StatisticController.

    @autowired is injected by type by default, and as prompted, my project has two beans of this type, so it cannot be injected automatically.

    The

    error message also suggests a solution:
    1. Use one of the beans with the @primary annotation as the default,
    2. Add @qualifier to the injected property to specify beanName to specify which bean

    to use

    but I’ve only written one implementation class for the interface, and as expected there’s only one bean, which should be fine.

    Reason

    after a roundabout search, I found that I had annotated springboot’s boot class with @mapperscan (” “com”).

    @mapperscan this is the annotation is the Mapper scan annotation for mybatis, and the scope of the scan I specified is the com package.
    mybatis scans the interface under com, generates the implementation class of the interface, and infuses it into spring.
    then spring scans the interface implementation class I wrote, injects spring, and you have two beans.

    solution

    in the springboot project it is recommended to add @mapper directly to the Mapper interface and not to use @mapperscan.

    if you want to use @mapperscan annotations, be careful to configure the scope of the scan to avoid the above problems caused by repeat scan injection of spring beans.

Failed to configure a DataSource: ‘ url’ attribute

Description:. Failed to configure a DataSource: ‘ url’ attribute is not specif:Reason: Failed to determine a suitable driver class

  • error cause: database not configured
  • solution:

error cause: database

is not configured

solution:

1.配置数据库

2. Set do not configure database

  • 1
  • 2
  • 3
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

 
 
  • 1

Idea has no code prompt solution when writing YML file

small white write springboot project, configuration yml file no code prompt, tried a lot of online methods, but did not find the answer, finally accidentally solved. I hope my method can help you.

I used idea2020, which should be updated. The yml file icon in 2020 has been changed, and there are no green leaves. The specific icon is like this.

if your icon looks like this, the software has recognized the yml file, but there is no code prompt, you need to download the yml plugin. Download plugins in setting.

Springboot integrated with mybatis

springBoot integration mybatis

#springBoot integration with the first mybatis project
1. Create a new normal maven project
2. Use idea’s easycode to automatically generate the controller, entity, service and dao layer code
3. Simple pom configuration, independent of error

  java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class tk.mybatis.spring.annotation.MapperScan.factoryBean()

依赖如下:
   <dependency>
       <groupId>org.mybatis.spring.boot</groupId>
       <artifactId>mybatis-spring-boot-starter</artifactId>  
       <version>2.1.0</version>
   </dependency>
    <dependency>
       <groupId>com.oracle</groupId>
       <artifactId>ojdbc6</artifactId>
       <version>11.2.0.4</version>
   </dependency>

4.  配置简单的yml,不配置会报找不到 

mybatis:
mapper-locations:类路径:mapper/* . xml

Failed to instantiate org.mybatis.spring.SqlSessionTemplate Constructor threw exception

2020-05-26 17:17:44.455 ERROR 752 --- [main] o.s.b.SpringApplication                  815 : Application startup failed org.springframework.beans.factory.Bean
CreationException: Error creating bean with name 'xxxMapperScannerConfigurer': Cannot create inner bean 'SqlSessionTemplate' of type [org.mybati
s.spring.SqlSessionTemplate] while setting bean property 'sqlSessionTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: E
rror creating bean with name 'SqlSessionTemplate#1': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanIns
tantiationException: Failed to instantiate [org.mybatis.spring.SqlSessionTemplate]: Constructor threw exception; nested exception is java.lang.NullPointerException
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:122)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1531)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1276)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
        at com.xxx.xxx.recall.rpc.Main.main(Main.java:35)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SqlSessionTemplate#1': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.mybatis.spring.SqlSessionTemplate]: Constructor threw exception; nested exception is java.lang.NullPointerException
...skipping...
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
        at com.xxx.xxx.recall.rpc.Main.main(Main.java:35)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SqlSessionTemplate#1': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.mybatis.spring.SqlSessionTemplate]: Constructor threw exception; nested exception is java.lang.NullPointerException
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:279)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
        ... 26 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.mybatis.spring.SqlSessionTemplate]: Constructor threw exception; nested exception is java.lang.NullPointerException
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:271)
        ... 31 more
Caused by: java.lang.NullPointerException
        at org.mybatis.spring.SqlSessionTemplate.<init>(SqlSessionTemplate.java:94)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
        ... 33 more

reason:

database JDBC link failed, check whether the user name and password are correct, I here because the password copy was wrong, resulting in.

Error: java.lang.IllegalArgumentExcept :Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required

conclusion: there was an error when the blogger was manually adding jar packages to the maven repository. The error was resolved by removing the dependent folder.

today to upload in ali cloud vod video, there is a jar package ali did not open source, need to manually introduced, when I was in the jar package is added to the maven, jar package name wrong, lead to the name of the folder and jar package name do not match, and then in the evening, there is a module was first started, to start the other modules, so the error, and then stop and then restart the start up of module, also not line, so I think it’s not code, after a search, see some people say that the JDK jar package might be the problem, I also touched the JDK and thought I had touched maven. Sure enough, once deleted, it was normal


Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eduChapterMapper' defined in file [F:\wmjava\guli_school\target\classes\com\wm\eduService\mapper\EduChapterMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1307)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
	... 33 common frames omitted
Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.util.Assert.notNull(Assert.java:201)
	at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122)
	at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73)
	at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790)
	... 43 common frames omitted

How to realize automatic assembly in springboot

spring boot itself is a framework that serves the spring framework. It can simplify configuration files, quickly build micro-blog applications, build tomcat built-in, and run directly without packaging deployment.
and one of the features I find most convenient is convention over configuration, which allows programmers to focus more on the business logic.
where EnableAntoConfiguration defaults to the dependent starter for automatic
springboot automatic assembly principle is :
1.Spring application.run implementation process has refreshContext(context), which internally parsed the label on our configuration class, and the annotation @enableantoconfiguration
2. Parses @ EnableAntoConfiguration this annotation of @ the configuration of the Import into class @ AntoConfigurationImportSelector
3. @ AntoConfigurationImportSelector. This class has methods SpringFactoriesLoder loadFactoryNames (getStringFactoriesLoaderFactoryClass (), getBeanClasLoader ()); The purpose is to read the meta-inf /spring.factories file
. Spring.factories file in the project in jarbao configure the Configuration class to be assembled automatically.

Spring boot thymeleaf crud implements simple functions of adding, deleting, modifying and querying

introduction

this article introduces a simple CRUD application using spring boot and Thymeleaf.

create Maven project

here to create a maven-based project using intellij community edition

overall architecture

Add Maven dependencies

database selected H2 lightweight database, convenient configuration, default configuration data written into memory, restart service lost, configuration data can be written to the file.

  <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.2.6.RELEASE</version>
  </parent>
  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-devtools</artifactId>
          <scope>runtime</scope>
      </dependency>
      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <scope>runtime</scope>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
      </dependency>
  </dependencies>

Domain layer
The

layer defines the entity class for data interaction. Here we define the Student class.

package com.springbootcrud.entity;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @NotBlank(message = "Name is mandatory")
    @Column(name = "name")
    private String name;

    @NotBlank(message = "Email is mandatory")
    @Column(name = "email")
    private String email;

    @Column(name = "phoneNo")
    private long phoneNo;

    public Student() {
    }

    public Student(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public long getPhoneNo() {
        return phoneNo;
    }

    public void setPhoneNo(long phoneNo) {
        this.phoneNo = phoneNo;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", phoneNo=" + phoneNo +
                '}';
    }
}

repository layer

is the persistence layer that interacts with the database. Here, the implementation of adding, deleting, modifying and checking entity classes in the database is specifically implemented. Here, we inherit the corresponding classes of the spring data framework instead of implementing the Dao layer implementation method by ourselves.

package com.springbootcrud.repository;

import com.springbootcrud.entity.Student;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {
    List<Student> findByName(String Name);
}

controller layer

this layer is responsible for processing the user’s input and returning the correct response back to the user.

package com.springbootcrud.controller;

import com.springbootcrud.entity.Student;
import com.springbootcrud.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;

@Controller
@RequestMapping("/students/")
public class StudentController {

    private final StudentRepository studentRepository;

    @Autowired
    public StudentController(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    @GetMapping("signup")
    public String showSignUpForm(Student student) {
        return "add-student";
    }

    @GetMapping("list")
    public String showUpdateForm(Model model) {
        System.out.println(studentRepository.findAll());
        model.addAttribute("students", studentRepository.findAll());
        return "index";
    }

    @PostMapping("add")
    public String addStudent(@Valid Student student, BindingResult result, Model model) {
        if (result.hasErrors()) {
            return "add-student";
        }

        studentRepository.save(student);
        return "redirect:list";
    }

    @GetMapping("edit/{id}")
    public String showUpdateForm(@PathVariable("id") final long id, Model model) {
        Student student = studentRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Invalid student Id:" + id));
        model.addAttribute("student", student);
        return "update-student";
    }

    @PostMapping("update/{id}")
    public String updateStudent(@PathVariable("id") long id, @Valid Student student, BindingResult result, Model model) {
        if (result.hasErrors()) {
            student.setId(id);
            return "update-student";
        }

        studentRepository.save(student);
        model.addAttribute("students", studentRepository.findAll());
        return "index";
    }

    @GetMapping("delete/{id}")
    public String deleteStudent(@PathVariable("id") long id, Model model) {
        Student student = studentRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid student id:" + id));
        studentRepository.delete(student);
        model.addAttribute("students", studentRepository.findAll());
        return "index";
    }

}

View layer

user sees the specific web page view, combined with Thymeleaf populated data, shown to the user

add-student.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Add User</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
    <!-- <link rel="stylesheet" href="../css/shards.min.css"> -->
</head>

<body>
    <div class="container my-5">
        <h3>Add Student</h3>
        <div class="card">
            <div class="card-body">
                <div class="col-md-10">
                    <form action="#" th:action="@{/students/add}" th:object="${student}" method="post">
                        <div class="row">
                            <div class="form-group col-md-8">
                                <label for="name" class="col-form-label">Name</label> <input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name"> <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
                            </div>
                            <div class="form-group col-md-8">
                                <label for="email" class="col-form-label">Email</label> <input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email"> <span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
                            </div>
                            <div class="form-group col-md-8">
                                <label for="phoneNo" class="col-form-label">Phone No</label> <input type="text" th:field="*{phoneNo}" class="form-control" id="phoneNo" placeholder="PhoneNo"> <span th:if="${#fields.hasErrors('phoneNo')}" th:errors="*{phoneNo}" class="text-danger"></span>
                            </div>
                            <div class="col-md-6">
                                <input type="submit" class="btn btn-primary" value="Add Student">
                            </div>
                            <div class="form-group col-md-8"></div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>

</html>

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Users</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
    <!-- <link rel="stylesheet" href="../css/shards.min.css"> -->
</head>

<body>
    <div class="container my-2">
        <div class="card">
            <div class="card-body">
                <div th:switch="${students}" class="container my-5">
                    <p class="my-5">
                        <a href="/students/signup" class="btn btn-primary"><i class="fas fa-user-plus ml-2"> Add Student</i></a>
                    </p>
                    <div class="col-md-10">
                        <h2 th:case="null">No Students yet!</h2>
                        <div th:case="*">
                            <table class="table table-striped table-responsive-md">
                                <thead>
                                    <tr>
                                        <th>Name</th>
                                        <th>Email</th>
                                        <th>Phone No</th>
                                        <th>Edit</th>
                                        <th>Delete</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr th:each="student : ${students}">
                                        <td th:text="${student.name}"></td>
                                        <td th:text="${student.email}"></td>
                                        <td th:text="${student.phoneNo}"></td>
                                        <td><a th:href="@{/students/edit/{id}(id=${student.id})}" class="btn btn-primary"><i class="fas fa-user-edit ml-2"></i></a></td>
                                        <td><a th:href="@{/students/delete/{id}(id=${student.id})}" class="btn btn-primary"><i class="fas fa-user-times ml-2"></i></a></td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

</body>
</html>

update-student.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Update User</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
    <!-- <link rel="stylesheet" href="../css/shards.min.css"> -->
</head>
<body>
    <div class="container my-5">
        <h3>Update Student</h3>
        <div class="card">
            <div class="card-body">
                <div class="col-md-8">
                    <form action="#" th:action="@{/students/update/{id}(id=${student.id})}" th:object="${student}" method="post">
                        <div class="row">
                            <div class="form-group col-md-6">
                                <label for="name" class="col-form-label">Name</label> <input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name"> <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
                            </div>
                            <div class="form-group col-md-8">
                                <label for="email" class="col-form-label">Email</label> <input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email"> <span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
                            </div>
                            <div class="form-group col-md-8">
                                <label for="phoneNo" class="col-form-label">Phone No</label> <input type="text" th:field="*{phoneNo}" class="form-control" id="phoneNo" placeholder="PhoneNo"> <span th:if="${#fields.hasErrors('phoneNo')}" th:errors="*{phoneNo}" class="text-danger"></span>
                            </div>
                            <div class="form-group col-md-8">
                                <input type="submit" class="btn btn-primary" value="Update Student">
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

run springboot application

program run entry.

package com.springbootcrud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

execution effect

Solution of redisconnection factory in springboot2 not Autowired

1. No redis package imported, then import the following jar package to solve

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. Do the project separation, so pay attention to the @component scanning scope of the Application startup class, default scanning of the Application startup class package and the beans under the subpackage.
is redis – common such as A project, A project of the package name is com.zhangsan.com mon. Redis. B project imports the JAR package of A project, the package name of B project is com. Zhangsan.service.B, then the Application start-up class of B project should be placed under com. Zhangsan, so as to load the beans of A project into A project.