springboot
什么是springboot
配置如何编写 yaml
自动装配原理
集成web开发:业务核心
集成数据库Druid
分布式开发: Dubbo(RPC)+zookeeper
swagger:接口文档
任务调度
springSecurity:Shiro
springcloud
微服务
springcloud入门
Restful
Eureka
Ribbon
Feign
HyStrix
Zuul 路由网关
Spring Cloud Config:git
springboot 一站式开发框架 1.5.9 版本
springboot 主要优点:开箱即用,内嵌tomcat ,没有xml配置要求
springboot 是打成 jar 包运行的
springboot 构建一个功能独立的微服务应用单元,快速构建一个应用
springCloud 大型分布式网络服务的调用,实现分布式
springCloudDataFlow 在分布式中间,进行流数据的计算处理。
maven - gav 定位一个jar 包位置
springboot maven 中 artifactid 都是以spring - boot - starter - 开头
spring - boot - starter - web 用实现 Http 接口 (该接口包含了 springMvc) 使用tomcat 作为默认嵌入容器
要在springboot Application 文件同级目录下建立controller、dao 。。。。才能开始测试,
如图:
创建springboot 项目
1. 利用官方提供的项目
去官网配置并下载:https://spring.io/projects/spring-boot
配置时 记得要添加 web 组件
导入maven项目,
总结:啥配置都不用写,可以把更多的精力放在业务上
2.利用 IDEA 模板创建
添加依赖 也可以到maven -- pom 里面添加
创建后的目录
//创建controller
到此 创建完成,什么配置都不用添加,也不用配置tomcat ,直接访问 http://localhost:8080/test
修改springboot 启动时的 banner
字符图片生成网站(banner生成网站): https://www.bootschool.net/ascii
去该网站下生成文件,保存txt
在 resouce 文件夹下 新建 banner . txt
将内容填充至 该文件中,springboot加载时,会加载该文本,并显示
需要注意的是,你的配置文件是否被springboot 识别,看文件图标下,是否有springboot 图标(类似于电源按钮图标)
JSR303数据校验
@Compant
@Validated //数据校验
public class Person{
@Email(message="错误提示")
private String email;
get 、 set method
}
空检查
@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=) Validates that the annotated string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) 检查数字是否介于min和max之间.
@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber 信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
将springboot应用打包成jar
maven 依赖
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
这样在运行项目后,或者 使用 maven-package 命令后 traget 目录下,就会生成jar包,运行这个jar包,就启动了服务
springboot 注解介绍
@SpringBootApplication : 表示类为springboot 的应用
@SpringBootConfiguration : 表示类为springboot 配置类
@Configuration : 表示为配置类
@EnableAutoConfiguration : 开启自动配置功能 ,以前大部分需要配置的东西,都自动配置了
@AutoConfigurationPackage: 自动配置包
@Import : spring 注解,导入组件,会导入许多的自动配置类(xxxAutoConfiguration),并配置好这些组件
@RestController
一般Controller层 有些类全部返回的都是ResponseBody
所以@ResponseBody可以提取到类上,如:
@Controller
@RestController
以上两个组合写法
@RestController
项目基本目录结构
public 、 resources 是自己创建的
static 目录,用来存放 css,js ,图片
templates 文件夹,用来存放springmvc 跳转的页面,模板引擎页面
application.properties : springboot 配置文件
yaml (springboot配置文件:删除application.xml,添加application.yaml)
在以往的配置文件中,一般配置放在 xml 中
但是springboot 推出了一种新得写法:yaml
剔除掉了 xml 得复杂配置,简化 xml
但是yaml 对于空格得要求十分得严格
换行后加一空格:那么与上一行得关系就是层级关系了。如果没有空格:就是同级关系。
格式: [name]: 空格[value]
例子:
值 name: xiongzhenxing
对象sutdent
name: xzx
age: 12
使用yaml 获取随机数
user.id=${random.uuid}
user.id=${random.int}
user.id=${random.int(10)}
使用yaml 直接注入数组、List、Set
pets:
- cat
- dog
- pig
或者
pets: [cat,dog,pib]
使用 yaml 直接注入对象 (使用情况:工程可能存在得配置类)
entity--》Person
@Component
@ConfigurationProperties( prefix ="person")
public Class Person{
private String name;
private Integer age;
private Data sendTimd;
get 、 set (method)
}
application.yaml
person:
name: xiongzhenxing
age: 12
sendTime: 2020/2/18
或者
person: {name: xiongzhenxing,age: 12,sendTime: 2020/2/18}
使用ConfigurationProperties 注解得时候,可能会存在报红
pom.xml 添加dependency
<dependency>
<groupId>org.springframework.boot></groupId>
<artifactId>spring-boot-configuration-processor</artifactld>
<optional>true</optional>
</dependency>
spring boot 多环境配置,加载指定 application 文件
在实际开发中,可能存在多套配置,如何在切换配置文件?
1.(假设下面得文件后缀为yaml)
默认加载 application.yaml , 那么可以在 application.yaml 中配置
spring:
profiles:
active: test
2. 多个配置写在一个文件中,只有一个配置文件 applicaiotn.yaml
server:
port: 8080
spring:
profiles:
active: test #如果不写spring。profiles.active..这些,就默认加载第一个配置
--- #作为多环境分割
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: test
当项目打包成jar 后,可以通过启动命令选择指定的配置
1.java -jar xx.jar --spring.profiles.active=dev
2.可以在jar 包所在目录,创建application.properties 配置
以上两种,优先级都高于所有
使用 PropertySource 加载指定其他的配置文件(除application以外的)
@Component
@PropertySource( value= "classpath:xx.properties")
public Class Person{
private String name;
private Integer age;
private Data sendTimd;
get 、 set (method)
}
导入用户自定义的spring配置文件 ImportResource
使其文件内容生效,在main 方法所在主类 前面加上注解,并且指定 配置文件
@ImportResource(locations = {"classpath: xxbeansxx.xml"})
@SpringBootApplication
public class SpringbootDay01Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootDay01Application.class, args);
}
}
这样 用户自定义spring配置文件 xxbeansxx.xml 中的配置内容就生效了
但是springboot 不推荐使用配置,所以这种方法不常用,看下面的 spring代码配置类
添加 spring 配置类 @Configuration
指明当前类是一个spring配置类,来替代 spring配置文件
添加注解 @Configuration
1. 注册bean对象
方法名称 就是 bean 对象名
返回值及返回类型,就是 bean 类型
@Bean
public HelloService helloService(){
return new HelloSerivce(); //返回值及返回类型,就是 bean 类型
}
springboot 日志 SLF4j+ logback
springboot 使用的是 SLF4j + logback 并且使用了许多日志接口,兼容了其他日志如log4j,commons等
SLF4j 是日志接口,logback 是日志实现
Logger logger = LoggerFactory.getLogger(getClass());
日志级别 (由低到高)
logger.trace("");
logger.debug("");
logger.info("");
logger.warn("");
logger.error("");
调整日志级别 , 日志只会在当前级别与更高级别生效,低级别就不会生效
springboot 默认日志级别 : info
调整某个包或者类得日志级别,其他默认 ,在application.properties 中配置
logging.level.com.xx=trace
指定日志文件: 如上图
指定日志文件路径:如上图
控制台日志输出格式:logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
文件日志输出格式:logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
如果觉得springboot 日志配置不符合项目要求
可以在类根路径下 更具使用得日志实现,创建相应得日志配置文件
springboot --- springmvc
编辑 application.properties
#关闭thymeleaf 模板缓存
spring.thymeleaf.cache=false
#修改项目访问地址
server.servlet.context-path=/xx
#修改项目访问端口
server.port=xx
#指定国际化文件所在目录
spring.messages.basename=i18n.login
#修改默认日期格式
spring.mvc.date-format=yyyy/MM/dd
#默认不支持put,delete等请求方式
spring.mvc.hiddenmethod.filter.enabled=true
#修改tomcat字符编码
server.tomcat.uri-encoding=UTF-8
资源目录
访问 资源文件夹,不用加文件夹名称 ( public 、resources 、static、templates)
静态资源的访问
如果自己在application 文件中指定了,静态资源目录,那么默认的自动失效
例如: spring.mvc.static-path-pattern=/file/**
设置首页
在resources 下的 public 、 resources 、 static 任意目录中创建 index.html
那么在访问主页 http://localhost:8080/ 时,会加载这个 index.html
但是开发不用这个,因为index.html 应该放到 themplates 中
所以我们采用 @RequestMapping( { "/","index.html" } ) 这种方式映射
修改网页图标
springmvc 版本要求2.1.* 2.2.* 不行
在resources资源文件夹下任意目录创建 文件 favicon.ico
thymeleaf 请求页面 ( 或者可以在创建项目的时候直接勾选thymeleaf)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
/*忽略以下内容*/
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
通过controller 方法返回的字符串,即可去 templates 目录下找 返回字符串.html
从而实现请求到页面的跳转
如果想在 页面使用表达式
需要在 html 标签中加入命名空间 xmlns:th="http://www.thymeleaf.org
<html lang="en" xmlns:th="http://www.thymeleaf.org">
@Controller
public class testController {
@RequestMapping("test")
public String test(Model model){
model.addAttribute("msg","hello springboot");
return "test";
}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:text="${msg}"> </div>
</body>
</html>
thymeleaf 取值方式
行内写法 ,没有标签 [[ ${变量名} ]]
普通变量 ${...} 可以取作用域值 ${session.user}
国际化消息 #{...}
URL @{...} @{/image/xx.jpg} or @{/image/add ( data=${b} ) }
片段表达式 ~{...} 插入页面
文本操作 +
数学运算 + - * / % >= <=
布尔运算 and or
条件运算 ( if )?( then ):(else)
thymeleaf 接管标签详解
th属性会替换掉原有得html 属性 , 例如: <div id = "aaa" th:id="bbb"/> 那么最后id 为bbb
th:text 普通文本
model.addAttribute("msg","<h1>hello springboot</h1>");
<div th:text="${msg}"> </div>
th:utext html标签转义
model.addAttribute("msg","<h1>hello springboot</h1>");
<div th:utext="${msg}"> </div>
th:each 遍历数据
th:fragment th:replace 抽取公共页面(例:顶部导航,底部,侧边)
可以将公共标签,写在一个新的html文件中,在需要抽取标签上加上 th:fragment="xx"
也可以用id 定位到抽取的标签 ,不过在引入的时候,需要在标签前加上# 例:~{xx::#xx}
显示抽取内容
将整个公共页面插入到声明得元素中(最外层得div 存在)
<div th:insert="~{抽取页面名称(不要后缀) ::抽取标签xx}"></div>
将公共页面 替换 声明的元素(最外层得div 不存在) 优先选择这个。。。。。。
<div th:replace="~{抽取页面名称(不要后缀) ::抽取标签xx}"></div>
抽取公共 导航栏,后解决不同页面高亮显示
例如在:emps 页面引入导航栏时加上参数 activeOn,同理在index 页面,加入参数 index
<div th:replace="~{commons/commons::leftCommons(activeOn='emps')}"/>
在公共导航栏 中判断,传递的 activeOn参数是否等于当前按钮,等于即高亮
<li th:class="${activeOn=='emps'?'active':''}">
<a href="emps.html"><i class="icon-chevron-right"></i> 表格</a>
</li>
springboot 配置 springmvc @Configuration
在配置类中,添加 springmvc 配置注解 替代 springmvc 配置文件
添加注解 @Configuration
实现接口 WebMvcConfigurer
就可以重写 springmvc 中封装的方法
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
标记注解Configuration
实现WebMvcConfigurer接口重写方法
}
return "redirect:/xx" ; 重定向到某个请求
return "forward:/xx" ; 重定向到某个请求
视图解析器
当请求来了后, 会优先选择Controller 匹配,如果匹配成功后,就会根据 返回值 跳转到指定 html 页面
如果匹配不成功,就会到视图解析器 匹配
所以 视图解析器 得优先级 低于 Controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//添加主页视图控制
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/login").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
}
Interceptors 拦截器
//登录请求
@RequestMapping( {"/user/login" , "/user/login.html" } )
public String login(@RequestParam("username")String username, @RequestParam("password")String password, Model model, HttpSession session){
if( !StringUtils.isEmpty(username) && "123456".equals(password) ){
session.setAttribute("loginFlag",username);
return "redirect:/index.html";
}else {
model.addAttribute("msg","用户名或密码错误");
return "login.html";
}
}
//重写拦截器
public class UserHandlerInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginFlag = request.getSession().getAttribute("loginFlag");
if(loginFlag!=null){
System.out.println("拦截器放行");
return true;
}else {
System.out.println("拦截器拦截");
request.setAttribute("msg","没有权限,请登录!");
request.getRequestDispatcher("/login.html").forward(request,response);
return false;
}
}
}
//拦截器配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserHandlerInterceptors()) //指定拦截器
.addPathPatterns("/**") //拦截请求
.excludePathPatterns("/login.html","/login","","/assets/**","/bootstrap/**","/images/**","/vendors/**"); //排除请求
}
国际化
1.创建国际化配置文件 i18n/login.properties , i18n/login_zh_CN.properties , i18n/login_en_US.properties
注意 zh_CN 代表中文,en_US 代表英文
2.配置文件中指定国际化文件所在目录
spring.messages.basename=i18n.login
3.修改文件编码 防止乱码
4.编写配置文件
5.将配置得参数 通过国际化写法 嵌入到页面
此时,页面基本上可以跟随浏览器语言得改变,所改变语言
6. 在页面底部 添加修改语言 链接
<a th:href="@{/login.html(language='zh_CN')}"> 中文</a>
<a th:href="@{/login.html(language='en_US')}"> 英文</a>
7. 重写区域解析器
package com.nextstep.component;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
//在连接上携带区域信息 http://localhost:8080/login.html?language=zh_CN
//还要将该容器添加到 Bean 中
public class MyLocaleResolver implements LocaleResolver {
//区域解析器
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("language"); //获取地区 language 参数
Locale locale = Locale.getDefault(); // 默认
if(!StringUtils.isEmpty(language)){ //传值是否为空
String[] split = language.split("_"); //分割 en_US ch_CN
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
8.将区域解析器,添加到springmvc 中
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//区域解析器
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
结构
即可通过 链接来修改页面语言
Restful 风格 CRUD
1. 查询所有员工 (/emps) get
//查询所有员工
@GetMapping({"emps","emps.html"})
public String select(Model model){
List lists = employeeDao.select();
model.addAttribute("lists",lists);
return "emps";
}
<tr th:each="list:${lists}">
<td th:text="${list.id}"></td>
<td >[[${list.lastName}]]</td>
</tr>
2.查询某个员工--修改页面 (/emp/1) get
<a th:href="@{/emp/}+${list.id}">修改</a>
//修改员工页面
@GetMapping("emp/{id}")
public String updateEmpPage(@PathVariable("id") Integer id , Model model){
Employee employee = employeeDao.selectById(id);
model.addAttribute("updateEmp",employee);
return "update";
}
<form class="form-horizontal" method="post" th:action="@{/emp}">
<input th:type="hidden" name="_method" value="put">
<input class="input-xlarge focused" name="lastName" type="text" th:value="${updateEmp.lastName}">
<button type="submit" class="btn btn-primary">修改</button>
</form>
6.修改员员工信息 (/emp) put
//修改员工
@PutMapping("emp")
public String updateEmp(Employee employee){
logger.info("logger--put Emp");
employeeDao.update(employee);
return "redirect:/emps";
}
3. 来到添加员工信息页面 (/emp) get
//添加员工页面
@GetMapping("emp")
public String addEmpPage(){
return "add";
}
<form class="form-horizontal" th:method="post" th:action="@{emp}">
<input class="input-xlarge focused" name="lastName" type="text" >
</form>
4. 添加员工 (/emp) post
//添加员工请求
@PostMapping("emp")
public String addEmp(Employee employee){
employee.setId(123);
employeeDao.add(employee);
logger.info("logger--post Emp");
return "redirect:/emps";
}
7. 删除员工 (/emp/1) delete
<form th:action="@{/emp/}+${list.id}" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="删除"></a>
</form>
//删除员工
@DeleteMapping("emp/{id}")
public String deleteEmp(@PathVariable("id") Integer id ){
employeeDao.delete(id);
return "redirect:/emps";
}
定制错误页面
1.在模板引擎themplates 下创建 error 文件夹
2.在error文件夹下创建对应的错误码页面 例: 404.html , 405.html , 500.html
3.可以使用通用错误页面 4xx.html , 5xx.html 优先精确匹配
可以在错误页面获取的信息
1.timestamp:时间戳
2.status:状态码
3.error:错误提示
4.exception:异常对象
5.message:异常信息
6.errors:JSR303 数据校验错误
错误信息的页面获取用法 : <h1> [[ ${ status } ]]
修改 默认 servlet 容器
修改默认容器为 jetty,在application.properties 中的配置还是一样的
排除掉 tomcat 依赖,添加 jetty 依赖, 在底层会自动判断容器是否存在,存在就加载
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>