SpringBoot 一文复习知识点概览

目录

1、第一个SpringBoot程序

2、运行原理初探

2.1、pom.xml

2.2、启动器 spring-boot-starter

2.3、主启动类

2.4、注解

2.5、run方法流程分析

3、SpringBoot配置

3.1、yaml配置文件

3.2、JSR303数据校验

3.2.1、常见参数

3.3、多环境配置及配置文件优先顺序

3.4、自动配置原理再理解

4、SpringBoot Web开发

4.1、Web开发静态资源处理

4.2、首页如何定制

4.3、Thymeleaf模板引擎

5、员工系统设计

5.1、员工管理系统

5.2、聊聊如何写一个网站

5.3、回顾

6、整合

6.1、整合 JDBC

6.1.1、创建测试项目和测试数据

6.1.2、JDBCTemplate

6.1.3、编写 Controller 测试

6.2、整合 Druid

6.2.1、Druid简介

6.2.2、配置数据源

6.2.3、配置 Druid 数据源监控

6.3、整合 Mybatis

7、SpringSecurity

7.1、简介

7.2、环境搭建

7.3、用户认证和授权

7.4、注销及权限控制

演化过程:JavaWeb 使用原始独立开发的 MVC 三层架构开发网站,为了简化我们的开发流程使用了 SSM 框架,但是配置也开始复杂起来,并且我们的 war 包需要配置 Tomcat 运行使用,把 Spring 技术做出简化的 SpringBoot,它内嵌了 Tomcat 方便的实现了微服务架构。当我们的服务越来越多的时候,SpringCloud 它来了。

1、第一个SpringBoot程序

环境准备:

  • jdk 1.8
  • maven 3.6.1
  • springboot:最新版
  • IDEA

项目创建方式一:使用Spring Initializr 的 Web页面创建项目 官方:提供了一个快速生成的网站!

1、打开 https://start.spring.io/

2、填写项目信息

3、点击”Generate Project“按钮生成项目;下载此项目

4、解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。

5、如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。

项目创建方式二:使用 IDEA 直接创建项目

1、创建一个新项目

2、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现

3、填写项目信息

4、选择初始化的组件(初学勾选 Web 即可)

5、填写项目路径

6、等待项目构建成功

IDEA集成了这个网站

  • 可以直接在官网直接下载后,导入IDEA开发(告诉官网在哪儿)
  • 直接使用idea创建一个SpringBoot项目(一般还是在IDEA中进行创建开发)

2、运行原理初探

自动装配:

2.1、pom.xml

运行主要依赖一个父依赖,主要是管理项目的资源过滤及插件!

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

点进去将会看到还有个父依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
  • 这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;
  • spring-boot-dependencies : 核心依赖在父工程中!
  • 我们在写或者引入一些SpringBoot的依赖的时候,默认是不需要指定版本,就因为有这些版本仓库;但是如果导入的包没有在依赖中管理着就需要手动配置版本了。

2.2、启动器 spring-boot-starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
  • 启动器 : 说白了就是SpringBoot的启动场景;spring-boot-starter-XXX:就是spring-boot的场景启动器
  • 比如spring-boot-start-web,它就会帮我们自动导入web环境所有的依赖!
  • SpringBoot会将所有的功能场景,都变成一个个的启动类。
  • 我们要使用什么功能,就只需要找到相应的启动器,在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可。starter。我们未来也可以自己定义starter;

2.3、主启动类

//@SpringBootApplication : 标注这个类是一个SpringBoot的应用 : 启动类下的所有资源被导入
@SpringBootApplication
public class Springboot01HelloworldApplication {
    public static void main(String[] args) {
        //将SpringBoot应用启动
        SpringApplication.run(Springboot01HelloworldApplication.class, args);
    }
}

2.4、注解

@SpringBootConfiguration :   SpringBoot的配置
    @Configuration : Spring配置类
    @Component : 说明这也是一个Spring的组件
    
@EnableAutoConfiguration : 自动配置
    @AutoConfigurationPackage : 自动配置包
        @Import({AutoConfigurationPackages.Registrar.class}) : 自动装配`包注册`
    @Import({AutoConfigurationImportS、elector.class}) : 自动配置导入选择

//获取所有的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
  1. @SpringBootApplication

标注在某个类上说明这个类就是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

  1. @ComponentScan

在spring中很重要,它对应了xml配置中的元素。

作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。

  1. @SpringBootConfiguration

SpringBoot的配置类,标注在某个类上,表示这是一个SpringBoot的配置类;

点进这个注解后

这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

  1. @EnableAutoConfiguration

开启自动配置功能

以前我们需要配置的东西,而现在SpringBoot可以自动帮我们配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

获取候选的配置

@AutoConfigurationPackage:自动配置包

  1. spring.factories

META-INF/spring.factories : 自动配置的核心文件,这就是自动配置的根源所在!

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}
Properties proerties = PropertiesLoaderUtils.loadProperties(resource);
//所有的资源加载到配置类中!

结论:SpringBoot所有的自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!

  1. SpringBoot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值;
  2. 将这些自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置;
  3. 以前我们需要自动配置的东西,现在SpringBoot帮我们做了;
  4. 整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下;
  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
  6. 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有的组件;并自动配置,@Configuration,JavaConfig;
  7. 有了自动配置类,免去了我们手动编写配置文件的工作!

JavaConfig @Configuration @Bean

Docker : 进程

关于SpringBoot,谈谈你的理解

  • 自动装配
  • run()

2.5、run方法流程分析

3、SpringBoot配置

3.1、yaml配置文件

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

  • application.properties
    • 语法结构 :key=value
  • application.yml
    • 语法结构 :key:空格 value

配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;

yaml基础语法

说明:语法要求严格

    1. 空格不能省略。
    2. 以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
    3. 属性和值的大小写都是十分敏感的。

注意:

  • “ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;比如 :name: "kuang \n shen" 输出 :kuang 换行 shen
  • '' 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen
# properties 只能保存键值对!
# k=v
# 对空格的要求十分高
# 普通的key-value

# 注入到我们的配置类中
name: chatter

# 对象
student:
  name: chatter
  age: 3

# 行内写法
student: {name: code,age: 4}

# 数组
pets:
  - cat
  - dog
  - pig
pets: [cat,dog,pig]、

yaml可以直接给实体类赋值

/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
@Component //注册bean
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
}
person:
  name: chatter				#S{random.uuid} 随机uuid
  age: ${random.int}	# 随机int
  happy: false
  birth: 2019/3/9
  maps: {k1: v1,k2: v2}
  hello: haayy
  lists:
    - code
    - music
    - girl
  dog:
    name: ${person.hello:hello}_旺财
    age: 3

SpringBoot配置注解处理器找不到,需要导入依赖

<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

解决properties文件的中文乱码问题

总结:

  1. @ConfigurationProperties只需要写一次即可,@Value则需要每个字段都添加
  2. 松散绑定:比如我的yml中写的last-name,这个和lastName是一样的,-后面跟着的字母默认是大写的。这就是松散绑定。
  3. .yaml和.yml基本一致的,优先建议.yaml
  4. JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性
  5. 复杂类型的封装,yaml中可以封装对象,使用value就不会支持
  6. 配置yml和配置properties都可以获取到值 , 强烈推荐 yml;如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

3.2、JSR303数据校验

Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;

@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated  //数据校验
public class Person {

    @Email(message="邮箱格式错误") //name必须是邮箱格式
    private String name;
}

使用数据校验,可以保证数据的正确性;

3.2.1、常见参数

@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 Date 和 Calendar 对象是否在当前时间之前  
@Future     验证 Date 和 Calendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

.......等等
除此以外,我们还可以自定义一些数据校验规则

3.3、多环境配置及配置文件优先顺序

profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;

yaml文件的优先级顺序

多环境文件的配置的切换

  • 方式一:application.properties
#springboot的多环境配置:可以选择激活哪一个配置文件
spring.profiles.active=dev

  • 方式二:application.yaml
server:
  port: 8081
#选择要激活哪个环境块
spring:
  profiles:
    active: dev
---
server:
  port: 8082
spring:
  profiles: dev		#配置环境的名称

---
server:
  port: 8083
spring:
  profiles: test

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!

3.4、自动配置原理再理解

#配置文件到底能写什么? ----联系---- spring.factories;
#在我们这配置文件中能配置的东西,都存在一个固有的规律
#     xxxAutoConfiguration:默认值   xxxProperties  和 配置文件绑定  我们就可以使用自定义的配置了!
#可以通过debug: true来查看,哪些自动配置类生效,哪些没有生效!
#debug: true

一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类

精髓

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxAutoConfigurartion:自动配置类;给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

了解:@Conditional

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

4、SpringBoot Web开发

jar:webapp

自动装配

SpringBoot到底帮我们配置了什么?我们能不能进行修改?能修改什么东西?能不能扩展?

  • xxxxAutoConfiguration:向容器中自动配置组件
  • xxxxProperties:自动配置类,装配配置文件中自定义的一些内容!

要解决的问题:

  • 导入静态资源……
  • 首页
  • jsp,模块引擎Thymeleaf
  • 装配扩展SpringMVC
  • 增删改查
  • 拦截器
  • 国际化!

4.1、Web开发静态资源处理

SpringBoot最大的特点就是自动装配

如果我们是一个web应用,我们的main下会有一个webapp,我们以前都是将所有的页面导在这里面的,对吧!但是我们现在的pom呢,打包方式是为jar的方式,那么这种方式SpringBoot能不能来给我们写页面呢?当然是可以的,但是SpringBoot对于静态资源放置的位置,是有规定的!

我们先来聊聊这个静态资源映射规则:

SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfiguration 这个配置类里面;

我们可以去看看 WebMvcAutoConfigurationAdapter 中有很多配置方法;

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        // 已禁用默认资源处理
        logger.debug("Default resource handling disabled");
        return;
    }
    // 缓存控制
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
    // webjars 配置
    if (!registry.hasMappingForPattern("/webjars/**")) {
        customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                                             .addResourceLocations("classpath:/META-INF/resources/webjars/")
                                             .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
    // 静态资源配置
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    if (!registry.hasMappingForPattern(staticPathPattern)) {
        customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                                             .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                             .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
}

读一下源代码:比如所有的 /webjars/** , 都需要去 classpath:/META-INF/resources/webjars/ 找对应的资源;

什么是webjars呢?

Webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。

使用SpringBoot需要使用Webjars,我们可以去搜索一下:

网站:https://www.webjars.org

要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!

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

访问:只要是静态资源,SpringBoot就会去对应的路径寻找资源,我们这里访问:http://localhost:8080/webjars/jquery/3.4.1/jquery.js

第二种静态资源映射规则

以下四个目录存放的静态资源可以被我们识别:

"classpath:/META-INF/resources/"

"classpath:/resources/"

"classpath:/static/"

"classpath:/public/"

我们可以在resources根目录下新建对应的文件夹,都可以存放我们的静态文件;

比如我们访问 http://localhost:8080/1.js , 他就会去这些文件夹中寻找对应的静态资源文件;

自定义静态资源路径

我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties中配置;

spring.resources.static-locations=classpath:/coding/,classpath:/kuang/

一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了!

总结:

  1. 在SpringBoot,我们可以使用以下方式处理静态资源
    • webjars localhost:8080/webjars/
    • public,static,/**,resources localhost:8080/
  1. 优先级:resources > static(默认)> static

4.2、首页如何定制

访问 http://localhost:8080/ ,就会找静态资源文件夹下的 index.html

在我们上面的3个目录中任意一个;然后访问测试 http://localhost:8080/

网站图标说明

与其他静态资源一样,Spring Boot在配置的静态内容位置中查找 favicon.ico。如果存在这样的文件,它将自动用作应用程序的favicon。

注意:有的版本没有

1、关闭SpringBoot默认图标

#关闭默认图标 spring.mvc.favicon.enabled=false

2、自己放一个图标在静态资源目录下,我放在 public 目录下

3、清除浏览器缓存!刷新网页,发现图标已经变成自己的了!

4.3、Thymeleaf模板引擎

前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

jsp支持非常强大的功能,包括能写Java代码,但是呢,我们现在的这种情况,SpringBoot这个项目首先是以jar的方式,不是war,像第二,我们用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的

那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢?

SpringBoot推荐你可以来使用模板引擎:

模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,什么样一个思想呢我们来看一下这张图:

模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式。而这些值,从哪来呢,就是我们在后台封装一些数据。然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。

引入Thymeleaf

怎么引入呢,对于springboot来说,什么事情不都是一个start的事情嘛,我们去在项目中引入一下。给大家三个网址:

Thymeleaf 官网:https://www.thymeleaf.org/

Thymeleaf 在Github 的主页:https://github.com/thymeleaf/thymeleaf

Spring官方文档:找到我们对应的版本

https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter

找到对应的pom依赖:可以适当点进源码看下本来的包!

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

我们去找一下Thymeleaf的自动配置类:ThymeleafProperties

@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
}

我们可以在其中看到默认的前缀和后缀!

我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。

使用thymeleaf什么都不需要配置,只需要将他放在指定的文件夹下即可

要学习语法,还是参考官网文档最为准确,我们找到对应的版本看一下;

Thymeleaf 官网:https://www.thymeleaf.org/ , 简单看一下官网!我们去下载Thymeleaf的官方文档!

我们要使用thymeleaf,需要在html文件中导入命名空间的约束,方便提示。

我们可以去官方文档的#3中看一下命名空间拿来过来:

xmlns:th="http://www.thymeleaf.org"

@RequestMapping("/t2")
public String test2(Map<String,Object> map){
    //存入数据
    map.put("msg","<h1>Hello</h1>");
    map.put("users", Arrays.asList("qinjiang","kuangshen"));
    //classpath:/templates/test.html
    return "test";
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>狂神说</title>
</head>
<body>
<h1>测试页面</h1>

<div th:text="${msg}"></div>
<!--不转义-->
<div th:utext="${msg}"></div>

<!--遍历数据-->
<!--th:each每次遍历都会生成当前这个标签:官网#9-->
<h4 th:each="user :${users}" th:text="${user}"></h4>

<h4>
    <!--行内写法:官网#12-->
    <span th:each="user:${users}">[[${user}]]</span>
</h4>

</body>
</html>

在SpringBoot中,有非常多的xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了!

5、员工系统设计

5.1、员工管理系统

  1. 首页配置:注意点:
    1. 所有页面的静态资源都需要使用thymeleaf接管;
    2. url的href用@{}2.
  1. 页面国际化,注意点:
    1. 我们需要配置i18n文件
    2. 如果需要在项目中进行按钮自动切换(页面底部切换语言),我们需要自定义一个组件LocaleResolver
    3. 记得将自己写的组件配置到spring容器中 @Bean
    4. 要将File Encodings设置为UTF-8,不然全乱了。

    5. application.properties 中配置

    6. html 页面中的修改需要国际化显示内容进行使用 #{} 表示,例如:th:text="#{login.tip}"

其中按钮使用 th:value

  1. 登录+拦截器
  2. 员工列表展示
    1. 提取公共页面
      1. th:fragment="sidebar"
      2. th:replace="~{common/commons::topbar}
      3. 如果要传递参数,可以直接使用()传参,接收判断即可!
    1. 列表循环展示
  1. 添加员工
    1. 按钮提交
    2. 跳转到添加页面
    3. 添加员工成功
    4. 返回首页

注意:SpringBoot 默认的时间格式是 yyyy/MM/dd

更改默认格式使用

# 时间日期格式

spring.mvc.date-format=yyyy-MM-dd

  1. 修改、删除、404

5.2、聊聊如何写一个网站

前端

  • 模板:别人下号的,我们拿来改成自己需要的
  • 框架:组件:自己手动组合拼接。Bootstrap,Layui,semantic-ui,element-ui
    • 栅格系统
    • 导航栏
    • 侧边栏
    • 表单

网站总体的设计

  1. 前端搞定:页面长什么样子:数据
  2. 设计数据库 (数据库这集难点!)
  3. 前端让它能够自动运行,独立化工程
  4. 数据接口如何对接:json,对象 all in one!
  5. 前后端联调测试!

自己需要掌握的

  1. 有一套自己熟悉的后台模板:工作必要! 推荐:x-admin
  2. 前端界面:至少自己能够通过前端框架,组合出来一个网站页面
    • index
    • about
    • blog
    • post
    • user
  1. 让这个网站能够独立运行!(一个月)

5.3、回顾

上周:

  • SpringBoot是什么?
  • 微服务
  • HelloWorld-
  • 探究远吗~自动装配原理~
  • 配置yaml
  • 多文档环境切换
  • 静态资源映射
  • Thymeleaf th:xxx
  • SpringBoot 如何扩展 MVC javaconfig~
  • 如何修改SpringBoot的默认配置~
  • CRUD
  • 国际化
  • 拦截器
  • 定制首页,错误页~

这周:

  • JDSC
  • Mybatis :重点
  • Druid :重点
  • Shiro:安全 :重点
  • Spring Security :安全 :重点
  • 异步任务~,邮件发送,定时任务
  • Swagger
  • Dubbo + Zookeeper

6、整合

6.1、整合 JDBC

6.1.1、创建测试项目和测试数据

1、我去新建一个项目测试:springboot-data-jdbc ; 引入相应的模块!基础模块

2、项目建好之后,发现自动帮我们导入了如下 JDBC 和 MySQL 的启动器,我们还需要导入 web 的启动器以用来编辑 controller :

<!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--JDBC-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

3、编写yaml配置文件连接数据库:

spring:
  datasource:
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: yjx123

注意:我们需要关闭默认的 properties 文件,否则会出现错误。

4、配置完这一些东西后,我们就可以直接去使用了,因为SpringBoot已经默认帮我们进行了自动配置;去测试类测试一下:查看默认的数据源并检验数据库是否连接成功。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
        //查看一下默认的数据源 :class com.zaxxer.hikari.HikariDataSource :dbcp.springboot
        System.out.println(dataSource.getClass());
        //获得数据库连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //xxxx Template : SpringBoot已经配置好的模板bean,拿来即用 CRUD
        //jdbc
        //redis
        //关闭
        connection.close();
    }

}

结果:我们可以看到他默认给我们配置的数据源为 : class com.zaxxer.hikari.HikariDataSource , 我们并没有手动配置

我们来全局搜索一下,找到数据源的所有自动配置都在 :DataSourceAutoConfiguration文件:

@Import(
    {Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class}
)
protected static class PooledDataSourceConfiguration {
    protected PooledDataSourceConfiguration() {
    }
}

这里导入的类都在 DataSourceConfiguration 配置类下,可以看出 Spring Boot 2.2.5 默认使用HikariDataSource 数据源,而以前版本,如 Spring Boot 1.5 默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;

HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

可以使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。

关于数据源我们并不做介绍,有了数据库连接,显然就可以 CRUD 操作数据库了。但是我们需要先了解一个对象 JdbcTemplate

6.1.2、JDBCTemplate

1、有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;

2、即使不使用第三方的数据库操作框架,如 MyBatis等,Spring 本身也对原生的JDBC 做了轻量级的封装,即JdbcTemplate。

3、数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。

4、Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用

5、JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration 类

JdbcTemplate主要提供以下几类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。

6.1.3、编写 Controller 测试

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class JdbcController {

    @Autowired
    JdbcTemplate jdbcTemplate;

    //查询数据库的所有信息
    //没有实体类,数据库中的东西,怎么获取? Map
    @GetMapping("/userList")
    public List<Map<String,Object>> userList(){
        String sql = "select * from user";
        List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
        return list_maps;
    }

    @GetMapping("/addUser")
    public String addUser(){
        String sql = "insert into mybatis.user(id,name,pwd) values (5,'小王','123456')";
        jdbcTemplate.update(sql);
        return "addUser-ok";
    }

    @GetMapping("/updateUser/{id}")
    public String updateUser(@PathVariable("id") int id){
        String sql = "update mybatis.user set name=?,pwd=? where id=" + id;
        //封装
        Object[] objects = new Object[2];
        objects[0] = "小明";
        objects[1] = "hhhhhhh";
        jdbcTemplate.update(sql,objects);
        return "updateUser-ok";
    }

    @GetMapping("/deleteUser/{id}")
    public String deleteUser(@PathVariable("id") int id){
        String sql = "delete from mybatis.user where id = ?";
        jdbcTemplate.update(sql,id);
        return "deleteUser-ok";
    }
}

通过 http://localhost:8080/deleteUser/5 等请求测试结果

6.2、整合 Druid

6.2.1、Druid简介

Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。

Druid 已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

Github地址:https://github.com/alibaba/druid/

com.alibaba.druid.pool.DruidDataSource 基本配置参数如下:

配置

缺省值

说明

name

配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。
如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this)

jdbcUrl

连接数据库的url,不同数据库不一样。例如:
mysql : jdbc:mysql://10.20.153.104:3306/druid2
oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto

username

连接数据库的用户名

password

连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter

driverClassName

根据url自动识别

这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)

initialSize

0

初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时

maxActive

8

最大连接池数量

maxIdle

8

已经不再使用,配置了也没效果

minIdle

最小连接池数量

maxWait

获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。

poolPreparedStatements

false

是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。

maxOpenPreparedStatements

-1

要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100

validationQuery

用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。

testOnBorrow

true

申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。

testOnReturn

false

归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能

testWhileIdle

false

建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。

timeBetweenEvictionRunsMillis

有两个含义:
1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明

numTestsPerEvictionRun

不再使用,一个DruidDataSource只支持一个EvictionRun

minEvictableIdleTimeMillis

connectionInitSqls

物理连接初始化的时候执行的sql

exceptionSorter

根据dbType自动识别

当数据库抛出一些不可恢复的异常时,抛弃连接

filters

属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall

proxyFilters

类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

6.2.2、配置数据源

  1. 添加上 Druid 数据源依赖。
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>
  1. 切换数据源;之前已经说过 Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源,但可以 通过 spring.datasource.type 指定数据源。
spring:
  datasource:
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: yjx123
    type: com.alibaba.druid.pool.DruidDataSource
  1. 数据源切换之后,在测试类中注入 DataSource,然后获取到它,输出一看便知是否成功切换;

  1. 切换成功!既然切换成功,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码
spring:
  datasource:
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: yjx123
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  1. 导入Log4j 的依赖
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 现在需要程序员自己为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用 Spring Boot 的自动生成了;我们需要 自己添加 DruidDataSource 组件到容器中,并绑定属性;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DruidConfig {

    /*
       将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
       绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
       @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
       前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
     */
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

}
  1. 去测试类中测试一下;看是否成功!
@Test
void contextLoads() throws SQLException {
    //查看一下默认的数据源 :class com.zaxxer.hikari.HikariDataSource :dbcp.springboot
    System.out.println(dataSource.getClass());
    //获得数据库连接
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    //xxxx Template : SpringBoot已经配置好的模板bean,拿来即用 CRUD
    //jdbc
    //redis
    //关闭
    DruidDataSource druidDataSource = (DruidDataSource) dataSource;
    System.out.println("druidDataSource 数据最大连接数:" + druidDataSource.getMaxActive());
    System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize());
    connection.close();
}

输出结果 :可见配置参数已经生效!

6.2.3、配置 Druid 数据源监控

Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面。

所以第一步需要设置 Druid 的后台管理页面,比如 登录账号、密码 等;配置后台管理;

// 后台监控 : 相当于: web.xml ServletRegistrationBean
// 因为SpringBoot内置了 servlet 容器,所以没有 web.xml,替代方法:ServletRegistrationBean
@Bean
public ServletRegistrationBean statViewServlet(){
    ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    //后台需要有人登录,账号密码配置
    HashMap<String ,String> initParameters = new HashMap<>();
    //增加配置
    //登录的 key 是固定的 loginUsername、loginPassword
    initParameters.put("loginUsername","admin");
    initParameters.put("loginPassword","admin");
    //允许谁可以访问
    initParameters.put("allow","");
    //禁止谁能访问 initParameters.put("kuangshen","192.168.11.123");

    bean.setInitParameters(initParameters);//设置初始化参数
    return bean;
}

配置完毕后,我们可以选择访问 :http://localhost:8080/druid/login.html

进入之后

配置 Druid web 监控 filter 过滤器

//filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new WebStatFilter());
        //可以过滤哪些请求呢?
        HashMap<String,String> initParameters = new HashMap<>();
        //这些东西不能进行统计
        initParameters.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParameters);
        return bean;
    }

平时在工作中,按需求进行配置即可,主要用作监控!

6.3、整合 Mybatis

官方文档:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

Maven仓库地址:https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter/2.1.1

总体步骤:

    1. 导入包
    2. 配置文件
    3. mybatis 配置
    4. 编写 sql
    5. service 层调用 dao 层
    6. controller 调用 service 层
  1. 新建一个 SpringBoot 项目

  1. 导入 MyBatis 所需要的依赖
<!--mybatis-spring-boot-starter:整合 有文档-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
  1. 配置数据库连接信息(不变)
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=yjx123
  1. 测试数据库是否连接成功!
  2. 创建实体类,导入 Lombok!
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private int id;
    private String name;
    private String pwd;

}
  1. 创建mapper目录以及对应的 Mapper 接口
//这个注解表示了这是一个 mybatis 的 Mapper类 : Dao
@Mapper
@Repository
public interface UserMapper {

    List<User> queryUserList();

    User queryUserById(int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);

}
  1. 在 resources 下建 mybatis.mapper 包,在包下面编写 Mapper 接口对应的映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.UserMapper">
    <select id="queryUserList" resultType="User">
        select * from user;
    </select>

    <select id="queryUserById" resultType="User">
        select * from user where id = #{id};
    </select>

    <insert id="addUser" parameterType="User">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="User">
        update user set name=#{name},pwd=#{pwd} where id = #{id}
    </update>

    <delete id="deleteUser" parameterType="int">
        delete from user where id = #{id}
    </delete>

</mapper>
  1. 整合 Mybatis
# 整合 mybatis
mybatis.type-aliases-package=com.kuang.pojo
# classpath 相当于 resources,mybatis前面不能加/,否则到项目目录扫描
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
  1. 编写 Controller 并测试
@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/queryUserList")
    public List<User> queryUserList(){
        List<User> userList = userMapper.queryUserList();
        for (User user : userList){
            System.out.println(user);
        }
        return userList;
    }

    @GetMapping("/queryUserById/{id}")
    public User queryUserById(@PathVariable("id") int id){
        User user = userMapper.queryUserById(id);
        return user;
    }

    @GetMapping("/addUser")
    public String addUser(){
        userMapper.addUser(new User(5, "羊大", "12345"));
        return "addUser OK";
    }

    @GetMapping("/updateUser")
    public String updateUser(){
        userMapper.updateUser(new User(5,"大脑","123"));
        return "updateUser OK";
    }

    @GetMapping("/deleteUser/{id}")
    public String deleteUser(@PathVariable("id") int id){
        userMapper.deleteUser(id);
        return "Ok";
    }
}
  1. 启动项目访问进行测试

7、SpringSecurity

在 web 开发中,安全第一位!过滤器,拦截器~

做网站:安全应该在什么时候考虑?(设计之初~)

  • 漏洞,隐私泄露~
  • 架构一旦确定~

shiro、SpringSecurity:很像~除了类不一样,名字不一样;

认证,授权(vip1、vip2、vip3)

  • 功能权限
  • 访问权限
  • 菜单权限
  • ……拦截器,过滤器:大量的原生代码~冗余

MVC - SPRING - SPRINGBOOT - 框架思想

Aop:横切 - 配置类

7.1、简介

Spring Security 是针对 Spring 项目的安全框架,也是 SpringBoot 底层安全模块默认的技术选型,它可以实现强大的 Web 安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!

记住几个类:

  • WebSecurityConfigurerAdapter:自定义 Security 策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启 WebSecurity 模式,@EnableXXX开启某个功能

Spring Security 的两个主要目标是“认证”和“授权”(访问控制)。

“认证”(Authentication)

“授权”(Authorization)

这个概念是通用的,而不是只在 Spring Security 中存在。

参考官网:Spring Security,查看我们自己项目中的版本,找到对应的帮助文档:Spring Security Reference

7.2、环境搭建

  • 新建一个 SpringBoot 项目,选中 Spring Web 模块
  • 导入 Thymeleaf 模板包
<!--thymeleaf模板-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
  • 导入静态资源
  • 关闭模板引擎
# 关闭模板引擎
spring.thymeleaf.cache=false
  • 编写 Controller
@Controller
public class RouterController {

    @RequestMapping({"/","/index"})
    public String index(){
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "views/login.html";
    }

    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id){
        return "views/level1/" + id;
    }

    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id){
        return "views/level2/" + id;
    }

    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id){
        return "views/level3/" + id;
    }
}

7.3、用户认证和授权

  • 导入依赖
<!--security-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • 编写配置类
package com.kuang.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

//AOP: 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程
    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问, 功能也只有对应有权限的人才能访问
        //请求授权的规则~
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        //没有权限默认会到登录页面,需要开启登录的页面
            //login
        http.formLogin();
    }


    //认证,SpringBoot 2.1.x 可以直接使用~
    //密码编码:PasswordEncoder
    //在Spring Security 5.0+ 新增了很多的加密方式~
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这些数据征程应该从数据库中读
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }
}

7.4、注销及权限控制

  • 在配置类中开启注销功能
@Override
protected void configure(HttpSecurity http) throws Exception {
    //首页所有人可以访问, 功能也只有对应有权限的人才能访问
    //请求授权的规则~
    http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/level1/**").hasRole("vip1")
        .antMatchers("/level2/**").hasRole("vip2")
        .antMatchers("/level3/**").hasRole("vip3");

    //没有权限默认会到登录页面,需要开启登录的页面
    //login
    http.formLogin();

    //注销:开启了注销功能,跳到首页
    http.logout().logoutUrl("/");
    //或者: http.logout().logoutSuccessUrl("/");
}
  • index 前端页面进行注销跳转
<!--注销-->
<a class="item" th:href="@{/logout}">
    <i class="sign-out icon"></i> 注销
</a>
  • 在 Thymeleaf 里面可以写一些 Spring Security 的操作,导入整合包
<!--security-thymeleaf整合包-->
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>
  • index.html 页面导入命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org"
        xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
  • Thymeleaf 进行使用 SpringSecurity
<!--登录注销-->
<div class="right menu">
    <!--如果未登录-->
    <div sec:authorize="!isAuthenticated()">
        <a class="item" th:href="@{/toLogin}">
            <i class="address card icon"></i> 登录
        </a>
    </div>
    <!--如果已登录:用户名,注销-->
    <div sec:authorize="isAuthenticated()">
        <a class="item">
            用户名:<span sec:authentication="name"></span>
            <!--角色:<span sec:authentication="principal.getAuthorities()"></span>-->
        </a>
    </div>
    <div sec:authorize="isAuthenticated()">
        <a class="item" th:href="@{/logout}">
            <i class="sign-out icon"></i> 注销
        </a>
    </div>
    
</div>

注意:对于 SpringBoot 版本只支持2.0.9及以下的2.0.x。

  • SpringBoot 默认开启了防止网站攻击的功能,所以登录可能出现登录失败的原因
//防止网站攻击: get ,post
http.csrf().disable();//关闭csrf功能,登录失败可能存在的原因~

这样就可以在主界面显示登录后的用户名和注销图示,未登录不显示。

为了让各个 level 界面能够分配给不同的 vip 权限显示,可以在前端界面再进行使用 SpringSecurity 的设置

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值