目录
- 1. SpringBoot简介
- 2. SpringBoot框架web开发
- 2.1 SpringBoot集成Mybatis
- 2.2 SpringBoot下使用事务
- 2.3 SpringBoot常用注解
- 2.4 RESTFull风格
- 2.5 SpringBoot集成Redis
- 2.6 SpringBoot集成Dubbo分布式框架
- 2.7 集成Dubbo,Redis,MyBatis,Spring,SpringMVC,JSP
- 2.8 SpringBoot创建非web工程
- 2.9 修改工程的启动Logo
- 2.10 SpringBoot使用拦截器
- 2.11 SpringBoot使用Servlet(了解)
- 2.12 SpringBoot使用过滤器Filter
- 2.13 SpringBoot设置字符编码
- 2.14 SpringBoot打war包
- 2.15 SpringBoot打jar包
- 2.16 SpringBoot集成logback日志
- 3. Thymeleaf
- 4. 国际化与安全
- 5. Swagger
- 6. 任务
- 7. Dubbo + Zookeeper
1. SpringBoot简介
1.1 什么是SpringBoot
一个JavaWeb开发框架,和SpringMVC类似,相比其他JavaWeb框架的好处是简化开发,约定大于配置。SpringBoot完全抛弃了繁琐的xml配置过程,采用大量的默认配置简化了我们的开发过程。
1.2 SpringBoot的特性
- 能够快速创建基于Spring的应用程序
- 能够直接使用main方法启动内嵌的Tomcat服务器运行SpringBoot程序,不需要部署war包文件
- 提供约定的starter POM来简化Maven配置
- 自动化配置,根据项目的Maven依赖配置,SpringBoot自动配置Spring、SpringMVC等
- 基本完全不使用xml文件,采用注解配置
- 提供了程序的健康检查等功能
1.3 什么是微服务
微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合。
1.4 第一个SpringBoot程序
创建步骤
- 创建新项目
- 选择Spring Initializr
- 添加Spring Web
@SpringBootApplication注解用于开启spring配置,它会扫描下面的所有spring注解。
在pom文件中
SpringBoot项目代码必须放到Application类(启动入口类)所在的同级目录或下级目录
启动程序后,在网页中输入localhost:8080/hello,即可展示出hello
注:@ResponseBody的作用其实是将java对象转为json格式的数据。
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】。
在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
1.5 核心配置文件application.properties
一个SpringBoot项目中只能有一个核心配置文件
所有的配置,只要不使用默认值,通通都要在这个配置文件中设置
此时需要在网页输入 localhost:8081/springboot/xx方法,才能访问到xx方法
1.6 第二种核心配置文件application.yml或application.yaml
与application.properties效果相同,只不过格式不同
如果核心配置文件application.properties和application.yaml或application.yml同时存在,则会优先选择application.properties中的配置。properties优先级更高!
1.7 多环境下核心配置文件的使用
工作中开发的环境有:开发环境,测试环境,准生产环境,生产环境
在不同环境下,配置文件也不同,频繁修改会较复杂,因此采用调用的方式。
yml或yaml与properties类似,是创建application-dev.yml,application-test.yml,…
1.8 SpringBoot在application.properties中的自定义配置(@Value)
1.8.1 方式一:一个值一个值的获取
例如在核心配置文件中有如下自定义配置
在程序的任意位置可通过 @Value 注解进行获取,即每一个@Value得到一个值。
1.8.2 方式二:将自定义配置映射到一个对象
首先在配置文件定义如下自定义配置,两个对象,school和abc
然后分别创建两个对象所对应的类,下面列举school类
package com.liu.controller.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Controller;
@Controller // school类放进spring容器中进行管理
@ConfigurationProperties(prefix = "school") //将此类设置为配置类,并加上前缀,指明对象
public class school {
private String name;
private String website;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
}
然后便可通过注入(@Autowired)来使用这个对象
@Autowired
private school school; //从spring容器中取出school对象
@RequestMapping("/say") //设置这个方法的请求路径
@ResponseBody
public String say(){
return "say: Hello " + school.getName() + " " + school.getWebsite();
}
这种方式在运用时,自定义配置参数必须要有前缀,即a.b型。
注:解决使用@ConfigurationProperties注解出现的警告问题
<!-- 解决使用@ConfigurationProperties注解出现的警告问题-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
1.9 SpringBoot集成JSP
首先考虑jsp存放的位置,之前放哪,现在仍放哪。在main文件夹下建立webapp文件夹。然后在项目结构中设置web资源文件夹。设置完之后点击Artifact,然后应用。
SpringBoot官方推荐使用的前端页面是Thymeleaf,如果使用Thymeleaf就可以直接使用,如果使用其他的就要单独做集成,在pom文件中添加依赖
<!-- 引入SpringBoot内嵌tomcat对jsp的解析依赖 -->
<!-- 仅仅只是展示jsp页面,只添加以下一个依赖, 若是jstl等,则另加依赖 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
在build中添加resources
<!-- SpringBoot项目默认推荐使用的前端引擎是thymeleaf
现在我们要使用springboot集成jsp,需手动指定jsp最后编译的路径
而且springboot集成jsp编译jsp的路径是springboot规定好的位置:
META-INF/resources
-->
<resources>
<resource>
<!--源文件夹 -->
<directory>src/main/webapp</directory>
<!--指定编译到META-INF/resources -->
<targetPath>META-INF/resources</targetPath>
<!--指定源文件夹中的哪个资源要编译进行,这里是所有资源 -->
<includes>
<include>*.*</include>
</includes>
</resource>
</resources>
最后需要在application.properties中配置视图解析器
配置完成后,使用方式如下:
1.在webapp下新建一个jsp文件
2.在Controller中创建IndexController(方式一)
方式二
2. SpringBoot框架web开发
2.1 SpringBoot集成Mybatis
在pom文件中添加mybatis依赖,mysql驱动
<!--MySQL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- 可通过version设置版本号 -->
</dependency>
<!--MyBatis整合SpringBoot框架的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
一般情况下我们都需要书写这两个包
但现在可以不用写,采用MyBatis提供的逆向工程来生成实体bean,映射文件mapper,Dao接口。也就是根据数据库自动生成,非常方便。步骤如下:
- 在项目根目录下新建GeneratorMapper.xml文件
把如下内容填入进去(00处修改驱动所在位置,11处修改jdbc连接,22处修改包名,33处修改表名、实体类名)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 00-->
<!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径,也就是maven中的jdbc包 -->
<classPathEntry location="D:\all_Java_Environment\apache-maven-3.8.3\maven-repo\mysql\mysql-connector-java\8.0.28\mysql-connector-java-8.0.28.jar"/>
<!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
<context id="tables" targetRuntime="MyBatis3">
<!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 11 -->
<!-- 配置数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springboot"
userId="root"
password="root">
</jdbcConnection>
<!-- 22 实体类-->
<!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定
生成的 model 放在 eclipse 的哪个工程下面-->
<javaModelGenerator targetPackage="com.liu.pojo"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="false" />
</javaModelGenerator>
<!-- 22 Mapper.xml文件-->
<!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
<sqlMapGenerator targetPackage="com.liu.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 22 Mapper接口文件-->
<!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.liu.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 33-->
<!-- 数据库表名及对应的 Java 模型类名 (第一行前后两个分别是 表名 和 实体类名 )
数据库中有多少个表就要配对应数量的table
-->
<table tableName="t_student" domainObjectName="Student"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
- 在pom文件中添加一个插件
<!--mybatis 代码自动生成插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<!--配置文件的位置-->
<configurationFile>GeneratorMapper.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
- 双击生成
生成过后,Dao接口 StudentMapper:
映射文件StudentMapper:
2.1.1 SpringBoot整合Mybatis后实际操作小案例
通过网页输入id号,查询用户信息
操作步骤是控制层(Controller) -> 业务层(Service) -> Dao层(Mapper)
控制层:
需添加@Controller注解
通过alt + enter 键可以快速创建service包,并创建StudentService接口。在StudentService接口中仍通过alt + enter 键可以快速创建接口实现类,并实现对应方法。
业务层:
需添加@Service注解
可以发现在运用springboot之后,不需要再向以前一样通过getMapper获取mapper,而是直接通过注解注入的方式,然后直接调用方法即可!。
Dao层:
需添加@Mapper注解(或采取下面会提出的@MapperScan方式)
以上操作完成之后,还需在pom文件中添加resources。原因是main下的java文件夹中只解析java文件,xml文件由resources文件下进行解析,而规定的Mapper.xml文件必须与Dao接口放在一起,因此需要添加此步让java文件夹下的所有xml文件都得到解析。(这是第一种方式,后面还有第二种)
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
application.properties配置文件中设置连接数据库的信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver //数据库8.版本需要加上cj
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
运行即可进行测试。
Mapper接口这里要加@Mapper注解,service接口实现类这里要加@Service注解
可以对mapper包里的每一个接口都加一个@Mapper注解,也可以直接在启动入口类那里加一个总的注解 @MapperScan(basePackages = “com.liu.mapper”)
Mapper映射文件存放位置方式二
将java文件夹下的xml资源文件,放到resources下面的mapper文件夹(自己创建)
然后在application.properties中指定MyBatis映射文件(Mapper)的路径:
# 指定MyBatis映射文件的路径(这里面classpath:指的是resources文件夹)
# (下面这句话的意思就是resources文件夹下mapper文件夹下的所有.xml文件)
mybatis.mapper-locations=classpath:mapper/*.xml
# 下面这个也可以加上,关于别名的(后面是实体类路径)
mybatis.type-aliases-package=com.liu.pojo
2.1.2 总结
SpringBoot集成Mybatis,最主要的是两个注解@Mapper,@MapperScan
@Mapper 需要在每一个Mapper接口类上添加,作用是扫描Dao接口,放进spring容器中
@MapperScan 是在SpringBoot启动入口类上添加的,它是扫描所有的包
关于Mapper映射文件存放位置的写法有以下两种:
- 将Mapper接口和Mapper映射文件存放到src/main/java同一目录下,然后在pom文件中手动指定资源文件夹路径resources
- 将Mapper接口和Mapper映射文件分开存放,Mapper接口类存放到src/main/java目录下,Mapper映射文件存放到resources(类路径)目录下自己新建的mapper文件夹下,在application.properties中指定mapper映射文件的存放位置。
2.2 SpringBoot下使用事务
事务是一个完整的功能,也叫做一个完整的业务
事务只跟DML语句有关系:即增删改
使用事务功能只需要在相应方法上加上@Transactional注解就行了
Controller层
Service层
2.3 SpringBoot常用注解
@RestController
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
2.4 RESTFull风格
2.5 SpringBoot集成Redis
a.添加操作redis数据类型的依赖
在这里插入代码片<!-- SpringBoot集成Redis的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
b.在SpringBoot核心配置文件中添加redis的配置
// 设置redis配置信息,连接自己本机的redis
spring.redis.host=
spring.redis.port=
spring.redis.password=
设置完之后,在操作时是通过此语句进行数据操作
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
插入数据
取数据
2.6 SpringBoot集成Dubbo分布式框架
什么是Dubbo?
Dubbo是一款高性能、轻量级的开源Java RPC框架,他提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
相当于是几个工程间通信
首先需要创建三个工程
a. 接口工程:存放实体bean(即对象)和业务接口(建立一个maven工程,用于存放接口)
b.服务提供者:存放业务接口的实现类并将服务暴露且注册到注册中心,调用数据持久层(即Dao层也在服务提供者书写)(建立一个springboot工程,实现接口工程中的接口)
- 添加依赖:dubbo,注册中心(Zookeeper注册中心),接口工程
- 配置服务提供者的核心配置文件
c.服务消费者:处理浏览器客户端发送的请求,从注册中心调用服务提供者所提供的服务(即实现类)(建立一个springboot工程,是对业务的实现)
- 添加依赖:dubbo,注册中心,接口工程
- 配置服务消费者的核心配置文件
详细内容
- 在服务提供者pom文件中添加依赖
<!-- dubbo集成springboot框架起步依赖,dubbo主导 -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 注册中心 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- 接口工程,引入接口-->
<dependency>
<groupId>com.liu</groupId>
<artifactId>springboot-dubbo-interface</artifactId>
<version>1.0.0</version>
</dependency>
- 在服务提供者核心配置文件中配置信息
# 设置内嵌Tomcat端口号
server.port=8080
# 设置上下文根
server.servlet.context-path=/
# 设置dubbo的配置,这个name就是工程的名称
spring.application.name=springboot-dubbo-provider
# 当前工程是一个服务提供者
spring.dubbo.server=true
# 设置注册中心,最后的数字是已经打开的Zookeeper的端口号
spring.dubbo.registry=zookeeper://localhost:3306
- 在服务消费者中添加依赖,同服务提供者
- 在服务消费者核心配置文件中配置信息
# 设置内嵌Tomcat端口号
server.port=8080
# 设置上下文根
server.servlet.context-path=/
# 设置dubbo的配置
spring.application.name=springboot-dubbo-consumer
# 设置注册中心
spring.dubbo.registry=zookeeper://localhost:3306
基本流程是,先在服务消费者的controller包下创建一个StudentController类,然后调用一个Service层的方法,此方法的接口放在接口工程中的service包下,此方法的实现类放在服务提供者的service包下。
相关注解:
在服务提供者中,实现类需要加注解@Component 和@Service,从而将其放入注册中心
在服务消费者中,控制层类里面加注解@Reference,从而从注册中心中获取到服务提供者中实现的业务
在服务提供者和服务消费者的启动类前都要加注解@EnableDubboConfiguration
2.7 集成Dubbo,Redis,MyBatis,Spring,SpringMVC,JSP
前面知识的总和,还是三个工程
- 接口工程:存放实体类bean和业务接口(service的接口)
- 服务提供者:它是一个springboot框架web项目,集成mybatis,redis。说白了是存放业务接口实现类和mapper接口及mapper.xml文件
- 添加依赖:mybatis依赖,mysql驱动依赖,dubbo依赖,zookeeper依赖,redis依赖,接口工程
- 配置springboot核心配置文件
- 配置连接数据库
- 配置连接redis
- 配置dubbo
- 服务消费者:它是一个springboot框架web项目,集成jsp,dubbo。说白了就是存放控制层和jsp页面。
- 添加依赖:dubbo依赖,zookeeper依赖,解析jsp页面的依赖,接口工程
- 配置springboot核心配置文件
- 配置视图解析器
- 配置dubbo
2.8 SpringBoot创建非web工程
创建时不勾选spring web即可
非web工程无法按照原先从spring容器注入的方式直接操纵业务方法。只能采取如下方式。
方式一:
方式二:
实现CommandLineRuner,重写run方法。通过此方式可实现从spring容器中注入并操纵方法。
2.9 修改工程的启动Logo
在resource文件夹下新建一个 banner.txt ,把内容贴进去即可。
可以利用网站生成图标:链接
2.10 SpringBoot使用拦截器
a.定义一个拦截器,实现HandlerInterceptor接口
b.再创建一个配置类。(相当于原来的在springmvc配置文件中使用mvc:interceptors标签,只不过现在改成了配置类)
控制层测试代码:
@Controller
@RequestMapping(value = "/user") // 访问请求时统一带着此前缀
public class UserController {
//该请求不登陆也可访问
@RequestMapping(value = "/login")
public @ResponseBody Object login(HttpServletRequest request){
// 将用户的信息存放到session中
User user = new User();
user.setId(1001);
user.setName("zhangsan");
request.getSession().setAttribute("user",user);
return "login SUCCESS";
}
// 该请求需要用户登录之后才能访问
@RequestMapping(value = "/center")
public @ResponseBody Object center(){
return "See Center Message";
}
// 该请求不登陆也可访问
@RequestMapping(value = "/out")
public @ResponseBody Object out(){
return "Out";
}
// 该请求不登陆也可访问,如果用户未登录但访问了需要登录才能访问的请求,会跳转到此路径
@RequestMapping(value = "/error")
public @ResponseBody Object error(){
return "Error";
}
}
2.11 SpringBoot使用Servlet(了解)
原先方式:
- 创建一个servlet它要继承HttpServlet
- 在web.xml配置文件中使用servlet servlet-mapping
现在的方式:
方式一(Servlet类上加一个注解,入口启动类加一个注解):
- @WebServlet(urlPatterns = “”),
- @ServletComponentScan(basePackages = “”)
方式二:不使用注解,通过配置类的方式
2.12 SpringBoot使用过滤器Filter
也是有两种方式,与使用Servlet时的两种方式相同。
方式一:注解方式
在建立的filter类上使用注解@WebFilter(urlPatterns = “”), 并在启动类使用注解@ServletComponentScan(basePackages = “”)
方式二:不使用注解,通过配置类的方式
注意在书写过滤路径时,**不代表子包不会生效,单个*才代表子包。
2.13 SpringBoot设置字符编码
首先在servlet中设置浏览器的编码格式
然后在核心配置文件中添加如下内容,即可显示中文。
# 设置请求相应字符编码
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=utf-8
2.14 SpringBoot打war包
war包端口号和上下文根是以本地Tomcat为准,配置在核心配置文件的端口号和上下文根失效。
-
在.pom文件中加以下代码:
在gva坐标前写:<!--修改打包方式--> <packaging>war</packaging>
在build中写:
<!--指定打war包的字符, 名字可以自己来取--> <finalName>SpringBootWar</finalName>
在resources中写:
<resource> <!--源文件夹--> <directory>src/main/webapp</directory> <!--目标文件夹--> <targetPath>META-INF/resources</targetPath> <!--包含的文件--> <includes> <include>**/*.*</include> </includes> </resource> <!--mybatis 的 mapper.xml--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!--src/main/resources 下的所有配置文件编译到类路径classes 下面去--> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource>
-
在入口类中继承SpringBootServletInitializer类
-
在Meven中双击package即可
2.15 SpringBoot打jar包
jar包端口号和上下文根是springboot核心配置文件中设置的值。
定义了一个controller
定义了一个webapp,创建了一个jsp
核心配置文件中指定端口号、上下文根。配置视图解析器
在pom文件中自带打包插件这里加上这个版本号
同war,可指定包名
打包时别忘了配置resources加载到classes类路径
然后就可以在Maven中双击package进行打包了
将生成的.jar文件,可以放到任何位置,在搜索框打开cmd窗口,使用下面命令就可以执行。
java -jar 包名.jar
2.16 SpringBoot集成logback日志
在resources下新建文件 logback-spring.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为
TRACE < DEBUG < INFO < WARN < ERROR < FATAL,
如果设置为 WARN,则低于 WARN 的信息都不会输出 -->
<!--
scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为true
-->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认
单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。 -->
<!-- debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback
运行状态。默认值为 false。通常不打印 -->
<configuration scan="true" scanPeriod="10 seconds">
<!-- 1 输出到 控制台 -->
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<!--此日志 appender 是为开发使用,只配置最底级别, 控制台输出的日志级别是大
于或等于此级别的日志信息 此处定义的是以Debug为基准,但要看下面的root处的定义,root处的定义优先-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>%date [%-5p] [%thread] %logger{60} [%file : %line] %msg%n</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 2 日志输出到文件 下面File表示输出的文件位置,fileNamePattern可以把之前的打包-->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<File>/home/log/stdout.log</File>-->
<File>D:/log/stdout.log</File>
<encoder>
<pattern>%date [%-5p] %thread %logger{60} [%file : %line] %msg%n</pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 添加.gz 历史日志会启用压缩 大大缩小日志文件所占空间 -->
<!--<fileNamePattern>/home/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>-->
<fileNamePattern>D:/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory><!-- 保留 30 天日志 -->
</rollingPolicy>
</appender>
<!-- 单个定义 -->
<!-- 可以全局的对日志进行打印,也可以对特定的包进行日志打印,这里就是指定特定的包进行日志打印 -->
<logger name="com.liu.mapper" level="DEBUG" />
<!-- 全部定义 如果此处定义了则以全部的为准,如果没有的话则以单个的为准 -->
<!-- 上面写了两个附加器(输出到控制台和输出到文件),只有在这里引用才会有效果 -->
<!-- 根处这里定义的是以INFO为基准,即只有大于等于INFO的才会展示。
如果root中没有定义level的话,默认为debug
如果没有root话则以上面appender中定义的Debug为基准 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
在pom文件添加依赖:
<!-- 日志的依赖 -->
<!--@Slf4j 自动化日志对象-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
在某个类上直接写 @Slf4j 注解就可以直接使用了。根据logback-spring.xml指定的等级,显示出的日志内容也不同。
3. Thymeleaf
3.1 集成Thymeleaf
新建工程的时候,多勾选这个选项
建完项目后生成的pom文件中就会多一个依赖
使用:(注意:新建的html文件,要放到resources文件夹下的templates文件夹下)
在html文件中首部添加这么一句话,添加过之后才能从后台获取数据。
<html lang="en" xmlns:th="http://www.thymeleaf.org">
controller层代码为:
3.2 Thymeleaf实时更新页面
如果想实时更新界面,html内容一修改,刷新一下前端界面也直接跟着修改。而不用重启工程,则采用如下方式。
- 在核心配置文件中做如下配置:
# 设置thymeleaf模板引擎的缓存,设置为false关闭,默认为true开启
spring.thymeleaf.cache=false
- 做出如下更改
3.3 Thymeleaf表达式
3.3.1 标准变量表达式
语法:th:xxx = “${…}”
说明:标准变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和 EL表达式 中的 ${} 相同。Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据。
举例:
这种写法必须依托在 th: 开头。
3.3.2 选择变量表达式(星号表达式)
标准变量表达式和选择变量表达式还可以混合使用
3.3.3 路径表达式
语法:th:xxx=“@{}”
对于没有参数的举例(对于绝对路径:与传统方法基本没有区别,对于相对路径:路径表达式有优点)
对于有参数的举例:
在控制层设置参数值。
然后在从url页面跳转到别的页面时传递参数值。
若是RESTful风格,需采用字符串拼接的方式。由url.html跳转到test2.html格式如下。
对于其他应用场景下使用路径表达式,如js,img等
form表单
加th:与不加没有区别,所以一般可以不加,只有在从后台取值或要跳转路径时加上th:。
3.4 lombok @Data注解
如果实体类写完不想写get,set等等方法,只需要在实体类前加一个@Data注解,添加这个注解的前提条件是安装了lombok插件。并在pom文件中添加依赖:
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
注意: 此时自动添加的除了get、set方法等,对于构造方法来说,只自动添加了一个无参的构造方法,可以通过 @AllArgsConstructor 注解,再添加有参的构造方法(自己手动添加也可以)(由于只添加有参的构造方法,无参的方法会默认被替掉而只剩下有参的构造方法,所以添加有参构造方法之后,再通过 @NoArgsConstructor 注解添加无参的构造方法)
3.5 thymeleaf中的th:each循环
3.5.1 List
后台:
前台:
3.5.2 Map
后台:
前台:
3.5.3 Array
与List一模一样
后台:
前台:
3.6 thymeleaf中的条件判断
后台:
前台:
3.7 内敛表达式
内敛文本
先在标签上加上 th:inline=“text” ,在内部就可以使用[[${xxx}]]来使用了(缺点:没有提示)
内敛脚本
用于在js代码中使用后台传过来的值
先在script标签上加上 th:inline=“javascript”,在内部就可以通过使用[[${xxx}]]来获取后台传过来的值了。
3.8 字面量
几种字面量(文本字面量,数字字面量,boolean字面量,null字面量)
3.9 字符串拼接
3.10 数学运算
相关运算符:
三元运算:表达式?”正确结果”:”错误结果”
算术运算:+ , - , * , / , %
关系比较::> , < , >= , <= ( gt , lt , ge , le )
相等判断:== , != ( eq , ne )
3.11 基本表达式对象
模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由
#号开始引用,下面列出比较常用的内置对象。
session:
后台:
前台:
request:
<h3>#request的使用</h3>
<script type="text/javascript" th:inline="javascript">
// 比如要拼成 http://localhost:8080/index
//1、获取请求路径(拼接)
//获取协议名称 http
var scheme = [[${#request.getScheme()}]];
//获取服务器名称 localhost
var serverName = [[${#request.getServerName()}]];
//获取服务器端口号 8080
var serverPort = [[${#request.getServerPort()}]];
//获取上下文根 这里没设置
var contextPath = [[${#request.getContextPath()}]];
var allPath = scheme + "://" + serverName + ":" + serverPort + contextPath;
alert("路径=" + allPath);
//2、获取请求路径(直接获取)
var requestURL = [[${#httpServletRequest.requestURL}]]; //请求的路径
var queryString = [[${#httpServletRequest.queryString}]]; // 传递的参数
//进行拼接
var requestAddress = queryString == null?requestURL: requestURL+"?"+queryString;
// alert("requestURL=" + requestURL);
// alert("queryString=" + queryString);
alert("请求路径=" + requestAddress)
</script>
3.12 功能表达式对象
模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法,工作中常使用的数据类型,如集合,时间,数值,可以使用 Thymeleaf 的提供的功能性对象来处理它们。
内置功能对象前都需要加#号,内置对象一般都以 s 结尾。
#dates: java.util.Date 对象的实用方法:
<span th:text="${#dates.format(curDate, 'yyyy-MM-dd HH:mm:ss')}"></span>
#calendars: 和 dates 类似, 但是 java.util.Calendar 对象;
#numbers: 格式化数字对象的实用方法;
#strings: 字符串对象的实用方法: contains, startsWith, prepending/appending 等;
#objects: 对 objects 操作的实用方法;
#bools: 对布尔值求值的实用方法;
#arrays: 数组的实用方法;
#lists: list 的实用方法,比如<span th:text="${#lists.size(datas)}"></span>
#sets: set 的实用方法;
#maps: map 的实用方法;
#aggregates: 对数组或集合创建聚合的实用方法;
举例:
后台:
前台:
4. 国际化与安全
4.1 国际化
1、配置
2、然后在核心配置文件application.properties中指定国际化的配置文件位置:
3、在html文件中就可以通过th:xxx获取到可视化配置中添加的值
4、在html中添加转换请求,并在配置类中增加视图请求
5、自定义一个组件LocaleResolver
public class MyLocalResolver implements LocaleResolver {
// 解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
// 获取请求中的语言参数
String language = request.getParameter("l");
System.out.println("Debug===>"+language);
Locale locale = Locale.getDefault(); //如果没有就使用默认的
// 如果请求的链接携带了国际化的参数
if(!StringUtils.isEmpty(language)){
// zh_CN en_US
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
6、将自己写的组件配置到spring容器中。即在配置类中 @Bean。
@Configuration
public class MyConfig implements WebMvcConfigurer {
// 增加视图请求
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 当请求/index.html时 跳转到index界面
registry.addViewController("/index.html").setViewName("index");
}
// 自定义的国际化组件就生效了!
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
}
7、测试
4.2 SpringSecurity环境搭建
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
写一个配置类,继承自WebSecurityConfigurerAdapter类
package com.liu.controller.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 // 还需添加此注解,一般@Enablexxx,是开启xxx功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 链式编程
// 授权
@Override
protected void configure(HttpSecurity http) throws Exception {
// 首页所有人可以访问,功能页只有对应有权限的人才能访问
// 请求授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll() // 首页所有人可以访问
.antMatchers("/level1/**").hasRole("vip1") // templates下的level1下,VIP1权限的人可以访问。
.antMatchers("/level2/**").hasRole("vip2"); // templates下的level2下,VIP2权限的人可以访问。
// 没有权限时会默认跳转到登录界面,需要开启登录的界面 默认跳到/login请求
http.formLogin();
// 开启注销功能 默认请求/logout文件
http.logout();
}
// @Autowired
// private DataSource dataSource;
// 认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 在内存中读 new BCryptPasswordEncoder()是密码的加密规则,不加密的话会报错
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
// 给相应的用户名和密码授予权限
.withUser("huige").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");
// 正常应该从数据库中读
// UserBuilder users = User.withDefaultPasswordEncoder();
// auth.jdbcAuthentication().dataSource(dataSource).withDefaultSchema()
// .withUser(users.username("user").password("password").roles("USER"))
// .withUser(users.username("admin").password("password").roles("USER","ADMIN"));
}
}
5. Swagger
- 号称世界上最流行的Api(应用程序编程接口)框架
- RestFul Api 文档在线自动生成工具=>Api文档与API定义同步更新(文档根据代码实时更新)
- 直接运行,可以在线测试API接口
- 支持多种语言:(Java,php)
5.1 SpringBoot集成Swagger
1、新建一个SpringBoot的web项目
2、导入依赖
<!-- 导入swagger相关依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
3、编写一个Hello工程
4、写一个配置类,开启Swagger2
注意springboot的版本降到2.5.6
5、访问 http://localhost:8080/swagger-ui.html 即可
5.2 配置Swagger信息
Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。
@Bean //配置docket以配置Swagger具体参数
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
可以通过apiInfo()属性配置文档信息,并用Docket实例关联上apiInfo()
@Configuration
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
// 配置了swagger的Docket的Bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
//配置文档信息
private ApiInfo apiInfo(){
return new ApiInfo("m豪的SwaggerAPI文档", //标题
"描述信息", // 描述信息
"1.0", // 版本
"urn:tos", // 团队信息
new Contact("m豪", "url", "123456@126.com"), // 作者信息
"Apache 2.0", // 许可
"http://www.apache.org/licenses/LICENSE-2.0", // 许可链接
new ArrayList()); // 扩展
}
}
5.3 Swagger配置扫描接口
1、构建Docket时通过select()方法配置怎么扫描接口。
// 配置了swagger的Docket的Bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select() // 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.liu.controller")) // 配置根据包的路径扫描接口
.build();
}
2、重启项目测试,由于我们配置根据包的路径扫描接口,所以我们只能看到一个类。
3、除了通过包路径配置扫描接口外,还可以通过配置其他方式扫描接口,这里注释一下所有的配置方式:
// 配置了swagger的Docket的Bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select() // 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
//下面是几种扫描方式
//1、any() // 扫描所有,项目中的所有接口都会被扫描到
//2、none() // 不扫描接口
//3、withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
//4、withClassAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
//5、basePackage(final String basePackage) // 根据包路径扫描接口
.apis(RequestHandlerSelectors.basePackage("com.liu.controller")) // 配置根据包的路径扫描接口
.build();
}
4、除此之外,还可以配置接口扫描过滤:
5.4 配置Swagger开关
1、通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了
2、动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示?
配置文件多写几个,application.properties(application-dev.properties,application-test.properties等等,在主配置文件中写上使用哪一套配置,然后在SwaggerConfig类中拿到使用的配置。判断是不是指定的配置,如果是则使用,否则不适用。
5.5 分组
1、如果没有配置分组,默认是default。通过groupName()方法即可配置分组:
2、如何配置多个分组?配置多个分组只需要配置多个docket即可:
5.6 实体配置
1、新建一个实体类
2、只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:
效果:
注:并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。
@ApiModel为类添加注释(上述“用户实体”)
@ApiModelProperty为类属性添加注释(上述“用户名” 和 “密码”)
还可以通过@ApiOperation、@ApiParam添加注释:
效果:
3、Swagger的所有注解定义在io.swagger.annotations包下,以下是常见注解
- @Api(tags = “xxx模块说明”) 作用在模块类上
- @ApiOperation(“xxx接口说明”) 作用在接口方法上
- @ApiModel(“xxxPOJO说明”) 作用在模型类上:如VO、BO
- @ApiModelProperty(value = “xxx属性说明”,hidden = true) 作用在类方法和属性上,hidden设置为true可以隐藏该属性
- @ApiParam(“xxx参数说明”) 作用在参数、方法和字段上,类似@ApiModelProperty
这样的话,可以给一些比较难理解的属性或者接口,增加一些配置信息,让人更容易阅读!
相较于传统的Postman或Curl方式测试接口,使用swagger简直就是傻瓜式操作,不需要额外说明文档(写得好本身就是文档)而且更不容易出错,只需要录入数据然后点击Execute,如果再配合自动化框架,可以说基本就不需要人为操作了。
Swagger是个优秀的工具,现在国内已经有很多的中小型互联网公司都在使用它,相较于传统的要先出Word接口文档再测试的方式,显然这样也更符合现在的快速迭代开发行情。当然了,提醒下大家在正式环境要记得关闭Swagger,一来出于安全考虑二来也可以节省运行时内存。
5.7 总结
1、我们可以通过Swagger给一些比较难理解的属性或者接口,增加注释信息。
2、接口文档实时更新。
3、可以在线测试。
6. 任务
6.1 异步任务
在需要异步执行的方法前加 @Async 注解,然后在SpringBoot启动类前加注解 @EnableAsync 就可以了。
6.2 定时任务
先在SpringBoot启动类前加注解 @EnableScheduling,然后在业务逻辑这里写上 @Scheduled注解,并用cron表达式作为参数。
7. Dubbo + Zookeeper
7.1 Zookeeper(注册中心)安装
什么是ZooKeeper?
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
下载之后,进行解压,如图:
打开conf目录,在其中添加zoo.cfg(直接复制zoo_simple.cfg再改名即可)
打开bin目录,双击服务端运行
如果出现了闪退的现象,则用记事本方式打开服务端,添加一个pause即可。
打开服务端运行之后,可打开客户端进行操作。
服务端:
客户端:
7.2 Dubbo-admin安装
注意: dubbo-admin是一个监控管理后台(可视化界面),查看我们注册了哪些服务,哪些服务被消费了。(也可以不要)