springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\

1.创建项目

Bootstrap下载模板:https://getbootstrap.com/docs/4.5/examples/
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第1张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第2张图片
springboot
以下(不选-选填)
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第3张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第4张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第5张图片

2.hello初建

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 0:01
 */
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello cevent!";
    }
}


导入静态资源
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第6张图片
Springboot对静态资源的映射规则,所在位置
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第7张图片

3.、所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源

依赖链接地址:https://www.webjars.org/
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第8张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第9张图片
引入jQuery链接:localhost:8080/webjars/jquery/3.3.1/jquery.js

引入jQuery链接:localhost:8080/webjars/jquery/3.3.1/jquery.js

    org.webjars</groupId>
    jquery</artifactId>
    3.3.1</version>
</dependency>

4.SpringBoot对静态资源的映射规则

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第10张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第11张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第12张图片
localhost:8080/abc === 去静态资源文件夹里面找abc
访问路径:http://localhost:8080/asserts/js/Chart.min.js

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第13张图片
欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射;
访问:http://localhost:8080/
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第14张图片
springboot
所有的 **/favicon.ico 都是在静态资源文件下找
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第15张图片

5.模板引擎thymeleaf

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第16张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第17张图片
访问success页面配置

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
    <h1>request mapping 成功!</h1>
</body>
</html>


6.HelloController

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 0:01
 */
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello cevent!";
    }

    @RequestMapping("/success")
    public String success(){
        //默认跳转路径:classpath://templates/success.html
        return "success";
    }
}


springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第18张图片

7.引用thymeleaf获取属性

//查数据,页面显示,map的key对应页面的th:text=""key值,可索引到页面
@RequestMapping("/successdata")
public String thymeLeanData(Map<String , Object> map){
    map.put("hello","你好:cevent!");
    return "success";
}


【thymeleaf】

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
    <h1>request mapping 成功!</h1>
    <!--th:text=""将div中的文本内容,谁知为controller的预设map值,th:id="${hello}"可替换为动态值 -->
    <div id="div01" class="class01" th:id="${hello}" th:class="${hello}" th:text="${hello}">显示欢迎信息...</div>
</body>
</html>


springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第19张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第20张图片
【controller更改】

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.Map;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 0:01
 */
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello cevent!";
    }

    @RequestMapping("/success")
    public String success(){
        //默认跳转路径:classpath://templates/success.html
        return "success";
    }

    //查数据,页面显示,map的key对应页面的th:text=""key值,可索引到页面
    @RequestMapping("/successdata")
    public String thymeLeanData(Map<String , Object> map){
        map.put("hello","

你好:cevent!

"
); map.put("users", Arrays.asList("kk","MR","wz")); return "success"; } }

【thymeleaf属性】

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
    <h1>request mapping 成功!</h1>
    <!--th:text=""将div中的文本内容,谁知为controller的预设map值,th:id="${hello}"可替换为动态值 -->
    <div id="div01" class="class01" th:id="${hello}" th:class="${hello}" th:text="${hello}">显示欢迎信息...</div>
    <hr />
    <div th:text="${hello}">转译-字符串</div>
    <div th:utext="${hello}">不转译字符-h1</div>
    <hr />

    <!--th:each每次遍历都会生成当前标签:3个h4-->
    <!--/*@thymesVar id="users" type="ch"*/-->
    <h4 th:text="${user}" th:each="user:${users}"></h4>
    <hr/>
    <h5>
    <span th:each="user:${users}" >
        [[${user}]]
    </span>
    </h5>
</body>
</html>


8.开始项目-引入资源

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第21张图片

8.1.entity-employee

package com.cevent.springboot.web.entity;/**
 * Created by Cevent on 2020/7/8.
 */

import java.util.Date;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 15:24
 */
public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    //male:1 female:0
    private Integer gender;
    private Department department;
    private Date birth;

    public Employee() {
    }

    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 = birth;
    }

    public Integer getId() {
        return id;
    }

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

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

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

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + gender +
                ", department=" + department +
                ", birth=" + birth +
                '}';
    }
}


8.2entity-department

package com.cevent.springboot.web.entity;/**
 * Created by Cevent on 2020/7/8.
 */

/**
 * @author cevent
 * @description
 * @date 2020/7/8 15:23
 */
public class Department {
    private Integer id;
    private String deptNmme;

    public Department() {
    }

    public Department(Integer id, String deptNmme) {
        this.id = id;
        this.deptNmme = deptNmme;
    }

    public Integer getId() {
        return id;
    }

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

    public String getDeptNmme() {
        return deptNmme;
    }

    public void setDeptNmme(String deptNmme) {
        this.deptNmme = deptNmme;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", deptNmme='" + deptNmme + '\'' +
                '}';
    }
}


8.3dao-employeeDao

package com.cevent.springboot.web.dao;/**
 * Created by Cevent on 2020/7/8.
 */

import com.cevent.springboot.web.entity.Department;
import com.cevent.springboot.web.entity.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;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 15:20
 */
@Repository
public class EmployeeDao {

    private static Map<Integer, Employee> employees=null;

    @Autowired
    private DepartmentDao departmentDao;

    static {
        employees=new HashMap<Integer, Employee>();
        employees.put(2001, new Employee(2001, "E-AA", "[email protected]", 1, new Department(101, "D-AA")));
        employees.put(2002, new Employee(2002, "E-BB", "[email protected]", 1, new Department(102, "D-BB")));
        employees.put(2003, new Employee(2003, "E-CC", "[email protected]", 0, new Department(103, "D-CC")));
        employees.put(2004, new Employee(2004, "E-DD", "[email protected]", 0, new Department(104, "D-DD")));
        employees.put(2005, new Employee(2005, "E-EE", "[email protected]", 1, new Department(105, "D-EE")));
    }

    private static Integer initId=2020;

    public void save(Employee employee){
        if(employee.getId()==null){
            employee.setId(initId++);
        }

        employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
        employees.put(employee.getId(),employee);
    }

    public Collection<Employee> getAll(){
        return employees.values();
    }

    public Employee get(Integer id){
        return employees.get(id);
    }

    public void delete(Integer id){
        employees.remove(id);
    }
}


8.4dao-departmentDao

package com.cevent.springboot.web.dao;/**
 * Created by Cevent on 2020/7/8.
 */

import com.cevent.springboot.web.entity.Department;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 15:20
 */
@Repository
public class DepartmentDao {
    private static Map<Integer, Department> departments=null;

    static {
        departments=new HashMap<Integer, Department>();
        departments.put(101, new Department(101, "D-AA"));
        departments.put(102, new Department(102, "D-BB"));
        departments.put(103, new Department(103, "D-CC"));
        departments.put(104, new Department(104, "D-DD"));
        departments.put(105, new Department(105, "D-EE"));
    }

    public Collection<Department> getDepartments(){
        return departments.values();
    }

    public Department getDepartment(Integer id){
        return departments.get(id);
    }
}


8.5hello@Controller

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.Map;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 0:01
 */
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello cevent!";
    }

    @RequestMapping("/success")
    public String success(){
        //默认跳转路径:classpath://templates/success.html
        return "success";
    }

    //查数据,页面显示,map的key对应页面的th:text=""key值,可索引到页面
    @RequestMapping("/successdata")
    public String thymeLeanData(Map<String , Object> map){
        map.put("hello","

你好:cevent!

"
); map.put("users", Arrays.asList("kk","MR","wz")); return "success"; } //配置thymelead模板引擎自动加载的路径 {"/","/index.html"} 访问当前项目,或者访问路径都进入指定页面 /* @RequestMapping({"/","/index.html"}) public String index(){ return "index"; }*/ }

8.6@configuration

package com.cevent.springboot.web.config;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.*;

/** 全局配置类:继承WebMvcConfigurationSupport,可以扩展springMVC的方法
 * @author cevent
 * @description
 * @date 2020/7/8 14:53
 * @EnableWebMvc 启动后,springboot的springmvc自动配置全部失效
 * @Configuration 必须关闭才能不阻塞自动配置的index寻找路径,这里配置的跳转不能使用
 */
//@EnableWebMvc
@Configuration
public class MyMVCConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //super.addViewControllers(registry);
        //浏览器发送cevent请求,响应转发success页面
        registry.addViewController("/cevent").setViewName("success");
    }

    //全部组件跳转作用,@Bean
    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter=new WebMvcConfigurerAdapter(){
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
            }
        };

        return adapter;
    }
}


8.7 main-class解析器

package com.cevent.springboot.web;

import ch.qos.logback.core.net.SyslogOutputStream;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

import java.util.Locale;

@SpringBootApplication
public class SpringBoot09WebRestfulCrudApplication {

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

    //自动解析器
    @Bean
    public ViewResolver myNegotiateViewResolve(){
        System.out.println( "创建了视图解析器My Negotiation View Resolver!");
        return new MyNegotiateViewResolver();
    }

    private static class MyNegotiateViewResolver implements ViewResolver{

        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }

}


8.8 login.html

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第22张图片

<!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="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">
      <!-- Custom styles for this template -->
      <link  th:href="@{/asserts/css/signin.css}" rel="stylesheet">
   </head>

   <body class="text-center">
      <form class="form-signin" action="dashboard.html">
         <img class="mb-4" th:src="@{/asserts/img/yameng-logo.png}" alt="" width="150" height="150">
         <h1 class="h3 mb-3 font-weight-normal">亚盟后台管理系统</h1>
         <label class="sr-only">用户名</label>
         <input type="text" class="form-control" placeholder="用户名" required="" autofocus="">
         <label class="sr-only">密码</label>
         <input type="password" class="form-control" placeholder="密码" required="">
         <div class="checkbox mb-3">
            <label>
          <input type="checkbox" value="remember-me"> 保存账户/密码
        </label>
         </div>
         <button class="btn btn-lg btn-primary btn-block" type="submit">登陆</button>
         <p class="mt-5 mb-3 text-muted">© 2020</p>
         <a class="btn btn-sm">中文</a>
         <a class="btn btn-sm">English</a>
      </form>

   </body>

</html>


8.9 application.yml配置

application.yml配置
##配置了访问路径后,原自动访问路径取消
#spring:
#  resources:
#    static-locations: classpath://hello,classpath://cevent/

##修改项目名,th语法(thymeleaf)设置路径可以保证绝对路径正确
server:
  servlet:
    context-path: /ceventcrud


8.10 pom.xml配置

"1.0" encoding="UTF-8"?>
"http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4.0.0</modelVersion>
    
        org.springframework.boot</groupId>
        spring-boot-starter-parent</artifactId>
        2.3.1.RELEASE</version>
        /> <!-- lookup parent from repository -->
    </parent>
    com.cevent</groupId>
    spring-boot-09-web-restful-crud</artifactId>
    0.0.1-SNAPSHOT</version>
    spring-boot-09-web-restful-crud</name>
    Demo project for Spring Boot</description>

    
        .version>1.8</java.version>
    </properties>

    
        <!--引入web模块-->
        
            org.springframework.boot</groupId>
            spring-boot-starter-web</artifactId>
        </dependency>

        
            org.springframework.boot</groupId>
            spring-boot-starter-test</artifactId>
            test</scope>
            
                
                    org.junit.vintage</groupId>
                    junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--1.已进入jquery-webjars-->
        
            org.webjars</groupId>
            jquery</artifactId>
            3.3.1</version>
        </dependency>
        <!--2.引入模板引擎-->
        
            org.springframework.boot</groupId>
            spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--3.引入bootstap-->
        
            org.webjars</groupId>
            bootstrap</artifactId>
            4.5.0</version>
        </dependency>


    </dependencies>

    
        
            
                org.springframework.boot</groupId>
                spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


9.启动报错注意,调整controller和configuration

2020-07-08 16:36:46.199  INFO 20296 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-07-08 16:36:46.207  INFO 20296 --- [           main] .w.SpringBoot09WebRestfulCrudApplication : Started SpringBoot09WebRestfulCrudApplication in 1.129 seconds (JVM running for 2.267)
2020-07-08 16:36:48.596  INFO 20296 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-07-08 16:36:48.596  INFO 20296 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-07-08 16:36:48.599  INFO 20296 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
2020-07-08 16:36:48.606  WARN 20296 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound             : No mapping for GET /
2020-07-08 16:36:49.390  WARN 20296 --- [nio-8080-exec-3] o.s.web.servlet.PageNotFound             : No mapping for GET /
2020-07-08 16:36:50.275  WARN 20296 --- [nio-8080-exec-4] o.s.web.servlet.PageNotFound             : No mapping for GET /
2020-07-08 16:37:42.231  WARN 20296 --- [nio-8080-exec-5] o.s.web.servlet.PageNotFound             : No mapping for GET /index
2020-07-08 16:37:47.185  WARN 20296 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound             : No mapping for GET /index.html

WebMvcConfigurerAdapter 与WebMvcConfigurationSupport区别(待补充)
实现:http://localhost:8080/ceventcrud/ 或者 http://localhost:8080/ceventcrud/login.html
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第23张图片

10.idea自动识别国际化properties文件

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第24张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第25张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第26张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第27张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第28张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第29张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第30张图片
yml配置

##配置了访问路径后,原自动访问路径取消
#spring:
#  resources:
#    static-locations: classpath://hello,classpath://cevent/

##修改项目名,th语法(thymeleaf)设置路径可以保证绝对路径正确
server:
  servlet:
    context-path: /ceventcrud

##配置国际化
spring:
  messages:
    basename: i18n.login


去页面获取国际化的值

<!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="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">
      <!-- Custom styles for this template -->
      <link  th:href="@{/asserts/css/signin.css}" rel="stylesheet">
   </head>

   <body class="text-center">
      <form class="form-signin" action="dashboard.html">
         <img class="mb-4" th:src="@{/asserts/img/yameng-logo.png}" alt="" width="150" height="150">
         <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in YaMeng E-Commerce Manager</h1>
         <label class="sr-only" th:text="#{login.username}">Username</label>
         <input type="text" class="form-control" placeholder="用户名" required="" autofocus="">
         <label class="sr-only" th:text="#{login.password}">Password</label>
         <input type="password" class="form-control" placeholder="密码" required="">
         <div class="checkbox mb-3">
            <label>
          <input type="checkbox" value="remember-me" /> [[#{login.rememberme}]]
        </label>
         </div>
         <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.submit}">Sign in</button>
         <p class="mt-5 mb-3 text-muted">© 2020</p>
         <a class="btn btn-sm">中文</a>
         <a class="btn btn-sm">English</a>
      </form>

   </body>

</html>


11.排除浏览器乱码

11.1file-settings

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第31张图片

11.2全局默认配置file-other srttings,idea2020取消了other,这里可以这样设置

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第32张图片

11.3浏览器更改语言

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第33张图片
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第34张图片

11.4修改页面

<!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="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">
      <!-- Custom styles for this template -->
      <link  th:href="@{/asserts/css/signin.css}" rel="stylesheet">
   </head>

   <body class="text-center">
      <form class="form-signin" action="dashboard.html">
         <img class="mb-4" th:src="@{/asserts/img/yameng-logo.png}" alt="" width="150" height="150">
         <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in YaMeng E-Commerce Manager</h1>
         <label class="sr-only" th:text="#{login.username}">Username</label>
         <input type="text" class="form-control" placeholder="用户名" required="" autofocus="">
         <label class="sr-only" th:text="#{login.password}">Password</label>
         <input type="password" class="form-control" placeholder="密码" required="">
         <div class="checkbox mb-3">
            <label>
          <input type="checkbox" value="remember-me" /> [[#{login.rememberme}]]
        </label>
         </div>
         <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.submit}">Sign in</button>
         <p class="mt-5 mb-3 text-muted">© 2020</p>
         <a class="btn btn-sm" th:href="@{/login.html(l='zh_CH')}">中文</a>
         <a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
      </form>

   </body>

</html>


12.MyLocaleResolver

package com.cevent.springboot.web.component;
/*
 * Created by Cevent on 2020/7/8.
 */

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;

/** 链接上携带国家信息
 * @author cevent
 * @description
 * @date 2020/7/8 22:05
 */
public class MyLocaleResolver implements LocaleResolver {
    //解析国家信息
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String lang=request.getParameter("l");
        Locale locale=null;
        if(!StringUtils.isEmpty(lang)){
            String[] split=lang.split("_");
            locale=new Locale(split[0],split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}


13.MyMVCConfig

package com.cevent.springboot.web.config;/**
 * Created by Cevent on 2020/7/8.
 */

import com.cevent.springboot.web.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*;

/** 全局配置类:继承WebMvcConfigurationSupport,可以扩展springMVC的方法
 * @author cevent
 * @description
 * @date 2020/7/8 14:53
 * @EnableWebMvc 启动后,springboot的springmvc自动配置全部失效
 * @Configuration 必须关闭才能不阻塞自动配置的index寻找路径,这里配置的跳转不能使用
 */
//@EnableWebMvc
@Configuration
public class MyMVCConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //super.addViewControllers(registry);
        //浏览器发送cevent请求,响应转发success页面
        registry.addViewController("/cevent").setViewName("success");
    }

    //全部组件跳转作用,@Bean
    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter=new WebMvcConfigurerAdapter(){
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
            }
        };

        return adapter;
    }

    //语言配置
    @Bean
    public LocaleResolver localResolver(){
        return new MyLocaleResolver();
    }
}


14.运行报错Error:(1, 1) java: 非法字符: ‘\ufeff’

Error:(1, 10) java: 需要class, interface或enum

springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第35张图片
编辑器里右键remobe BOM
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第36张图片

15.登录拦截器

15.1设置页面post-action

<form class="form-signin" action="dashboard.html" th:action="@{user/login}" method="post"> 


15.2loginController

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 22:45
 */
@Controller
public class LoginController {

    //为简化SpringMVC写法
    //@RequestMapping(value="/user/login",method = RequestMethod.POST)
    @PostMapping(value = "/user/login")
    public String login(
            @RequestParam("username") String username,
            @RequestParam("password") String password,
            Map<String,Object> errorMap,
            HttpSession session //记录登录用户session
    ){
        if(!StringUtils.isEmpty(username) && "cevent".equals(password)){
            //记录数据传给LoginHandler
            session.setAttribute("loginUser",username);
            //防止重复提交,重定向
            //登录成功
            return "redirect:/main.html";
        }else{
            errorMap.put("msg","用户名/密码错误");
            return "login";
        }

    }
}


15.3loginHandlerInterceptor

loginHandlerInterceptor
package com.cevent.springboot.web.component;/**
 * Created by Cevent on 2020/7/8.
 */

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author cevent
 * @description
 * @date 2020/7/8 23:16
 */

/**
 * 登录检查拦截
 */
public class LoginHandlerIntecepter implements HandlerInterceptor {

    //目标方法执行之前,执行预检查
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        Object user=request.getSession().getAttribute("loginUser");
        if(user==null){
            //未登录,返回登录页面
                //未登录,存放错误消息
                request.setAttribute("msg","您没有权限进入后台,请先登录");
                request.getRequestDispatcher("/login.html").forward(request,response);

            return false;
        }else{
            return true;
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}


15.4mvcConfig

package com.cevent.springboot.web.config;/**
 * Created by Cevent on 2020/7/8.
 */

import com.cevent.springboot.web.component.LoginHandlerIntecepter;
import com.cevent.springboot.web.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*;

/** 全局配置类:继承WebMvcConfigurationSupport,可以扩展springMVC的方法
 * @author cevent
 * @description
 * @date 2020/7/8 14:53
 * @EnableWebMvc 启动后,springboot的springmvc自动配置全部失效
 * @Configuration 必须关闭才能不阻塞自动配置的index寻找路径,这里配置的跳转不能使用
 */
//@EnableWebMvc
@Configuration
public class MyMVCConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //super.addViewControllers(registry);
        //浏览器发送cevent请求,响应转发success页面
        registry.addViewController("/cevent").setViewName("success");
    }

    //全部组件跳转作用,@Bean
    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
                //模板引擎解析:添加视图重定向
                registry.addViewController("/main.html").setViewName("dashboard");


            }

            //注册拦截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                //拦截任意路径下的请求/**
                registry.addInterceptor(new LoginHandlerIntecepter()).addPathPatterns("/**")
                .excludePathPatterns("/login.html","/","/user/login");
            }
            //springboot已经做了静态资源映射,css、js自动拦截

        };

        return adapter;
    }

    //语言配置
    @Bean
    public LocaleResolver localResolver(){
        return new MyLocaleResolver();
    }
}


15.5login.html

login.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="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">
      <!-- Custom styles for this template -->
      <link  th:href="@{/asserts/css/signin.css}" rel="stylesheet">
   </head>

   <body class="text-center">
      <form class="form-signin" action="dashboard.html" th:action="@{/user/login}" method="post">
         <img class="mb-4" th:src="@{/asserts/img/yameng-logo.png}" alt="" width="150" height="150">
         <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in YaMeng E-Commerce Manager</h1>
         <!--重新编译页面代码:ctrl+f9 判断,msg不为空的时候才出现-->
         <label class="sr-only" th:text="#{login.username}">Username</label>
         <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
         <input type="text" class="form-control" name="username" placeholder="用户名" required="" autofocus="">
         <label class="sr-only" th:text="#{login.password}">Password</label>
         <input type="password" class="form-control" name="password" placeholder="密码" required="">
         <div class="checkbox mb-3">
            <label>
          <input type="checkbox" value="rememberme" /> [[#{login.rememberme}]]
        </label>
         </div>
         <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.submit}">Sign in</button>
         <p class="mt-5 mb-3 text-muted">© 2020</p>
         <a class="btn btn-sm" th:href="@{/login.html(l='zh_CH')}">中文</a>
         <a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
      </form>

   </body>

</html>


15.6 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 href="./asserts/css/bootstrap.min.css" th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">

      <!-- Custom styles for this template -->
      <link href="./asserts/css/dashboard.css" th:href="@{/asserts/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>
      <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
         <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>

      <div class="container-fluid">
         <div class="row">
            <nav class="col-md-2 d-none d-md-block bg-light sidebar">
               <div class="sidebar-sticky">
                  <ul class="nav flex-column">
                     <li class="nav-item">
                        <a class="nav-link active" 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-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>
                           Dashboard <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>
                 
                  </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>
                   
                  </ul>
               </div>
            </nav>

            <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>


16 员工列表

16.1 员工列表抽取顶部栏(dashboard)

<body>
   <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>


引用顶部栏(list)

<body>
   <!--引用topbar
   模板名:使用thymeleaf的前后缀配置规则进行解析
   -->
   <div th:insert="~{dashboard::topbar}"></div>


springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第37张图片
真正抽取

    <body>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="dashboard::topbar"></div>


侧边栏(dashboard)

<div class="container-fluid">
   <div class="row">
      <!--抽取侧边栏,除了fragment,也可以用选择器,添加id即可-->
      <nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="" id="sideBar">
         <div class="sidebar-sticky">


引入侧边栏

    <body>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="dashboard::topbar"></div>

      <div class="container-fluid">
         <div class="row">
            <!--引入侧边栏-->
            <div th:replace="~{dashboard::#sideBar}"></div>


16.2 引入片段的时候传入active点亮参数

(bar页面配置引入标签时的active)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--top 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-->
<!--抽取侧边栏,除了fragment,也可以用选择器,添加id即可-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="" id="sideBar">
    <div class="sidebar-sticky">
        <ul class="nav flex-column">
            <li class="nav-item">
                <!--实现动态高亮-->
                <a class="nav-link active"
                   th:class="${activeURI=='main.html'?'nav-link active':'nav-link'}"
                   href="#" th:href="@{/main.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>
                    Dashboard <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 class="nav-link active" th:href="@{/emps}" th:class="${activeURI=='emps'?'nav-link active':'nav-link'}" >
                    <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>
                    员工管理
                </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>

</body>
</html>


16.3Dashboard页面

<body>
   <!--1.引入commons-topbar-->
   <div th:replace="commons/bar::topbar"></div>

   <div class="container-fluid">
      <div class="row">
         <!--2.引入commons-sidebar-->
         <div th:replace="commons/bar::#sideBar(activeURI='main.html')"></div>


List页面

    <body>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="commons/bar::topbar"></div>

      <div class="container-fluid">
         <div class="row">
            <!--引入侧边栏-->
            <div th:replace="~{commons/bar::#sideBar(activeURI='emps')}"></div>


16.4引入员工列表

(1)employeeDao

//获取所有员工
public Employee get(Integer id){
    return employees.get(id);
}


(2)empController

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/9.
 */

import com.cevent.springboot.web.dao.EmployeeDao;
import com.cevent.springboot.web.entity.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 java.util.Collection;

/**
 * @author cevent
 * @description
 * @date 2020/7/9 21:15
 */
@Controller
public class EmployeeController {

    @Autowired
    EmployeeDao employeeDao;

    //1.查询所有员工,返回列表页面
    @GetMapping("/emps")
    public String empList(Model model){

        Collection<Employee> empsCollection= employeeDao.getAll();
        //将获取的员工信息,放在请求域中
        model.addAttribute("emps",empsCollection);

        //根据thymeleaf框架默认拼串: classpath:/templates/ "xxx" .html
        return "emps/list";
    }
}


(3)list

<!DOCTYPE html>
<!-- 引入th命名空间 -->
<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 href="../../static/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">

      <!-- Custom styles for this template -->
      <link href="../../static/asserts/css/dashboard.css" th:href="@{/asserts/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>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="commons/bar::topbar"></div>

      <div class="container-fluid">
         <div class="row">
            <!--引入侧边栏-->
            <div th:replace="~{commons/bar::#sideBar(activeURI='emps')}"></div>

            <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
               <h2>
                  <button class="btn btn-sm btn-success">员工添加</button>
               </h2>
               <div class="table-responsive">
                  <table class="table table-striped table-sm">
                     <thead>
                        <tr>
                           <th>员工ID</th>
                           <th>姓名</th>
                           <th>邮箱</th>
                           <th>性别</th>
                           <th>部门</th>
                           <th>生日</th>
                           <th>操作</th>
                        </tr>
                     </thead>

                     <!--更换tbody-->
                     <tbody>
                        <tr th:each="emp:${emps}">
                           <td th:text="${emp.id}"></td>
                           <td>[[${emp.lastName}]]</td>
                           <td th:text="${emp.email}"></td>
                           <!--判断显示,不推荐将REX写在大括号内-->
                           <!--<td th:text="${emp.gender==0?'女':'男'}"></td>-->
                           <td th:text="${emp.gender}==0?'女':'男'"></td>
                           <td th:text="${emp.department.deptNmme}"></td>
                           <!--格式化date-->
                           <td th:text="${#dates.format(emp.birth,'yyyy/MM/dd HH:mm:ss')}"></td>
                           <td>
                              <button class="btn btn-sm btn-primary">编辑</button>
                              <button class="btn btn-sm btn-danger">删除</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="../../static/asserts/js/jquery-3.2.1.slim.min.js"></script>
      <script type="text/javascript" src="../../static/asserts/js/popper.min.js"></script>
      <script type="text/javascript" src="../../static/asserts/js/bootstrap.min.js"></script>

      <!-- Icons -->
      <script type="text/javascript" src="../../static/asserts/js/feather.min.js"></script>
      <script>
         feather.replace()
      </script>

      <!-- Graphs -->
      <script type="text/javascript" src="../../static/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>


17.添加员工

17.1bootstrap获取静态表单

https://getbootstrap.com/docs/4.5/components/forms/
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第38张图片

<form>
  <div class="form-group">
    <label for="exampleFormControlInput1">Email address</label>
    <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="[email protected]">
  </div>
  <div class="form-group">
    <label for="exampleFormControlSelect1">Example select</label>
    <select class="form-control" id="exampleFormControlSelect1">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </select>
  </div>
  <div class="form-group">
    <label for="exampleFormControlSelect2">Example multiple select</label>
    <select multiple class="form-control" id="exampleFormControlSelect2">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </select>
  </div>
  <div class="form-group">
    <label for="exampleFormControlTextarea1">Example textarea</label>
    <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
  </div>
</form>


17.2添加页面add

添加页面add
	<!DOCTYPE html>
<!-- 引入th命名空间 -->
<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 href="../../static/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">

      <!-- Custom styles for this template -->
      <link href="../../static/asserts/css/dashboard.css" th:href="@{/asserts/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>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="commons/bar::topbar"></div>

      <div class="container-fluid">
         <div class="row">
            <!--引入侧边栏-->
            <div th:replace="~{commons/bar::#sideBar(activeURI='emps')}"></div>

            <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
               <h2 class="btn btn-sm btn-success"  >添加员工信息
               </h2>
               <form th:action="@{/emp}" method="post">
                  <div class="form-group">
                     <label >员工-姓名</label>
                     <!--name=jave bean de 定义name-->
                     <input name="lastName" type="text" class="form-control" id="exampleFormControlInput1" placeholder="cevent">
                  </div>
                  <div class="form-group">
                     <label >员工-邮箱</label>
                     <input name="email" type="email" class="form-control" id="exampleFormControlInput2" placeholder="[email protected]">
                  </div>
                  <div class="form-group">
                     <label >员工-性别</label>
                     <div class="form-check form-check-inline">
                        <input name="gender" value="1" class="form-check-input" type="radio"/>
                        <label class="form-check-label"></label>
                     </div>
                     <div class="form-check form-check-inline">
                        <input name="gender" value="0" class="form-check-input" type="radio"/>
                        <label class="form-check-label"></label>
                     </div>
                  </div>
                  <div class="form-group">
                     <label >所属-部门</label>
                     <!-- multiple全显示options <select multiple class="form-control" id="exampleFormControlSelect2"> -->
                     <select  class="form-control" name="department.id">
                        <!--提交为部门id-->
                        <option th:each="dept:${dept}" th:text="${dept.deptName}" th:value="${dept.id}"></option>
                     </select>
                  </div>
                  <div class="form-group">
                     <label >员工-生日</label>
                     <input name="birth" type="text" class="form-control" id="exampleFormControlInput3" placeholder="cevent">
                  </div>
                  <button type="submit" class="btn btn-primary">添加</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="../../static/asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
      <script type="text/javascript" src="../../static/asserts/js/popper.min.js" th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script>
      <script type="text/javascript" src="../../static/asserts/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script>

      <!-- Icons -->
      <script type="text/javascript" src="../../static/asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script>
      <script>
         feather.replace()
      </script>

   </body>

</html>


17.3empController

package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/9.
 */

import com.cevent.springboot.web.dao.DepartmentDao;
import com.cevent.springboot.web.dao.EmployeeDao;
import com.cevent.springboot.web.entity.Department;
import com.cevent.springboot.web.entity.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 java.util.Collection;

/**
 * @author cevent
 * @description
 * @date 2020/7/9 21:15
 */
@Controller
public class EmployeeController {

    @Autowired
    EmployeeDao employeeDao;
    @Autowired
    DepartmentDao departmentDao;

    //1.查询所有员工,返回列表页面
    @GetMapping("/emps")
    public String empList(Model model){

        Collection<Employee> empsCollection= employeeDao.getAll();
        //将获取的员工信息,放在请求域中
        model.addAttribute("emps",empsCollection);

        //根据thymeleaf框架默认拼串: classpath:/templates/ "xxx" .html
        return "emps/list";
    }

    //2.到添加员工页面
    @GetMapping("/emp")
    public String toAddEMPPage(Model model){
        //2.1先查出所有部门,页面显示再选择
        Collection<Department> depts=departmentDao.getDepartments();
        model.addAttribute("dept",depts);
        return "emps/add";
    }

    //3.员工添加,SpringMVC自动将请求参数(name)和入参对象的属性名(javaBean)进行一一绑定
    @PostMapping("/emp")
    public String addEMP(Employee employee){
        //打印add员工信息
        System.out.println("新建的员工信息:"+employee);

        //1.添加保存员工
        employeeDao.save(employee);

        //返回员工列表页面,redirect:重定向到地址,forward:转发到地址
        return "redirect:/emps";

    }

}


17.4日期格式yml配置

日期格式yml配置
##配置了访问路径后,原自动访问路径取消
#spring:
#  resources:
#    static-locations: classpath://hello,classpath://cevent/

##修改项目名,th语法(thymeleaf)设置路径可以保证绝对路径正确
server:
  servlet:
    context-path: /ceventcrud

##配置国际化,禁用模板引擎缓存thymeleaf.cache,指定日期格式mvc.format.date
#date-time: yyyy-MM-dd HH:mm:ss
spring:
  messages:
    basename: i18n.login
  thymeleaf:
    cache: false
  mvc:
    format:
      date: yyyy-MM-dd


18. 员工修改

18.1修改list页面

<!--更换tbody-->
<tbody>
   <tr th:each="emp:${emps}">
      <td th:text="${emp.id}"></td>
      <td>[[${emp.lastName}]]</td>
      <td th:text="${emp.email}"></td>
      <!--判断显示,不推荐将REX写在大括号内-->
      <!--<td th:text="${emp.gender==0?'女':'男'}"></td>-->
      <td th:text="${emp.gender}==0?'女':'男'"></td>
      <td th:text="${emp.department.deptName}"></td>
      <!--格式化date-->
      <td th:text="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm:ss')}"></td>
      <td>
         <a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.id}">编辑</a>
         <button class="btn btn-sm btn-danger">删除</button>
      </td>


带入员工id
springboot-web开发:restful增删改查:国际化-登录拦截,o.s.web.servlet.PageNotFound:No mapping for GET/java: 非法字符: ‘\_第39张图片

18.2修改add页面

修改add页面
<!DOCTYPE html>
<!-- 引入th命名空间 -->
<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 href="../../static/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">

      <!-- Custom styles for this template -->
      <link href="../../static/asserts/css/dashboard.css" th:href="@{/asserts/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>
      <!--引用topbar
      模板名:使用thymeleaf的前后缀配置规则进行解析
      -->
<!--      <div th:insert="~{dashboard::topbar}"></div>-->
      <div th:replace="commons/bar::topbar"></div>

      <div class="container-fluid">
         <div class="row">
            <!--引入侧边栏-->
            <div th:replace="~{commons/bar::#sideBar(activeURI='emps')}"></div>

            <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
               <!--区分员工修改/添加-->
               <h2 class="btn btn-sm btn-success"  th:text="${emp!=null?'修改员工信息':'新建员工'}">添加员工信息
               </h2>
               <form th:action="@{/emp}" method="post">
                  <!--发送put请求,修改员工数据-->
                  <!--
                  1.SpringMVC中配置HiddenHttpMethodFilter
                  2.页面创建post表单
                  3.页面创建input,name="_method"(代表新的请求方式),需要if判断员工!=null
                  4.不为空,获取emp的ID
                  -->
                  <input name="_method" value="put" type="hidden" th:if="${emp!=null}"/>
                  <input name="id" type="hidden" th:if="${emp!=null}" th:value="${emp.id}">
                  <div class="form-group">
                     <label >员工-姓名</label>
                     <!--name=jave bean de 定义name-->
                     <input name="lastName" type="text" class="form-control" id="exampleFormControlInput1"  th:value="${emp!=null}?${emp.lastName}">
                  </div>
                  <div class="form-group">
                     <label >员工-邮箱</label>
                     <input name="email" type="email" class="form-control" id="exampleFormControlInput2"  th:value="${emp!=null}?${emp.email}">
                  </div>
                  <div class="form-group">
                     <label >员工-性别</label>
                     <div class="form-check form-check-inline">
                        <input name="gender" value="1" class="form-check-input" type="radio" th:checked="${emp!=null}?${emp.gender==1}"/>
                        <label class="form-check-label"></label>
                     </div>
                     <div class="form-check form-check-inline">
                        <input name="gender" value="0" class="form-check-input" type="radio" th:checked="${emp!=null}?${emp.gender==0}"/>
                        <label class="form-check-label"></label>
                     </div>
                  </div>
                  <div class="form-group">
                     <label >所属-部门</label>
                     <!-- multiple全显示options <select multiple class="form-control" id="exampleFormControlSelect2"> -->
                     <select  class="form-control" name="department.id">
                        <!--提交为部门id-->
                        <option th:each="dept:${dept}" th:text="${dept.deptName}" th:value="${dept.id}" th:selected="${emp!=null}?${dept.id==emp.department.id}"></option>
                     </select>
                  </div>
                  <div class="form-group">
                     <!--使用dates工具-->
                     <label >员工-生日</label>
                     <input name="birth" type="text" class="form-control"  th:value="${emp!=null}?${#dates.format(emp.birth,'yyyy-MM-dd HH:mm:ss')}" />
                  </div>
                  <button type="submit" class="btn btn-primary" th:text="${emp!=null?'修改':'添加'}">添加</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="../../static/asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
      <script type="text/javascript" src="../../static/asserts/js/popper.min.js" th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script>
      <script type="text/javascript" src="../../static/asserts/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script>

      <!-- Icons -->
      <script type="text/javascript" src="../../static/asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script>
      <script>
         feather.replace()
      </script>

   </body>

</html>


18.3empController

empController
package com.cevent.springboot.web.controller;/**
 * Created by Cevent on 2020/7/9.
 */

import com.cevent.springboot.web.dao.DepartmentDao;
import com.cevent.springboot.web.dao.EmployeeDao;
import com.cevent.springboot.web.entity.Department;
import com.cevent.springboot.web.entity.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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;

import java.util.Collection;

/**
 * @author cevent
 * @description
 * @date 2020/7/9 21:15
 */
@Controller
public class EmployeeController {

    @Autowired
    EmployeeDao employeeDao;
    @Autowired
    DepartmentDao departmentDao;

    //1.查询所有员工,返回列表页面
    @GetMapping("/emps")
    public String empList(Model model){

        Collection<Employee> empsCollection= employeeDao.getAll();
        //将获取的员工信息,放在请求域中
        model.addAttribute("emps",empsCollection);

        //根据thymeleaf框架默认拼串: classpath:/templates/ "xxx" .html
        return "emps/list";
    }

    //2.到添加员工页面
    @GetMapping("/emp")
    public String toAddEMPPage(Model model){
        //2.1先查出所有部门,页面显示再选择
        Collection<Department> depts=departmentDao.getDepartments();
        model.addAttribute("dept",depts);
        return "emps/add";
    }

    //3.员工添加,SpringMVC自动将请求参数(name)和入参对象的属性名(javaBean)进行一一绑定
    @PostMapping("/emp")
    public String addEMP(Employee employee){
        //打印add员工信息
        System.out.println("新建的员工信息:"+employee);

        //1.添加保存员工
        employeeDao.save(employee);

        //返回员工列表页面,redirect:重定向到地址,forward:转发到地址
        return "redirect:/emps";

    }

    //4.修改员工页面
    @GetMapping("/emp/{id}")
    public String toEditPage(@PathVariable("id") Integer id,Model model){
        Employee employee=employeeDao.get(id);
        model.addAttribute("emp",employee);
        //页面显示部门列表
        Collection<Department> depts=departmentDao.getDepartments();
        model.addAttribute("dept",depts);

        //修改/添加通用add页面
        return "emps/add";
    }

    //5.更新员工数据
    @PutMapping("/emp")
    public String updateEMP(Employee employee){
        System.out.println("修改的员工数据");
        employeeDao.save(employee);
        return "redirect:/emps";

    }

}


你可能感兴趣的:(springboot,yml,maven)