Spring Boot
1 Spring Boot入门
1.1 Spring Boot特性:
- 能够快速创建基于 Spring 的应用程序
- 能够直接使用 java main 方法启动内嵌的 Tomcat 服务器运行 Spring Boot 程序,不需 要部署 war 包文件
- 提供约定的 starter POM 来简化 Maven 配置,让 Maven 的配置变得简单
- 自动化配置,根据项目的 Maven 依赖配置,Spring boot 自动配置 Spring、Spring mvc 等
- 提供了程序的健康检查等功能
- 基本可以完全不使用 XML 配置文件,采用注解配置
1.2 SpringMvc常用注解:
1.2.1 @Controller
- Spring MVC 的注解,处理 http 请求
1.2.2 @RestController
- Spring 4 后新增注解,是@Controller 注解功能的增强 是 @Controller 与@ResponseBody 的组合注解 如果一个 Controller 类添加了@RestController,那么该 Controller 类下的所有方法都相当 于添加了@ResponseBody 注解 用于返回字符串或 json 数据
1.2.3 @RequestMapping(常用)
- 支持 Get 请求,也支持 Post 请求
1.2.4 @GetMapping
- RequestMapping 和 Get 请求方法的组合 只支持 Get 请求 Get 请求主要用于查询操作
1.2.5 @PostMapping
- RequestMapping 和 Post 请求方法的组合 只支持 Post 请求 Post 请求主要用户新增数据
1.2.6 @PutMapping
- RequestMapping 和 Put 请求方法的组合 只支持 Put 请求 Put 通常用于修改数据
1.2.7 @DeleteMapping
-
RequestMapping 和 Delete 请求方法的组合 只支持 Delete 请求 通常用于删除数据
-
/** * 该案例主要演示了使用 Spring 提供的不同注解接收不同类型的请求 */ //RestController 注解相当于加了给方法加了@ResponseBody 注解,所以是不能跳转页面的, 只能返回字符串或者 json 数据 @RestController public class MVCC ontroller { @GetMapping(value = "/query") public String get() { return "@GetMapping 注解,通常查询时使用"; } @PostMapping(value = "/add") public String add() { return "@PostMapping 注解,通常新增时使用"; } @PutMapping(value = "/modify") public String modify() { return "@PutMapping 注解,通常更新数据时使用"; } @DeleteMapping(value = "/remove") public String remove() { return "@DeleteMapping 注解,通常删除数据时使用"; } }
-
1.2.8 @ResponseBody
- 不加这个注解可以返回一个自定义html页面
- 加这个注解返回return后面的东西。
1.2 Spring Boot四大核心:
- 自动配置
- 起步依赖
- Actuator
- 命令行界面
1.3 核心配置文件
-
在SpringBoot中核心配置文件一般只有一个。如果这两种核心配置文件同时存在,那项目会优先读取application.properties中的配置文件。
-
application.properties
-
设置内嵌tomcat内嵌端口号:
-
server.port=9090
-
-
设置上下文根
-
server.servlet.context-path=/txzmy
-
-
修改前
-
修改后:
-
-
application.yml(.yaml)
-
设置内嵌tomcat端口号和上下文根:
-
在使用这种方式时,先删除application.properties,后新建一个file,核心文件的命名必须以application开头。这种方式类似与python的缩进。
-
server: port: 9090 servlet: context-path: /txzmy
-
1.4 多环境下配置核心文件
-
工作中的四种环境:开发环境,测试环境,准生产环境,生产环境。在不同的环境下同一个网页的访问网址不同,核心文件配置不同。
-
添加其他环境下的核心配置文件必须以application-开头。
-
#主核心配置文件 #激活使用的配置文件 #等号后面只需要跟已定的核心配置文件的名称 spring.profiles.active=dev
-
三种不同文件类型的核心配置文件写法相似。
1.5 自定义配置
1.5.1 获取自定义配置:
-
我们可以在核心配置文件或者其他文件里设置一些值,通过注解@value可以访问到这些值。
-
#主核心配置文件 #激活使用的配置文件 spring.profiles.active=dev #设置自定义的值 schoolName=CTGU stuName=tx #方法类 package com.txzmy.springboot; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @Controller public class Index { @Value("${schoolName}") public String schoolName; @Value("${stuName}") public String stuName; @RequestMapping(value = "/hello") public @ResponseBody String hello() { return "hello,"+stuName+" from "+schoolName; } }
-
通过域名http://localhost:7070/dev/hello访问结果:hello,tx from CTGU
-
1.5.2 将自定义配置映射到对象
-
在用@Value时我们只能一个一个的取值,我们可以通过@Component和@ConfigurationProperties将文件中的值映射到对象中。配置对象必须有统一的前缀。直接上代码:
-
#主核心配置文件 #激活使用的配置文件 spring.profiles.active=dev #设置自定义的值 school.Name=CTGU school.stuName=tx //被映射的类 #package com.txzmy.springboot; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; //将拿到的值交给spring容器管理 @Component //@ConfigurationProperties必须有个前缀,即上面设置的自定义值的前缀,后面可以不带这个前缀。 @ConfigurationProperties(prefix = "school") public class school { private String Name; private String stuName; public String getName() { return Name; } public void setName(String name) { Name = name; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } } //方法类 package com.txzmy.springboot; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @Controller public class Index { @Autowired public school school; @RequestMapping(value = "/hello") public @ResponseBody String hello() { return "hello,"+school.getStuName()+" from "+school.getName(); } }
-
运行结果:hello,tx from CTGU
-
1.6 SpringBoot集成JSP
1.6.1 创建存放JSP文件的文件夹:
- 在项目main文件夹下新建一个文件夹->在file菜单栏中选择Project Structure->选择Modules->在旁边的项目文件了选中刚刚创建的文件夹(用来存放JSP文件的文件夹)->点击右边中间的+号,再次选中刚刚创建的文件夹,最后apply再ok就完成了。
1.6.2 添加SpringBoot内嵌的Tomcat对JSp的解析依赖:
-
<!-- 引入SpringBoot内嵌的Tomcat对JSp的解析依赖,不添加解析不了--> <!-- 在这里我们仅仅展示JSP页面,只添加下面一个依赖--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jsper</artifactId> </dependency>
1.6.3 指定JSP编译的路径及文件夹项目:
-
<build> <!-- Springboot项目默认推荐使用的前端引擎是thymeleaf 现在我们要使用springboot集成jsp,手动指定jsp最后编译的路径 而且springboot集成jsp编译jsp的路径是springboot规定好的位置 MFTA-TNF /resources --> <resources> <resource> <!-- 源文件夹--> <directory>src/main/webapp</directory> <!--指定编译到META-INF/reserous--> <targetPath>META-INF/reserous</targetPath> <!--指定源文件夹的那个文件要编译--> <includes> <include>*.*</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
1.6.4 在核心配置文件里配置视图解析器:
-
核心配置文件:application.properties
-
#配置视图解析器 #配置前缀 spring.mvc.view.prefix=/ #配置后缀 spring.mvc.view.suffix=/jsp
-
@Controller public class Index { @RequestMapping(value = "/hello") public ModelAndView hello() { ModelAndView mv = new ModelAndView(); mv.addObject("message","Hello SpringBoot"); mv.setViewName("hello"); return mv; } }
-
2 Spring Boot框架Web开发:
2.1 集成Mybatis:
2.1.1 添加起步依赖:
-
<!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--MyBatis整合SpringBoot框架的起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency>
2.1.2 关于MySQL的安装参考推荐:
2.1.3 逆向工程:
-
Mybatis提供的逆向工程可以生成实体bean,映射文件,DAO接口:
-
需要添加的配置文件:
-
在项目的根目录下添加GeneratorMapper.xml文件,文件具体内容如下:
-
<?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> <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 --> <classPathEntry location="D:/mysql-downloads/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49.jar"/> <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 --> <context id="txzmy" targetRuntime="MyBatis3"> <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 配置数据库连接信息 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306" userId="root" password="Tx110304.."> </jdbcConnection> <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定 生成的 model 放在 eclipse 的哪个工程下面--> <javaModelGenerator targetPackage="comzmy.model" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> <property name="trimStrings" value="false" /> </javaModelGenerator> <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的 包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 --> <sqlMapGenerator targetPackage="comzmy.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包 名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 --> <javaClientGenerator type="XMLMAPPER" targetPackage="comzmy.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 数据库表名及对应的 Java 模型类名 --> <table tableName="student" domainObjectName="Student" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/> </context> </generatorConfiguration>
-
-
在项目文件pom.xml中添加依赖:
-
<!--MyBatis 集成 SpringBoot 框架起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!--MySQL 驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <!--指定配置资源的位置--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <!--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> </plugins>
-
-
在application.properties文件中配置数据库的相关信息:
-
#配置内嵌 Tomcat 端口号 server.port=9090 #配置项目上下文根 server.servlet.context-path=/txzmy #配置数据库的连接信息 #注意这里的驱动类有变化 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 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=Tx110304..
-
-
在右侧maven结构中选择Plugins->mybatis-generator->mybatis-generator:generate.双击mybatis-generator:generate.
-
2.2 Spring Boot实现RESTful
2.2.1 认识RESTful:
- REST(英文:Representational State Transfer,简称 REST) 一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器 交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次,REST 这个词,是 Roy Thomas Fielding 在他 2000 年的博士论文中提出的。 任何的技术都可以实现这种理念,如果一个架构符合 REST 原则,就称它为 RESTFul 架 构 。
- 比如我们要访问一个 http 接口:http://localhost:8080/boot/order?id=1021&status=1 采用 RESTFul 风格则 http 地址为:http://localhost:8080/boot/order/1021/1
2.2.2 Spring Boot开发RESTful:
-
Spring boot 开发 RESTFul 主要是几个注解实现:
- @PathVariable
- 获取 url 中的数据,该注解是实现 RESTful最主要的一个注解。
- @PostMapping
- 接收和处理 Post 方式的请求 。
- @DeleteMapping
- 接收 delete 方式的请求,可以使用 GetMapping 代替 。
- @PutMapping
- 接收 put 方式的请求,可以用 PostMapping 代替。
- @GetMapping
- 接收 get 方式的请求。
- @PathVariable
-
pom.xml添加内容:
-
<dependencies> <!--SpringBoot 框架 web 项目起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--MyBatis 集成 SpringBoot 框架起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!--MySQL 驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <!--指定配置资源的位置--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <!--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> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
-
application.yml 核心配置文件:
-
server: port: 8090 #设置 Tomcat 内嵌端口号 servlet: context-path: / #设置上下文根 #配置数据源 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBC CompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 username: root password: Tx110304..
-
2.3 SpringBoot集成Redis:
2.3.1 认识Reids:(源于百度百科)
-
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1]
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
2.3.2 添加依赖:
-
在Pom.xml添加操作redis数据类型的依赖:
<!--SpringBoot集成Redis的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
在SpringBoot核心配置文件中添加Redis的 配置(配置连接信息):
#redis连接信息 spring.redis.host= sring.redis.port= sring.redis.password=
2.3.3 相关类:
-
RestController类:
@RestController public class RedisController { @Autowired private StudentService studentService; @GetMapping(value = "/springboot/allStudentCount") public Object allStudentCount(HttpServletRequest request) { Long allStudentCount = studentService.queryAllStudentCount(); return "学生总人数:" + allStudentCount; } }
-
StudentService 接口:
public interface StudentService { /** * 获取学生总人数 * @return */ Long queryAllStudentCount(); }
-
在 StudentServiceImpl 中注入 RedisTemplate 并修改根据 id 获取学生的方法:
@Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Autowired private RedisTemplate<Object,Object> redisTemplate; @Override public Long queryAllStudentCount() { //设置 redisTemplate 对象 key 的序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); //从 redis 缓存中获取总人数 Long allStudentCount = (Long) redisTemplate.opsForValue().get("allStudentCount"); //判断是否为空 if (null == allStudentCount) { //去数据库查询,并存放到 redis 缓存中 allStudentCount = studentMapper.selectAllStudentCount(); redisTemplate.opsForValue().set("allStudentCount",allStudentCount,15, TimeUnit.SECONDS); } return allStudentCount; } }
-
StudentMapper 接口:
public interface StudentMapper { /** * 获取学生总人数 * @return */ Long selectAllStudentCount(); }
-
StudentMapper 映射文件:
<!--获取学生总人数--> <select id="selectAllStudentCount" resultType="java.lang.Long"> select count(*) from t_student </select>
-
启动类 Application:
-
在 SpringBoot 启动类上添加扫描数据持久层的注解并指定扫描包:
@SpringBootApplication @MapperScan(basePackages = "com.txzmy.mapper")//扫描数据持久层 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
2.4 集成dubbo:
2.4.1. 准备工作
创建一个Maven空项目,作为项目的父工程,此工程的子项目基于Spring Boot 2.0.5 实现
在父工程的pom.xml引入之后要创建的子工程
<modules>
<module>gmall-interface</module>
<module>user-service-provider</module>
<module>order-service-consumer</module>
</modules>
可以提前看一下工程结构
下面分别来实现子工程:(子工程的实现方式都是在gmall工程下新建Module)
2.4.2. 公共API
项目中共用的接口和POJO类,代码和之前一样,这里不再展开
2.4.3. 服务提供者
工程结构如下
引入依赖
<!-- 引入公共API,以实现其接口 -->
<dependency>
<groupId>com.zang</groupId>
<artifactId>gmall-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 引入spring-boot-starter以及dubbo和curator的依赖 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!-- Spring Boot相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
需要注意的是,根据jdk和Spring Boot版本的不同,dubbo-spring-boot-starter的版本需要有根据的选择
dubbo提供了@Service注解,可将类声明为提供方,省去了大量配置的麻烦
import com.alibaba.dubbo.config.annotation.Service;
import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.UserService;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Service //属于Dubbo的@Service注解,非Spring 作用:暴露服务
@Component
public class UserServiceImpl implements UserService {
@Override
public List<UserAddress> getUserAddressList(String userId) {
//省略
}}
通过属性配置的方式设置application.properties
#当前服务/应用的名字
dubbo.application.name=user-service-provider
#注册中心的协议和地址
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
#通信规则(通信协议和接口)
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#连接监控中心
dubbo.monitor.protocol=registry
#开启包扫描,可替代 @EnableDubbo 注解
##dubbo.scan.base-packages=com.zang.gmall
springboot容器根据配置启动服务提供方,这里需要添加 @EnableDubbo 注解
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 开启基于注解的dubbo功能(主要是包扫描@DubboComponentScan)
// 也可以在配置文件中使用dubbo.scan.base-package来替代 @EnableDubbo
@EnableDubbo
@SpringBootApplication
public class UserServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceProviderApplication.class, args);
}
}
提供方顺利启动
2.4.4. 服务消费者
消费者工程在初始化时设置为web项目,结构如下
引入和服务提供方同样的依赖,除此之外,添加springboot web模块的依赖。
<!-- springboot web模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
dubbo提供了@Reference注解,可替换@Autowired注解,用于引入远程服务
import com.alibaba.dubbo.config.annotation.Reference;
import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.OrderService;
import com.zang.gmall.service.UserService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Reference
UserService userService;
@Override
public List<UserAddress> initOrder(String userId) {
//代码省略
}}
配置文件application.properties
#避免和监控中心端口冲突,设为8081端口访问
server.port=8081
dubbo.application.name=order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry
启动类同样加上@EnableDubbo注解
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@SpringBootApplication
public class OrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceConsumerApplication.class, args);
}
}
为查看调用是否成功,新增控制层用于访问
import com.zang.gmall.bean.UserAddress;
import com.zang.gmall.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class OrderController {
@Autowired
OrderService orderService;
@ResponseBody //以json格式返回
@RequestMapping("/initOrder")
public List<UserAddress> initOrder(@RequestParam("uid") String userId){
return orderService.initOrder(userId);
}
}
2.4.5. 测试调用
启动消费方,在浏览器访问
调用成功
附:springboot也允许引用xml文件配置,方法是在启动类中加入如下注解
//@EnableDubbo
//引入配置信息
@ImportResource(locations="classpath:provider.xml")
@SpringBootApplication
public class UserServiceProviderApplication {
//略
}
3 Spring Boot下的非Web程序:
3.1 创建一个非Web程序:
3.1.1 方式一:
-
直接在 main 方法中,根据 SpringApplication.run()方 法获取返回的 Spring 容器对象,再获取业务 bean 进行调用:
-
//Application.java文件 package com.txzmy; import com.txzmy.TestInterface1.UserService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { /** * SpringBoot 程序启动后,返回值是 ConfigurableApplicationContext,它也是一个 Spring 容器对象 * 它其它相当于原来 Spring 中启动容器 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(""); */ //获取 SpringBoot 程序启动后的 Spring 容器 ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); //从 Spring 容器中获取指定 bean 的对象 UserService userService = (UserService) context.getBean("userServiceImpl"); //调用业务 bean 的方法 String sayHello = userService.SayHello(); System.out.println(sayHello); } } //UserService接口 package com.txzmy.TestInterface1; public interface UserService { String SayHello(); } //UserServiceImpl接口实现类 package com.txzmy.TestAchieve; import com.txzmy.TestInterface1.UserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService { @Override public String SayHello() { return "Hello"; } }
-
运行结果:
-
注意:
- 在getBean方法中,如果接口实现类的名称首字母是大写,则在getBean方法的参数中首字母必须换为小写。解决“No bean named 'UserServiceImpl' available”报错。
-
3.1.2 方式二:
-
Spring boot 的入口类实现 CommandLineRunner 接口。
-
//Application.java文件 package com.txzmy; //import javafx.application.Application; import com.txzmy.TestInterface1.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private UserService userService; @Override // 重写CommandLineRunner中的run方法 public void run(String... args) throws Exception { System.out.println(userService.SayHello()); } public static void main(String[] args) { SpringApplication.run(Application.class); } } //接口类和接口实现类和上面相同
-
运行结果:
-
3.2 关闭,修改SpringBoot启动logo:
3.2.1 关闭Logo:
-
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); //关闭启动 logo 的输出 springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args); } }
3.2.2 修改logo:
- 在 src/main/resources 放入 banner.txt 文件,该文件名字不能随意,文件中的内容就是要输出 的 logo ;
- 可 以 利 用 网 站 生 成 图 标 : https://www.bootschool.net/ascii 或 者 http://patorjk.com/software/taag/,将生成好的图标文字粘贴到 banner.txt 文件中,然后将关 闭 logo 输出的语句注释,启动看效果。
4 Spring Boot 使用拦截器:
4.1 使用拦截器的步骤:
-
定义一个拦截器,实现HandlerInterceptor接口。
-
package com.txzmy.interceptor; import com.txzmy.model.User; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("进入拦截器-----------------"); //编写业务中拦截的规则 //从session中获取用户的信息 User user = (User)request.getSession().getAttribute("user"); //判断用户是否登录 if(null==user) { response.sendRedirect(request.getContextPath()+"/user/error"); return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
-
-
创建一个配置类(即:在SpringMvc配置文件中使用MVC:拦截器标签)。
-
package com.txzmy.config; import com.txzmy.interceptor.UserInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration //定义此类为配置文件(即相当于之前的xml配置文件) public class InterceptorConfig implements WebMvcConfigurer { @Override //拦截器注册类,需要我们把自己定义的拦截器注册进去 public void addInterceptors(InterceptorRegistry registry) { //定义需要拦截的和不需要拦截的String容器 //要拦截user下面的所有的访问请求,必须用户登录后才可以访问 String[] addPathPatterns={ "/user/**" }; //要排除的路径,排除的路径说明用户不需要登陆也可以访问 String[] excludePathPatterns={ "/user/out","/user/error","/user/login" }; registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns); } }
-
-
请求页面类:
-
package com.txzmy.web; import com.txzmy.model.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/user") public class UserController { @RequestMapping(value = "/login") public @ResponseBody Object login(HttpServletRequest request) { //将用户信息放到session中 User user=new User(); user.setId(1001); user.setName("张满月"); request.getSession().setAttribute("user",user); return "login success"; } //该请求需要用户登录后才可以访问 @RequestMapping(value = "/center") public @ResponseBody Object center() { return "Center Message"; } //该请求不需要用户可以访问 @RequestMapping(value = "/out") public @ResponseBody Object out() { return "out Message"; } //如果用户未登录访问了需要登陆才可以访问的数据,会跳转至该请求 @RequestMapping(value = "/error") public @ResponseBody Object error() { return "error"; } }
-
-
用户类:
-
package com.txzmy.model; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
5 Spring Boot中使用Servlet:
5.1 Servlet:
5.1.1 认识Servlet:
- Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页.
5.1.2 Servlet 任务:
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
5.2 两种使用Servlet的方式:
5.2.1 方式一 通过注解方式实现:
-
MyServlet.java
-
package com.example.demo.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(urlPatterns = "/myServlet") public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("My SpringBoot Servlet"); response.getWriter().flush(); response.getWriter().close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
-
Application.java
-
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication //开启Spring配置 @ServletComponentScan(basePackages = "com.example.demo.Servlet") //指定要扫描的Servlet public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
-
5.2.2 方式二 通过 SpringBoot 的配置类实现(组件注册)
-
ServletConfiguration.java
-
package com.example.demo.Servlet; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ServletConfiguration { //@Bean 是一个方法级别上的注解,主要用在配置类里 /* * 相当于一个<beans> * <bean id="" class=""/> * </beans> * */ @Bean public ServletRegistrationBean servletRegistrationBean() { //将自定义 servlet 注册到注册 Servlet 类中,并指定访问路径 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(), "/MyServlet"); return servletRegistrationBean; } }
-
-
MyServlet.java
-
package com.example.demo.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; public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("My SpringBoot Servlet2222"); response.getWriter().flush(); response.getWriter().close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
-
application.java不变
6 Spring Boot中使用过滤器Filter
6.1 过滤器的作用:
- Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器
- Filter 过滤器它是 JavaEE 的规范。也就是接口
- Filter 过滤器它的作用是:拦截请求,过滤响应。
6.2 创建Filter的两种方法:
6.2.1 方式一 通过注解方式实现:
-
MyFilter.java
-
@WebFilter(urlPatterns = "/springboot/myFilter") //设置过滤的访问路径 public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("-------------您已进入过滤器---------------"); filterChain.doFilter(servletRequest,servletResponse); } }
-
-
Application文件
-
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @ServletComponentScan(basePackages = "com.demo.filter") @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }
-
-
结果:通过 .../springboot/myFilter...的访问路径全部无法访问。
6.2.2 方式二 通过 Spring Boot 的配置类实现:
-
FilterConfiguration.java
-
package com.example.demo.Filter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.FilterRegistration; @Configuration public class FilterConfiguration { @Bean public FilterRegistrationBean myFilterRegistration (){ //注册过滤器 FilterRegistrationBean filterRegistrationBean =new FilterRegistrationBean(new MyFilter()); //添加过滤路径 filterRegistrationBean.addUrlPatterns("/User/*"); return filterRegistrationBean; } }
-
-
MyFilter.java
-
package com.example.demo.Filter; import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("get access to filter"); filterChain.doFilter(servletRequest,servletResponse); } }
-
-
userController.java
-
package com.example.demo.Filter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class userController { @RequestMapping(value = "/User/one") public @ResponseBody String one() { return "one"; } @RequestMapping(value = "/two") public @ResponseBody String two() { return "two"; } }
-
7 Spring Boot 项目配置字符编码:
7.1 目的:
- 解决网页中的中文乱码问题,不需要用户手动更改浏览器的encoding。
7.2 两种配置字符编码的方式:
7.2.1 方式一: 使用传统的 Spring 提供的字符编码过滤器
-
MyServlet.java
-
package com.example.demo.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 MyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("张满月:Hello,demo"); //设置浏览器编码格式 resp.setContentType("text/html;character=utf-8"); resp.getWriter().flush(); resp.getWriter().close(); } }
-
-
配置类:
-
package com.example.demo.Servlet; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.CharacterEncodingFilter; @Configuration //定义此类为配置类 public class SystemConfiguration { @Bean public ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new MyServlet(),"/Servlet/MyServlet"); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { //设置字符编码过滤器 //CharacterEncoding 是由 Spring 提供的一个字符编码过滤器,之前是配置在web.xml 文件中 CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); //强制使用指定字符编码 characterEncodingFilter.setForceEncoding(true); //设置指定字符编码 characterEncodingFilter.setEncoding("utf-8"); //创建过滤器注册 bean FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(); //设置字符编码过滤器 filterRegistrationBean.setFilter(characterEncodingFilter); //设置字符编码过滤器路径 filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } }
-
-
application.properties
-
#关闭 springboot 的 http 字符编码支持 #只有关闭该选项后,spring 字符编码过滤器才生效 server.servlet.encoding.enabled=false
-
-
不设置解码方式中文可能会乱码。
7.2.2 方式二:在 application.properties 中配置字符编码(推荐)
-
核心配置文件application.properties:
-
#设置请求响应的字符编码 spring.http.encoding.enabled=true spring.http.encoding.force=true spring.http.encoding.charset=UTF-8
-
-
MyServlet.java
-
package com.example.demo.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("/ServletDemo") public class MyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("张满月:Hello,demo"); //设置浏览器编码格式 resp.setContentType("text/html;character=utf-8"); resp.getWriter().flush(); resp.getWriter().close(); } }
-
-
在主类中定义扫描路径:
-
@SpringBootApplication @ServletComponentScan(basePackages = "com.example.demo.Servlet") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
-
-
未设置前:
- 网页显示结果:????Hello,demo
-
设置后:
- 网页显示结果:张满月:Hello,demo
8 Spring Boot 打包与部署:
8.1 Spring Boot打war包部署:
8.1.1 准备:
-
将SpringBoot的项目的打包方式设置为war:
-
<groupId>com.example</groupId> <artifactId>demo</artifactId> <version>1.0.0</version> <packaging>war</packaging>
-
-
移除内嵌的tomcat模块,但是为了我们在本机测试方便,我们还需要引入它,所以配置如下:
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
-
-
添加tomcat-servelt-api依赖:
-
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>7.0.42</version> <scope>provided</scope> </dependency>
-
修改入口方法 继承一个SpringBootServletInitializer类,并且覆盖configure方法:
-
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class SpringDataJpaExampleApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringDataJpaExampleApplication.class); } public static void main(String[] args) { SpringApplication.run(SpringDataJpaExampleApplication.class, args); } }
-
-
添加war插件,用来自定义打包以后的war包的名称:
-
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <warSourceExcludes>src/main/resources/**</warSourceExcludes> <warName>springboot</warName> </configuration> </plugin>
-
-
8.1.2 打包步骤:
- maven->要打包的项目->Lifecycle->package
- 打包完成后项目下面会出现一个文件夹,里面.war文件就是打包好的文件。
8.1.3 使用tomcat启动打好的war包:
- 将war包复制到本机的tomcat里的webapps文件夹下,在bin中双击startup.bat启动服务。双击shutdown.bat可以关闭服务。
8.1.4 关于startup和shutdown文件闪退问题:
-
右键startup文件,编辑,在文件头添加:
-
SET JAVA_HOME=D:\java-web-spring\JAVA\ideaIU-2019\jdk1.8.0_31 SET TOMCAT_HOME=D:\java-web-spring\JAVA\ideaIU-2019\apache-tomcat-9.0.21
-
两个路径分别为jdk的路径和tomcat的路径。shutdown文件闪退操作相同。
-
8.2 SpringBoot打jar包:
8.2.1 准备:
-
在 pom.xml 文件中添加 Tomcat 解析 jsp 依赖
-
<!--SpringBoot 项目内嵌 tomcat 对 jsp 的解析包--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency>
-
-
在 pom.xml 文件中添加 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>
-
-
修改 application.properties 配置文件:
-
打jar包也将工程的核心配置文件一起打包,所以在核心配置文件里面设置的端口号起作用,而war包的上下文根是打包的项目名。
-
#设置内嵌 Tomcat 端口号 server.port=9090 #设置项目上下文根 server.servlet.context-path=/ #配置 jsp 的前/后缀 spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp
-
8.2.2 打包步骤:
- maven->要打包的项目->Lifecycle->package
- 打包完成后项目下面会出现一个文件夹,里面.jar文件就是打包好的文件。
8.2.3 启动打包好的工程:
- 启动jar包可以用内置的tomcat启动:
- 将jar包复制到某个文件夹内,在文件夹文件路径栏输入cmd进入窗口:
- 在输入java -jar +打包的项目名字.jar回车即可以启动项目。
8.3 Spring Boot 部署与运行方式总结:
-
➢在 IDEA 中直接运行 Spring Boot 程序的 main 方法(开发阶段)
-
用 maven 将 Spring Boot 安装为一个 jar 包,使用 Java 命令运行
java -jar springboot-xxx.jar
可以将该命令封装到一个 Linux 的一个 shell 脚本中(上线部署)
- 写一个 shell 脚本(run.sh): #!/bin/sh java -jar xxx.jar
- 赋权限 chmod 777 run.sh
- 启动 shell 脚本: ./run.sh
- 使用 Spring Boot 的 maven 插件将 Springboot 程序打成 war 包,单独部署在 tomcat 中运行(上 线部署常用)
9 SpringBoot 集成 logback 日志:
9.1 目的:
- 做故障定位;
- 显示程序运行状态。
9.2 参考:
10 Thymeleaf:
10.1 Thymeleaf简介:
- Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web 框架集成。与其它模板引擎相比,Thymeleaf 最大的特点是,即使不启动 Web 应用,也可以直接在浏览器中打开并正确显示模板页面 。
10.2 thymeleaf相关的方法:
10.2.1 设置前后缀(在核心配置文件中):
-
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html
10.2.2 开关thymeleaf的缓存(在核心配置文件中):
-
#设置缓存,默认为开启,建议在开发阶段关闭 thymeleaf 页面缓存,目的实时看到页面 spring.thymeleaf.cache=false
-
让页面随源码的改动而改变:
-
关掉thymeleaf缓存;
-
在Run/Debug Configurations窗口中修改On 'Update' action和On frame deactivation为Update resources.
-
相关实现:
-
//控制类 @Controller public class ThymeleafController { @RequestMapping(value = "/thymeleaf/index") public String index(Model model) { model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版!"); return "index"; } }
-
//thymeleaf模板 <body > <!--Thymeleaf 前端框架以 Html 为载体--> <span th:text="${data}"></span> <span th:text="${data}"></span> <p th:text="${data}"></p> <div th:text="${data}"></div> </body> </html>
-
这样在thymeleaf模板中修改 内的标签在网页上也会相应的动态修改(不用重启项目程序)。
-
-
-
10.3 thymeleaf变量表达式:
10.3.1标准变量表达式:
-
语法 ${...}
-
标准变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和 EL 中的 ${} 相 同。Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据。
-
例子:
-
user类
-
package com.example.model; public class user { private int num; private String name; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
-
-
UserController类:
-
package com.example.web; import com.example.model.user; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; @Controller public class UserController { @RequestMapping(value = "/user/detail") public String message(Model model) { user user = new user(); user.setName("KB"); user.setNum(24); model.addAttribute("user",user); return "message"; } }
-
message.html:
-
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="${user.getName()}"> message showed:</div> PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="${user.getName()}"> message showed:</div> </body> </html>
-
-
核心配置文件:
-
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html #设置缓存 spring.thymeleaf.cache=false
-
-
结果:
-
PlayerNum :
24
PlayerName:
KB
PlayerNum :
24
PlayerName:
KB
-
-
-
10.3.2 选择变量表达式:
-
语法:*{...}
-
说明:
- 选择变量表达式,也叫星号变量表达式,使用 th:object 属性来绑定对象
- 选择表达式首先使用 th:object 来绑定后台传来的 User 对象,然后使用 * 来代表这个对 象,后面 {} 中的值是此对象中的属性。 选择变量表达式 *{...} 是另一种类似于标准变量表达式 ${...} 表示变量的方法
- 选择变量表达式在执行时是在选择的对象上求解,而${...}是在上下文的变量 Model 上求 解,这种写法比标准变量表达式繁琐。
-
示例:
-
<div th:Object="${user}"> PlayNum :<span th:text="*{getNum()}"></span><br/> PlayerName:<span th:text="*{getName()}"></span> </div>
-
其他类和上面一样。
-
10.3.3 标准变量表达式和选择变量表达式混合使用
-
标准变量和选择变量表达式可以混合使用,也可以不混合使用,使用 th:object 进行对 象的选择,也可以直接使用 *{...} 获取数据:
-
示例:
-
PlayerNum :<div th:text="*{user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="*{user.getName()}"> message showed:</div>
-
10.4 thymeleaf URL路径表达式:
10.4.1 绝对路径:
-
不带参数:
-
<h1>URL 路径表达式:@{...}</h1> <h2>绝对路径(没有参数)</h2> <a th:href="@{http://localhost:8080/thymeleaf/info}">查看:绝对路径</a>
-
-
带参数:
-
<h2>绝对路径(路径中有参数)</h2> <a th:href="@{'http://localhost:8080/thymeleaf/user/info?id=' + ${user.id}}">查看用户信息:绝对路径(带参数)</a>
-
-
不推荐使用:路径写死。
10.4.2 相对路径:
-
不带参数:
-
<h2 style="color: red">实际开发推荐使用:相对路径(没有参数)</h2> <a th:href="@{/thymeleaf/info}">查看:相对路径</a>
-
-
带参数:
-
:
- 先请求一个带有跳转标签的网址,点击click就会再请求一个带参数的网址。
-
user类:
-
package com.example.model; public class user { private int num; private String name; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
-
UserController类:
-
package com.example.web; import com.example.model.user; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; @Controller public class UserController { // public ModelAndView message( ) //// { //// user user = new user(); //// user.setNum(30); //// user.setName("SC"); //// ModelAndView modelAndView =new ModelAndView(); //// modelAndView.setViewName("userInfomation"); //// modelAndView.addObject("userNum",user.getNum()); //// modelAndView.addObject("userName",user.getName()); //// return modelAndView; //// } @RequestMapping(value = "/user/detail") public String message(Model model) { user user =new user(); user.setName("KB"); user.setNum(24); model.addAttribute("user",user); return "message"; } @RequestMapping(value = "/user/Info") public @ResponseBody String userInfo(int num,String name) { return "num:"+num+" Name:"+name; } }
-
-
message.html
-
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a th:href ="@{/user/Info(num=${user.getNum()},name=${user.getName()})}">click</a> </body> </html>
-
-
核心配置文件:
-
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html #设置缓存 spring.thymeleaf.cache=false server.servlet.context-path=/url
-
-
篇幅好像超了,余下见下一篇:
https://www.cnblogs.com/txzmy/p/16212382.html
10.5 thymeleaf常见属性:
10.5.1 th:action:
- th:action 定义后台控制器的路径,类似标签的 action 属性,主要结合 URL 表达式,获 取动态变量;
10.5.2 th:method:
-
设置请求方法
-
<form th:action="@{/user/login}" th:method="post"></form>
-
10.5.3 th:href:
-
定义超链接,主要结合 URL 表达式,获取动态变量.
-
<a href="http://www.baidu.com">超链接百度</a><br/> <a th:href="'http://www.baidu.com?id=' + ${user.id}">th:href 链接</a>
-
10.5.4 th:src:
-
用于外部资源引入,比如