SpringBoot入门使用教程
建议:先学spring再学springBoot。
文章目录
前言
Spring是一个非常优秀的轻量级框架,以IOC(控制反转)和AOP(面向切面)为思想内核,极大简化了JAVA企业级项目的开发。虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。使用Spring进行项目开发需要在配置文件中写很多代码,所有这些配置都代表了开发时的损耗。Spring项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。比如Spring5.0以上只能使用Junit4.12以上的版本。接下来我们学习一个springBoot的升级版。
- spring缺点:配置繁琐,引入依赖过多。
一、SpringBoot介绍_SpringBoot核心功能
- 核心配置:springBoot项目自动提供最优配置,同时可以修改默认值完成特定需求。
- 起步依赖:SpringBoot的依赖是基于功能的,而不是普通项目的依赖是基于JAR包的。SpringBoot将完成一个功能所需要的所有坐标打包到一起,并完成了版本适配,我们在使用某功能时只需要引入一个依赖即可。
二、SpringBoot入门_搭建项目
1.SpringBoot入门_通过官网搭建项目
- 访问官网start.spring.io
- 点击create即可下载项目压缩包,解压放入IDEA环境中即可完成。
- 注意版本信息:
SNAPSHOT:快照版,表示开发版本,随时可能修改;
M1(Mn):M1是milestone的缩写,也就是里程碑版本;
RC1(RCn):RC1是release candidates的缩写,也就是发布预览版;
Release:正式版,也可能没有任何后缀也表示正式版 - SpringBoot打包类型说明:
使用SpringMVC开发的是一个web项目,但由于在SpringBoot中直接嵌入了Tomcat等Web容器,所以在使用SpringBoot做Web开发时不需要部署War文件,只需要打成Jar包即可。
2.SpringBoot入门_通过IDEA脚手架搭建项目
- 在IDEA中新建项目,项目类型为Spring Initializr,选择JDK版本和搭建网站后点击下一步。
3.SpringBoot项目结构_POM文件
- SpringBoot项目结构
- POM文件
- SoringBoot项目必须继承soring-boot-starter-parent,即所有的springboot项目都是spring-boot-starter-parent的子项目。spring-boot-starter-parent中定义了常用配置、依赖、插件信息等,供给springBoot项目使用。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0-M1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
- springBoot项目中可以定义起步依赖,起步依赖是以功能为单位,而不是以jar包为单位。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- spring-boot-maven-plugin插件是将项目打包成jar包的插件。该插件打包后的springboot项目无需依赖web容器,可以直接使用jdk运行。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
4.SpringBoot项目结构_启动类、配置文件
- 启动类
- 配置文件
5.SpringBoot入门_通过Maven搭建项目
- 建立一个普通maven项目,在pom文件中加入起步依赖和继承spring-boot-starter-parent项目
<!-- 父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0-M1</version>
</parent>
<!-- 起步依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- 插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
-
添加启动类:
-
在resource下建立配置文件,指定端口,springboot是约定大于配置的框架,所以配置名称必须为application.properties。
6.SpringBoot入门_编写JAVA代码
- 使用springMVC测试案例(springBoot会自动扫描,但自能在同级包下或同级包下的包中)
启动项目访问:http://localhost:8080/hello
- 测试用例代码
package edu.beihua;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Mycontroller {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("hello SpringBoot!");
return "hello SpringBoot!";
}
}
三、SpringBoot原理分析
-
SpringBoot原理分析_起步依赖,实质利用了依赖传递。
按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,发现spring-boot-starter-parent的父工程是spring-boot-dependencies。
进入spring-boot-depencies的pom.xml中可以发现,一部分依赖坐标的版本,依赖管理、插件管理都已经定义好,所以spring-boot-starter-parent后已具备版本锁定等配置。
所以起步依赖的作用就是传递父级依赖。 -
SpringBoot原理分析_自动配置
-
查看注解@SpringBootApplication的源码
@SpringBootConfifiguration:等同与@Confifiguration,既标注该类是Spring的一个配置类
@EnableAutoConfifiguration:SpringBoot自动配置功能开启
- 核心注解
四、YAML文件
- 配置文件介绍
在springBoot项目中大部分配置都是默认配置好的,如果想更改配置可以通过编辑application.properties或者application.yml进行配置。
SpringBoot默认会从resources目录下加载application.properties或application.yml文件。其中,application.properties文件是键值对类型的文件。
可以参考官方文档如何覆盖原配置:官方文档
处理application.properties配置文件外,还可以通过YAML文件进行配置。YAML文件的扩展名为.yml或.yaml,它的基本要求如下:
大小写敏感、使用缩进代表层级关系、相同的部分只出现一次。
比如使用properties文件配置tomcat端口:
server.port=8888
而使用YAML文件配置tomcat端口:
server:
port: 8888
-
自定义配置简单数据
除了覆盖默认配置,我们还可以在YAML文件中配置其他信息以便我们在项目中使用。配置简单数据的方式如下:
-
自定义配置对象数据
对象:
属性名1: 属性值
属性名2: 属性值
# 或者
对象: {属性名1: 属性值,属性名2: 属性值}
# 学生一
student1:
sex: female
age: 10
address: 北京
#学生2
student2: {sex: famale,age: 10,address: beijing}
注意:属性名前面的空格个数不限,在yml语法中,相同缩进代表同一个级别,但是属性前的空格数一样即可。
4. 自定义配置集合数据
集合:
- 值1
- 值2
# 或者
集合: [值1,值2]
#学生2
student2: {sex: famale,age: 10,address: beijing}
#城市
city1:
- beijing
- shanghai
- chhongqing
- sichuan
city2: [beijing,tianjing,shanghai,yunnan]
#集合中元素是对象
student:
- name: zhansan
age: 23
address: yunnan
score: 155
- name: sisi
age: 18
address: 155
score: 38
- 读取配置文件的数据
@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上,用法如下:
server:
port: 8888
#管理员用户名
name: zhangsan
# 学生一
student1:
sex: female
age: 10
address: 北京
#学生2
student2: {sex: famale,age: 10,address: beijing}
#城市
city1:
- beijing
- shanghai
- chhongqing
- sichuan
city2: [beijing,tianjing,shanghai,yunnan]
#集合中元素是对象
student:
- name: zhansan
age: 23
address: yunnan
score: 155
- name: sisi
age: 18
address: 155
score: 38
java类中:
package deu.beihua.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class myConteoller1 {
@Value("${name}")
private String name;
@Value("${student1.age}")
private int age;
@Value("${city1[0]}")
private String address;
@Value("${student[0].address}")
private String score1;
@RequestMapping("/yaml")
@ResponseBody
public String testYaml(){
System.out.println(this.name);
System.out.println(this.address);
System.out.println(this.score1);
return "hello springboot!";
}
}
@Value只能映射简单数据类型,不能将yaml文件中的对象、集合映射到属性中。
@ConfigurationProperties(prefifix=“对象”)可以将配置文件中的配置自动与实体进行映射,这样可以将yml文件中配置的对象属性直接映射到Bean当中。
#@ConfigurationProperties(prefifix=“对象”)可以将配置文件中的配置自动与实体进行映射,
#这样可以将yml文件中配置的对象属性直接映射到Bean当中。
user:
id: 10001
username: tuadhjashgak
address:
- beijing
- tianjin
- shanghai
- chongqing
grades:
- subject: math
score: 100
- subject: english
score: 90
-
占位符的使用
YAML文件中可以使用${}占位符,实现值得复用。它有两个作用:
编写配置文件: -
配置文件存放位置及优先级
-
bootstrap配置文件
server:
port: 8888
myconfig:
myport: ${server.port}
读取配置文件的值:
@Controller
public class YmlController3 {
@Value("${myconfig.myport}")
private int port;
@RequestMapping("/yml3")
@ResponseBody
public String yml3(){
System.out.println(port);
return "hello springboot!";
}
}
使用框架提供的方法:
${random.value} :生成类似uuid的随机数,没有"-"连接
${random.uuid} :生成一个uuid,有短杠连接
${random.int} :随机取整型范围内的一个值
${random.int(10)}:随机生成一个10以内的数
${random.int(100,200)}:随机生成一个100-200 范围以内的数
${random.long}:随机取长整型范围内的一个值
${random.long(100,200)}:随机生成长整型100-200范围内的一个值
# 随机生成tomcat端口
server:
port: ${random.int(1024,9999)}
- YAML文件_配置文件存放位置及优先级
项目根目录下;
项目根目录下/config子目录中
项目的resource目录中
项目的resource目录下的/config子目录中
springboot的配置文件只有两种类型:application.properties和application.yaml
-
YAML文件_bootstrap配置文件
SpringBoot中有两种容器对象,分别是bootsstrap和application,application是应用程序的父容器,bootstap的加载优先级高于application。bootstrap配置文件主要对bootsrap容器进行配置。bootstrap文件支持properties和yaml文件的格式,主要应用于外部引入spring应用的配置。 -
bootstarp的特征:
boostrap由父ApplicationContext加载,比applicaton优先加载。 boostrap里面的属性不能被覆盖。
- bootstrap与application的应用场景
application配置文件主要用于SpringBoot项目的自动化配置。 - bootstrap配置文件有以下几个应用场景。
使用Spring Cloud Config配置中心时,需要在bootstrap配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息。
一些固定的不能被覆盖的属性。
一些加密/解密的场景。
五、springBoot注册Web组件
由于SpringBoot项目没有web.xml文件,所以无法在web.xml中注册web组件,SpringBoot有自己的方式注册web组件。
- 新建一个项目springbootdemo3,并添加springWeb组件
在启动类同级目录下建立servlet包,建立一个servlet类
package edu.beihua.springbootdemo3.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("First Servlet…………");
}
}
- 在启动类中加入@ServletComponentScan,目的在启动时扫描注册注解的Web组件。
package edu.beihua.springbootdemo3;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
//SpringBoot启动时扫描注册注解的Web组件
@ServletComponentScan
public class SpringbootDemo3Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemo3Application.class, args);
}
}
- 第二种注册方式(编写注册类实现)
添加SecondServlet类
package edu.beihua.springbootdemo3.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Second Servlet…………");
}
}
编写servletConfig 类
package edu.beihua.springbootdemo3.servletConfig;
import edu.beihua.springbootdemo3.servlet.SecondServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.ServletRegistration;
@Configuration
public class servletConfig {
//ServletRegistrationBean可以注册Servlet组件,将其放入Spring容器中即可注册Servlet
@Bean
public ServletRegistrationBean getServletRegistrationBean(){
// 注册Servlet组件
ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
//添加Servlet组件访问路径
bean.addUrlMappings("/second");
return bean;
}
}
- 注册Filter方式一(和Web Servlet差不多)
纯注解式开发:
package edu.beihua.springbootdemo3.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/first")
public class FirstFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入 First Filter…………");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("放行 First Filter…………");
}
}
方式二:
package edu.beihua.springbootdemo3.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecondFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("进入 Filter…………");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("退出 Filter…………");
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
编写配置类:
package edu.beihua.springbootdemo3.servletConfig;
import edu.beihua.springbootdemo3.filter.SecondFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
//ServletRegistrationBean可以注册Servlet组件,将其放入Spring容器中即可注册Servlet
@Bean
public FilterRegistrationBean getFilterRegistrationBean(){
// 注册Servlet组件
FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
//添加Servlet组件访问路径
bean.addUrlPatterns("/second");
return bean;
}
}
SpringBoot注册Web组件_Listener监听器(实现一:注解实现)
package edu.beihua.springbootdemo3.lisenner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FirstListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("初始lisenner》》》》》");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContextListener.super.contextDestroyed(sce);
}
}
- 第二种使用监听器构建对象进行创建监听器
package edu.beihua.springbootdemo3.lisenner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
public class SecondListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("初始第二个lisenner》》》》》");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContextListener.super.contextDestroyed(sce);
}
}
- 监听器配置类
package edu.beihua.springbootdemo3.servletConfig;
import edu.beihua.springbootdemo3.lisenner.SecondListener;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//使用监听器注册对象,进行注册
public class LisennerConfig {
@Bean
public ServletListenerRegistrationBean getServletListenerRegistrationBean(){
ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(new SecondListener());
return bean;
}
}
六、springBoot访问静态资源
在springBoot项目中,没有WebApp目录,只有src目录。在src/main/resource下有一个static和templates两个文件夹。
springboot会默认在static目录中存放静态资源,templates下存放一些动态的模板资源等,springboot不推荐使用jsp做动态模板,推荐使用Thymeleaf。
static是所有静态资源的根目录如图片的链接就如此访问:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试用例</title>
</head>
<body>
<img style="width: auto;height: auto;" src="/img/1.png" alt="">
</body>
</html>
- 项目结构
- 启动项目访问:http://localhost:8080/index.html或者http://localhost:8080(默认访问index.html)
- 静态资源的其他存放路径
以上这些位置都可以存放静态资源。 - 自定义存放静态资源(省略,不常用)
七、springBoot整合jsp
虽然springboot不推荐使用jsp,但是我们可以自己配置使用,要手动添加webapp目录。
- 由于SpringBoot自带tomcat无法解析JSP,需要在pom文件添加JSP引擎
<!--添加jsp引擎,SpringBoot内置的Tomcat不能解析JSP-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
- 创建webapp目录,编写JSP文件(新建文件夹后需要设置)。
- 继续完善webapp文件夹
- 由于INF下的东西是不能直接访问的。需要配置视图解析器
spring:
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
logging:
pattern:
console: "%d{MM/dd HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n"
- 编写controller类
package edu.beihua.springbootdemo3.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Controller
public class pageController {
// 页面跳转
@GetMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
- 运行项目,访问 :http://localhost:8080/myjsp
八、Thymeleaf_入门
- 简介
thymeleaf既可以显示静态页面,又可以显示动态页面效果。Thymeleaf是一款用于HTML/XML内容的模板引擎,酷似jsp。它可以轻易的与springMVC等web框架进行集成作为Web应用的模板引擎。在SpringBoot中推荐使用Thymeleaf编写动态页面。 - 优点
能直接在浏览器上运行,无需依赖启动整个web容器;
在不依赖网络环境,有无网络都能运行,没有数据时,thymeleaf也能运行静态的模板,当有数据时thymeleaf会替换掉静态内容,是页面动态显示。 - Thymeleaf引入使用过程
新建SpringBoot项目;
引入SpringMVC和Thymeleaf的起步依赖;
Thymeleaf依赖:
<!--添加Thymeleaf起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 创建视图index.html
<!DOCTYPE html>
<!-- 引入thymeleaf命名空间,方便使用thymeleaf属性 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>thymeleaf入门</title>
</head>
<body>
<!-- 静态页面显示北华大学,动态页面使用后端传来的msg数据代替 -->
<!-- thymeleaf支持el表达式 -->
<h2 th:text="${msg}">北华大学</h2>
</body>
</html>
- template中的html文件不能直接访问,需要编写Controller跳转到页面中
package edu.beihua.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class pageController {
@RequestMapping("/show")
public String show(Model model){
model.addAttribute("msg","Hello Thymeleaf!");
return "index";
}
}
- Thymeleaf_变量输出
准备模型数据
@GetMapping("/show")
public String showPage(Model model){
model.addAttribute("msg","Hello Thymeleaf");
return "index";
}
在视图展示model的值
<span th:text="${msg}"></span>
<hr/>
<input th:value="${msg}">
- Thymeleaf_操作字符串
Thymeleaf提供了一些内置对象可以操作数据,内置对象可直接在模板中使用,这些对象是以#引用的,操作字符串的内置对象为strings。
使用方式
<span th:text="${#strings.isEmpty(msg)}"></span>
<hr/>
<span th:text="${#strings.contains(msg,'s')}"></span>
<hr/>
<span th:text="${#strings.length(msg)}"></span>
- Thymeleaf_操作时间
pageContrller中准备数据:
model.addAttribute("date",new Date(130,01,01));
在index视图中使用内置时间对象dates操作时间对象
<span th:text="${#dates.format(date)}"></span>
<hr/>
<span th:text="${#dates.format(date,'yyyy/MM/dd')}"></span>
<hr/>
<span th:text="${#dates.year(date)}"></span>
<span th:text="${#dates.month(date)}"></span>
<span th:text="${#dates.day(date)}"></span>
- Thymeleaf_条件判断
pageController准备数据
model.addAttribute("sex","女");
视图中进行变量的条件判断:
<div>
<span th:if="${sex} == '男'">
性别:男
</span>
<span th:if="${sex} == '女'">
性别:女
</span>
</div>
pageController中准备数据
model.addAttribute("id","12");
进行条件判断
<div th:switch="${id}">
<span th:case="1">ID为1</span>
<span th:case="2">ID为2</span>
<span th:case="3">ID为3</span>
<span th:case="*">ID为*</span>
</div>
- Thymeleaf_遍历集合
编写实体类
public class Users {
private String id;
private String name;
private int age;
// 省略getter/setter/构造方法
}
准备数据
List<Users> users = new ArrayList<>();
users.add(new Users("1","beihua",23));
users.add(new Users("2","小涂",22));
users.add(new Users("3","admin",25));
model.addAttribute("users",users);
在页面中展示数据
<table border="1" width="50%">
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
<!-- 遍历集合的每一项起名为user -->
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
</tr>
</table>
- Thymeleaf_状态变量
准备数据:
创建User类
public class User {
private String id;
private String username;
private String pwd;
}
//省略set、get、构造方法、tostring方法
pageController中:
@Controller
public class pageController {
@RequestMapping("/show")
public String show(Model model){
model.addAttribute("msg","Hello Thymeleaf!");
//集合数据
List<User> list = new ArrayList<>();
list.add(new User("1","tujiayuan0","ehjkqwh0"));
list.add(new User("2","tujiayuan4","ehjkqwh1"));
list.add(new User("3","tujiayuan2","ehjkqwh2"));
list.add(new User("4","tujiayuan3","ehjkqwh3"));
model.addAttribute("userlist",list);
return "index";
}
}
视图中的使用
<table bgcolor="1" width="60%" cellpadding="0" style="background-color: aliceblue;text-align: center">
<tr>
<th>ID</th>
<th>姓名</th>
<th>密码</th>
<th>索引</th>
<th>计数</th>
<th>是否是第一个遍历</th>
<th>是否是最后一个遍历</th>
<th>结合中元素总数</th>
<th>是否是奇数</th>
<th>是否是偶数</th>
</tr>
<!--遍历集合的每一项为user-->
<!--冒号前的第一个对象是遍历出的对象,第二个对象是封装状态变量的对象-->
<tr th:each="user,status :${userlist}">
<td th:text="${user.id}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.getPwd()}"></td>
<td th:text="${status.index}"></td>
<td th:text="${status.count}"></td>
<td th:text="${status.first}"></td>
<td th:text="${status.last}"></td>
<td th:text="${status.size}"></td>
<td th:text="${status.odd}"></td>
<td th:text="${status.even}"></td>
</tr>
</table>
运行结果:
- Thymeleaf_遍历map:map遍历出来的是键值对对象。
controller中准备数据:
Map<String,User> map = new HashMap<>();
map.put("user1",new User("1","shangxuetang","23"));
map.put("user2",new User("2","baizhan","22"));
map.put("user3",new User("3","admin","25"));
model.addAttribute("map",map);
视图中的数据:
<br/>
<hr/>
<table bgcolor="1" width="60%" cellpadding="0" style="background-color: aliceblue;text-align: center">
<tr>
<th>ID</th>
<th>Name</th>
<th>password</th>
<th>Key</th>
</tr>
<!-- 遍历出的是一个键值对对象,key获取键,value获取值 -->
<tr th:each="m : ${map}">
<td th:text="${m.value.id}"></td>
<td th:text="${m.value.username}"></td>
<td th:text="${m.value.getPwd()}"></td>
<td th:text="${m.key}"></td>
</tr>
</table>
- thymeleaf也可以获取request,session,application域中的数据,方法如下:
准备数据:
此处方法参数发生了改变
request.setAttribute("req","HttpServletRequest");
session.setAttribute("ses","HttpSession");
session.getServletContext().setAttribute("app","application");
index视图中调用格式
<hr/>
<!--request域中获取数据的方法-->
request1:<span th:text="${#request.getAttribute('req')}"></span>
request2:<span th:text="${#httpServletRequest.getAttribute('req')}"></span>
<br>
session1:<span th:text="${session.ses}"></span>
session2:<span th:text="${#httpSession.getAttribute('ses')}"></span>
<br>
application1:<span th:text="${application.app}"></span>
application2:<span th:text="${#servletContext.getAttribute('app')}"></span>
- 在Thymeleaf中路径的写法为@{路径}
<a th:href="@{http://www.baidu.com}">百度</a>
- 在路径中添加参数
准备数据
model.addAttribute("id","100");
model.addAttribute("name","bzcxy");
准备跳转后访问的Controller
@GetMapping("/show2")
@ResponseBody
public String show2(String id,String name){
return id+":"+name;
}
在URL中添加参数
<a th:href="@{show2?id=1&name=sxt}">静态参数一</a>
<a th:href="@{show2(id=2,name=bz)}">静态参数二</a>
<a th:href="@{'show2?id='+${id}+'&name='+${name}}">动态参数一</a>
<a th:href="@{show2(id=${id},name=${name})}">动态参数二</a>
- 在RESTful风格路径中添加参数
准备跳转后访问的Controller
@GetMapping("/show3/{id}/{name}")
@ResponseBody
public String show3(@PathVariable String id,@PathVariable String name){
return id+":"+name;
}
在URL中添加参数
<a th:href="@{/show3/{id}/{name}(id=${id},name=${name})}">restful格式传递参数方式</a>
- 在Springboot配置文件中可以进行Thymeleaf相关配置
在yaml而配置文件中的配置如下
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
encoding: UTF-8
cache: false
servlet:
content-type: text/html
九、springBoot整合Mybatis
9.1 SpringBoot热部署
热部署即是修改完代码后不需要重启项目即可生效, 就是在应用正在运行的时候升级软件,却不需要重新启动应用。在SpringBoot中,可以使用DevTools工具实现热部署。
<!-- 热部署工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
在idea中设置自动编译
点击File–>Settings,将第三步打上√
在Idea设置自动运行,快捷键Ctrl+Shift+Alt+/后点击Registry,勾选complier.automake.allow.when.app.running。
完成关闭即可。
9.2 建立一个新的springboot项目添加所需依赖
Spring整合MyBatis时需要进行大量配置,而SpringBoot整合MyBatis则可以简化很多配置:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
准备数据库数据
CREATE DATABASE `student`;
USE `student`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `student`(`id`,`name`,`sex`,`address`) values (1,'张三','男','上海'),(2,'白月初','女','北京');
十、SpringBoot参数校验
10.1 简单数据校验
-
SpringBoot自带了validation工具可以从后端对前端传来的参数进行校验,用法如下:
-
引入validation起步依赖
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 编写controller
// 该控制器开启参数校验
@Validated
@Controller
public class TestController {
@RequestMapping("/t1")
@ResponseBody
// 在参数前加校验注解,该注解的意思是字符串参数不能为null
public String t1(@NotBlank String username){
System.out.println(username);
return "请求成功!";
}
}
- 访问http://localhost:8080/t1,发现当没有传来参数时,会抛出ConstraintViolationException异常。
- 在校验参数的注解中添加message属性,可以替换异常信息。
// 该控制器开启参数校验
@Validated
@Controller
public class TestController {
@RequestMapping("/t1")
@ResponseBody
// 在参数前加校验注解,该注解的意思是字符串参数不能为null
public String t1(@NotBlank(message = "用户名不能为空") String username){
System.out.println(username);
return "请求成功!";
}
}
10.2 SpringBoot参数校验_异常处理
- 当抛出ConstraintViolationException异常后,我们可以使用SpringMVC的异常处理器,也可以使用SpringBoot自带的异常处理机制。
当程序出现了异常,SpringBoot会使用自带的BasicErrorController对象处理异常。该处理器会默认跳转到/resources/templates/error.html页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>错误页面</title>
</head>
<body>
<h1>服务器开小差了!</h1>
</body>
</html>
SpringBoot参数校验_校验相关注解
- Controller中用法
@RequestMapping("/t2")
@ResponseBody
public String t2(
@NotBlank @Length(min = 1, max = 5) String username,
@NotNull @Min(0) @Max(150) Integer age,
@NotEmpty @RequestParam List<String> address,
@NotBlank @Email String email) {
System.out.println(username);
System.out.println(age);
System.out.println(address);
System.out.println(email);
return "请求成功!";
}
10.3 SpringBoot参数校验_对象类型
SpringBoot也可以校验对象参数中的每个属性,用法如下:
- 在实体类中
public class Student {
@NotNull(message = "id不能为空")
private Integer id;
@NotBlank(message = "姓名不能为空")
private String name;
// 省略getter/setter/tostring
}
- 控制器中
@Controller
public class TestController2 {
@RequestMapping("/t3")
@ResponseBody
// 校验的对象参数前添加@Validated,并将异常信息封装到BindingResult对象中
public String t3(@Validated Student student,BindingResult result) {
// 判断是否有参数异常
if (result.hasErrors()) {
// 所有参数异常
List<ObjectError> list = result.getAllErrors();
// 遍历参数异常,输出异常信息
for (ObjectError err : list) {
FieldError fieldError = (FieldError) err;
System.out.println(fieldError.getDefaultMessage());
}
return "参数异常";
}
System.out.println(student);
return "请求成功!";
}
}
10.4 SpringBoot日志管理
SpringBoot默认使用Logback组件作为日志管理。Logback是log4j创始人设计的一个开源日志组件。在SpringBoot项目中我们不需要额外的添加Logback的依赖,因为在spring-boot-parent中已经包含了Logback的依赖。
- 在/resources下添加Logback配置文件logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址-->
<property name="LOG_HOME" value="${catalina.base}/logs/"/>
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yy99-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="Stdout"/>
<appender-ref ref="RollingFile"/>
</root>
</configuration>
- 在代码中打印日志
@Controller
public class LogbackController {
private final static Logger logger = LoggerFactory.getLogger(LogbackController.class);
@RequestMapping("/printLog")
@ResponseBody
public String showInfo(){
logger.info("记录日志");
return "Hello Logback";
}
}
- 如果日志过多,可以屏蔽一些包的日志,在配置文件中配置
#屏蔽org包中的日志输出
logging.level.org=off
十一 、项目部署
11.1 项目部署——项目打包
SpringBoot项目是依赖于Maven构建的,但打包时如果只依赖Maven打包工具则会打包不完整,我们还需要在SpringBoot项目中引入SpringBoot打包插件 :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
此时再使用Maven插件打包:
- 打包目录在target
若只是用maven打包就会缺少boot-inf,在打包后的项目。- 运行jar包:
- 进入jar包所在目录,使用cmd打开命令行窗口
- 输入命令
java -jar jar包名