spring-boot整合场景实例分析

Spring Boot

一、简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

二、创建spring-boot项目

【1】通过idea的脚手架工具创建

在这里插入图片描述

【2】通过idea的maven项目创建

在这里插入图片描述

【3】Pom文件介绍

(1)引入父级依赖

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

spring boot的父级依赖,只有继承它的项目才是spring boot项目。

spring-boot-starter-parent是一个特殊的starter,它用来提供相关的mavern默认依赖,使用它之后,常用的依赖包可以省去version标签

(2)引入启动器依赖

如果是web项目引入

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

(3)引入打包插件

<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

spring-boot-maven-plugin插件是将springboot的应用程序打包成jar包的插件,将所有应用启动运行所需要的jar包都包含进来,从逻辑上将具备独立运行的条件,运行 mvn package后,可以使用java -jar命令直接允许。

【4】启动类

springboot 的启动类的作用是启动springboot项目,基于Main方法运行。启动类在启动时会自动扫描该类所在的路径下所有@Controller,@Service,@Component等直接。所以启动类的位置应放在包的根目录下。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootDemoApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}

启动类和启动器的区别:启动类表示项目启动的入口,启动器表示jar包的坐标

【5】启动器

spring boot将所有的功能场景都抽取出来,做成一个一个的starter启动器,只需要在项目里面引入这些starter相关的场景所有依赖都会自动导入进来,要用什么功能就导入什么场景,在jar包管理上非常方便,最终实现一站式开发。

spring boot 提供了多达44个启动器

1)spring-boot-starter
这是Spring Boot的核心启动器,包含了自动配置、日志和YAML。

2)spring-boot-starter-actuator
帮助监控和管理应用。

3)spring-boot-starter-amqp
通过spring-rabbit来支持AMQP协议(Advanced Message Queuing Protocol)。

4)spring-boot-starter-aop
支持面向方面的编程即AOP,包括spring-aop和AspectJ。

5)spring-boot-starter-artemis
通过Apache Artemis支持JMS的API(Java Message Service API)。

6)spring-boot-starter-batch
支持Spring Batch,包括HSQLDB数据库

7)spring-boot-starter-cache
支持Spring的Cache抽象。

8)spring-boot-starter-cloud-connectors
支持Spring Cloud Connectors,简化了在像Cloud Foundry或Heroku这样的云平台上连接服务。

9)spring-boot-starter-data-elasticsearch
支持ElasticSearch搜索和分析引擎,包括spring-data-elasticsearch。

10)spring-boot-starter-data-gemfire
支持GemFire分布式数据存储,包括spring-data-gemfire。

11)spring-boot-starter-data-jpa
支持JPA(Java Persistence API),包括spring-data-jpa、spring-orm、hibernate

12)spring-boot-starter-data-MongoDB
支持MongoDB数据,包括spring-data-mongodb。

13)spring-boot-starter-data-rest
通过spring-data-rest-webmvc,支持通过REST暴露Spring Data数据仓库。

14)spring-boot-starter-data-solr
支持Apache Solr搜索平台,包括spring-data-solr。

15)spring-boot-starter-freemarker
支持FreeMarker模板引擎。

16)spring-boot-starter-groovy-templates
支持Groovy模板引擎。

17)spring-boot-starter-hateoas
通过spring-hateoas支持基于HATEOAS的RESTful Web服务。

18)spring-boot-starter-hornetq
通过HornetQ支持JMS。

19)spring-boot-starter-integration
支持通用的spring-integration模块。

20)spring-boot-starter-jdbc
支持JDBC数据库。

21)spring-boot-starter-jersey
支持Jersey RESTful Web服务框架。

22)spring-boot-starter-jta-atomikos
通过Atomikos支持JTA分布式事务处理。

23)spring-boot-starter-jta-bitronix
通过Bitronix支持JTA分布式事务处理。

24)spring-boot-starter-mail
支持javax.mail模块。

25)spring-boot-starter-mobile
支持spring-mobile。

26)spring-boot-starter-mustache
支持Mustache模板引擎。

27)spring-boot-starter-Redis
支持Redis键值存储数据库,包括spring-redis。

28)spring-boot-starter-security
支持spring-security。

29)spring-boot-starter-social-facebook
支持spring-social-facebook

30)spring-boot-starter-social-linkedin
支持pring-social-linkedin

31)spring-boot-starter-social-twitter
支持pring-social-twitter

32)spring-boot-starter-test
支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。

33)spring-boot-starter-thymeleaf
支持Thymeleaf模板引擎,包括与Spring的集成。

34)spring-boot-starter-velocity
支持Velocity模板引擎。

35)spring-boot-starter-web
S支持全栈式Web开发,包括Tomcat和spring-webmvc。

36)spring-boot-starter-websocket
支持WebSocket开发。

37)spring-boot-starter-ws
支持Spring Web Services。

Spring Boot应用启动器面向生产环境的还有2种,具体如下:

38)spring-boot-starter-actuator
增加了面向产品上线相关的功能,比如测量和监控。

39)spring-boot-starter-remote-shell
增加了远程ssh shell的支持。

最后,Spring Boot应用启动器还有一些替换技术的启动器,具体如下:

40)spring-boot-starter-jetty
引入了Jetty HTTP引擎(用于替换Tomcat)。

41)spring-boot-starter-log4j
支持Log4J日志框架。

42)spring-boot-starter-logging
引入了Spring Boot默认的日志框架Logback。

43)spring-boot-starter-tomcat
引入了Spring Boot默认的HTTP引擎Tomcat。

44)spring-boot-starter-undertow
引入了Undertow HTTP引擎(用于替换Tomcat)。

【6】配置文件

spring boot提供了一个名称为application的全局配置文件,支持两种格式properties格式和YAML格式

(1)配置的格式

application.properties配置server端口号实例

server.port=8080

yaml格式配置

application.yml

server:
  port: 8887

yaml格式的要求

大小写敏感

使用缩进代表层级关系

相同的部分只能出现一次

(2)配置文件存放的位置

当前根目录中

当前根目录下的一个/config子目录中

resources即classpath的根路径中

resources即classpath的根路径下的/config目录中

在上面这些目录中spring boot都能找到并加载配置文件

(3)配置文件的加载顺序

同一个目录下,既有application.properties 又有application.yml默认先读取application.properties

如果同一个配置属性,在多个配置文件中都配置了,默认使用第一个读取到的,后面读取的不覆盖前面读取的。

当前根目录下/config > 当前根目录 > resources 路径下的/config > resources 路径下的配置

(4)配置文件中的占位符

语法:${}

作用:获取框架提供的方法如:random.int等;将配置文件中的键的值赋值给另一个键

实例:生成随机数

${random.value} 类似uuid随机数,没有“-”连接

${random.int} 随机生成一个整数

${random.int(100,200)} 随机生成一个100到200之间的整数

${random.long} 随机生成一个长整型

${random.long(100,200)}

${random.uuid} 生成一个uuid,有短杆连接

【7】bootstrap配置文件

spring boot有两种上下文对象,一种是bootstrap,另一种是application配置,bootstrap是应用程序的父上下文,即bootstrap加载优先于application。bootstrap主要用于从额外的资源加载配置信息,还可以在本地外部废纸文件中解密属性。bootstrap里面的属性会优先加载,也不能被本地相同的配置覆盖。

特征:由父ApplicationContext加载,比application优先加载;属性不能被覆盖

应用场景:

1、使用spring cloud config做配置中心时,需要bootstrap配置文件中添加链接到配置中心的配置属性来加载外部配置中心的配置信息

2、一些固定不能被覆盖的属性

3、一些加密解密的场景

【8】spring boot 的核心注解

(1) @SpringBootApplication

是spring boot的启动类;

@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponetScan

(2) @SpringBootConfiguration

@SpringBootConfiguration注解是@Configuration注解的派生注解,和@Configuration注解的功能一致,标注该类是一个配置类,只不过@SpringBootConfiguration是spring boot的注解,而@Configuration是spring的注解。

(3)@Configuration

通过bean对象的操作替代spring中的xml文件

(4)@EnableAutoConfiguration

spring boot 自动配置:尝试根据添加的jar依赖自动配置spring应用。是@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)注解的组合

(5) @AutoConfigurationPackage

@AutoConfigurationPackage自动注入主类下所在包下所有加了注解的类,像@Controller,@Service和配置类@Configuration

(6)@Import({AutoConfigurationImportSelector.class})

直接导入普通的类,导入实现了ImportSelector接口的类,导入实现了ImportBeanDefinitionRegister接口的类

(7)@ComponentScan

组件扫描,可自动发现和装配一些bean

(8)@ConfigurationPropertiesScan

扫描配置属性。@EnableConfigurationProperties注解使用@ConfigurationPropertiesScan注解类生效。

【9】spring boot 在controller中常用注解

(1)@RestController

@RestController = @Controller + @ResponseBody

该注解controller中的方法无法返回页面,返回的是return中的内容。

(2)GetMapping

@GetMapping = @RequestMapping(method = RequestMethod.GET)

(2)PostMapping

@GetMapping = @RequestMapping(method = RequestMethod.POST)

(2)PutMapping

@GetMapping = @RequestMapping(method = RequestMethod.PUT)

(2)DeleteMapping

@GetMapping = @RequestMapping(method = RequestMethod.DELETE)

三、Spring boot 整合web层技术

【1】整合servlet

(1)方式1:通过注解扫描完成servlet组件的注册

创建servlet

@WebServlet(name = "firstServlet", urlPatterns = {
    
    "/hello"})
public class FirstServlet extends HttpServlet {
    
    

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
    
    
        System.out.println("first servlet");
    }
}

修改启动类

@SpringBootApplication
@ServletComponentScan // 在启动时会扫描@WebServlet,@WebFilter,@WebListener注解
public class SpringbootDemoApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}

(2)方式2:通过配置类

@SpringBootConfiguration
public class ServletConfiguration {
    
    

    @Bean
    public ServletRegistrationBean getSecondServlet() {
    
    
        ServletRegistrationBean servletConfiguration = new ServletRegistrationBean(new SecondServlet());
        servletConfiguration.addUrlMappings("/second");
        return servletConfiguration;
    }

}

【2】整合Filter

(1)方式1:通过注解扫描完成filter组件注册

创建Filter

@WebFilter(filterName = "firstFilter", urlPatterns = {
    
    "/firstFilter"})
//@WebFilter(filterName = "firstFilter", urlPatterns = {"*.do", "*.html"})
public class FirstFilter implements Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
        System.out.println("first filter");
    }

    @Override
    public void destroy() {
    
    

    }
}

修改启动类

@ServletComponentScan 同样支持扫描@WebFilter注解

(2)方式2:通过Configuration类

@SpringBootConfiguration
public class FilterConfiguration {
    
    

    @Bean
    public FilterRegistrationBean getSecondFilter() {
    
    
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new SecondFilter());
        filterRegistrationBean.addUrlPatterns("/secondFilter");
        return filterRegistrationBean;
    }
}

【3】整合listener

(1)方式1:通过注解扫描完成listener组件注册

编写listener

@WebListener
public class FirstListener implements ServletContextListener {
    
    

    public void contextInitialized(ServletContextEvent sce) {
    
    
        System.out.println("first listener");
    }

    public void contextDestroyed(ServletContextEvent sce) {
    
    
    }

}

修改启动器配置,添加@ServletComponentScan

(2)方式2:通过配置类

@SpringBootConfiguration
public class ListenerConfiguration {
    
    

    @Bean
    public ServletListenerRegistrationBean getSecond() {
    
    
        ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
        bean.setListener(new SecondListener());
        return bean;
    }
}

【4】访问静态资源

在spring boot项目中没有常规web开发中的webContent目录,只有src目录,在resources目录下有两个文件夹static和templates。在static目录下存放静态页面、图片、js、css等,templates存放动态页面需要通过controller跳转访问,不能直接访问。

(1)static目录

spring boot可以直接通过文件名访问静态资源,即static目录下的资源

(2)templates目录

在spring boot中不推荐使用jsp作为视图层技术,而是用thymeleaf模板引擎做动态页面,因为jsp渲染是在服务端实现的所以效率低,而thymeleaf和freemarker是在客户端渲染的效率更高。

(3)springboot访问静态资源的位置

classpath:/MATE-INF/resources/

classpath:/resources/

classpath:/static/

classpath:/public/

上述这些目录下存放静态资源springboot都能访问到

(4)自定义静态资源位置

spring.resources.static-locations=classpath:/templates

【5】文件上传

1、创建Controller类

@RestController
public class FileUploadController {
    
    

    @PostMapping("/uploadFile")
    public String uploadFile(MultipartFile file) {
    
    
        System.out.println(file.getName());
        try {
    
    
            file.transferTo(new File("d:/"+file.getOriginalFilename()));
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "success";
    }

}

2、页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>uploadFile</title>
</head>
<body>
<form action="/uploadFile" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

3、通过配置修改文件大小

默认单个文件最大为1M,一个请求中所有文件大小最大为10M;通过下面配置可进行修改

spring.servlet.multipart.max-file-size=2M
spring.servlet.multipart.max-request-size=20M

【6】spring boot整合freemarker

(1)项目创建

在这里插入图片描述

修改配置让templates可以创建htm文件

在这里插入图片描述

(2)启动器依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-freemarker</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

(3)创建controller

@Controller
public class PageController {
    
    

    @GetMapping("/showUsers")
    public String showUsers(Model model) {
    
    
        List<User> userList = new ArrayList<>();
        User user1 = new User("zhangsan", "18", "girl");
        User user2 = new User("lisi", "19", "boy");
        User user3 = new User("wangwu", "17", "girl");
        User user4 = new User("malu", "16", "boy");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        model.addAttribute("userList", userList);
        return "users";
    }
}

(4)页面测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>freemarker测试</title>
</head>
<body>
<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
    </tr>
    <#list userList as user>
        <tr>
            <td>${user.userName}</td>
            <td>${user.userAge}</td>
            <td>${user.userSex}</td>
        </tr>
    </#list>
</table>
</body>
</html>

(5)freemarker配置

因为默认是.hftl,所以后缀不是此格式要修改

spring.freemarker.suffix=.ftl

【7】spring boot 整合thymeleaf

(1)thymeleaf介绍

Thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发。它是一个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,该作者还是Java加密库Jasypt的作者。

Thymeleaf提供了一个用于整合Spring MVC的可选模块,在应用开发中,你可以使用Thymeleaf来完全代替JSP,或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。

(2)项目构建

和freemarker一样,启动器依赖的模板引擎选择thymeleaf

(3)启动器依赖
<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>

(3)示例

controller

@Controller
public class PageController {
    
    

    @GetMapping("/index")
    public String index(Model model) {
    
    
        model.addAttribute("msg", "hello world");
        return "index";
    }
}

index页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>

<span th:text="${msg}"></span><br>

</body>
</html>
(4)thymeleaf语法讲解

命名空间:xmlns:th=“http://www.thymeleaf.org”

A 、字符串与变量输出操作

变量名 解释
th:text 在页面输出值
th:value 可以将一个值放入到input标签的value中

B、字符串操作

thymeleaf提供了一些内置对象,内置对象可以直接在模板中使用,通过#号引用。

内置对象使用语法:

1)引用内置对象需使用#

2)大部分内置对象的名称都以s结尾。如:strings、numbers、dates

变量名 解释
${strings.isEmpty(key)} 判断字符串是否为空
${strings.contains(msg, ‘T’)} 判断字符串是否包含子串
${strings.startsWith(msg, ‘T’)} 判断字符串是否以子串开头
${strings.endsWith(msg, ‘T’)} 判断字符串是否以子串结尾
${strings.toUpperCase(msg)} 字符串转大写
${strings.toLowerCase(msg)} 字符串转小写

C、日期格式化处理

变量 解释
${#dates.format(key)} 格式化日志,默认以浏览器默认语言为格式化标准
${#dates.format(key, ‘yyyy-MM-dd’)} 按照自定义的格式做日期转换
${#dates.year(key)} 获取日期的年
${#dates.month(key)} 获取日期的月
${#dates.day(key)} 获取日期的日

D、条件判断

变量 解释
th:if 条件判断
th:switch / th:case 与java中的switch语句等效,有条件的显示匹配的内容。如果有多个匹配结果只选择第一个显示。th:case="*"表示java中switch的default。

E、迭代遍历集合

变量 解释
th:each 迭代器,用于循环迭代集合

th:each状态变量,通过状态变量获取

index:当前迭代器的索引从0开始

count:当前迭代对象的计数从1开始

size:被迭代对象的长度

odd/even:布尔值,当前循环是否是基数或者偶数 从0开始

first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false

last:布尔值,当前循环的是否是最后一条,如果是返回true否则返回false

controller实例

@Controller
public class PageController {
    
    

    @GetMapping("/index")
    public String index(Model model) {
    
    
        model.addAttribute("msg", "hello world");
        List<User> userList = new ArrayList<>();
        User user1 = new User("zhangsan", "18", "girl");
        User user2 = new User("lisi", "19", "boy");
        User user3 = new User("wangwu", "17", "girl");
        User user4 = new User("malu", "16", "boy");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        model.addAttribute("userList", userList);
        return "index";
    }
}

页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>

<span th:text="${msg}"></span><br>

<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
        <td>下标</td>
        <td>偶数</td>
        <td>奇数</td>
        <td>大小</td>
        <td>起始</td>
        <td>结尾</td>
    </tr>
    <tr th:each="user,statu : ${userList}">
        <td th:text="${user.userName}"></td>
        <td th:text="${user.userAge}"></td>
        <td th:text="${user.userSex}"></td>
        <td th:text="${statu.index}"></td>
        <td th:text="${statu.odd}"></td>
        <td th:text="${statu.even}"></td>
        <td th:text="${statu.size}"></td>
        <td th:text="${statu.first}"></td>
        <td th:text="${statu.last}"></td>
    </tr>
</table>

</body>
</html>

F、迭代map

<span>map遍历</span>
<table>
    <tr>
        <td>key</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
    </tr>
    <tr th:each="user : ${userMap}">
        <td th:text="${user.key}"></td>
        <td th:text="${user.value.getUserName()}"></td>
        <td th:text="${user.value.getUserAge()}"></td>
        <td th:text="${user.value.getUserSex()}"></td>
    </tr>
</table>

G、操作域对象

1、HttpServletRequest域

request.setAttribute("requestAttr", "requestAttr1");
httpServletRequest1:<span th:text="${#httpServletRequest.getAttribute('requestAttr')}"></span>
httpServletRequest2:<span th:text="${#request.getAttribute('requestAttr')}"></span>

2、HttpSession域

request.getSession().setAttribute("sessionAttr", "sessionAttr");
httpSession1:<span th:text="${#httpSession.getAttribute('sessionAttr')}"></span>
httpSession2:<span th:text="${session.sessionAttr}"></span>

3、ServletContext域

request.getSession().getServletContext().setAttribute("servletCtx", "servletCtxAttr");
ServletContext1:<span th:text="${#servletContext.getAttribute('servletCtx')}"></span>
ServletContext2:<span th:text="${application.servletCtx}"></span>

示例

controller

@Controller
public class OperationFileController {
    
    

    @GetMapping("/yu")
    public String yu(HttpServletRequest request, Model model) {
    
    
        request.setAttribute("requestAttr", "requestAttr1");
        request.getSession().setAttribute("sessionAttr", "sessionAttr");
        request.getSession().getServletContext().setAttribute("servletCtx", "servletCtxAttr");
        return "yu";
    }
}

页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
httpServletRequest1:<span th:text="${#httpServletRequest.getAttribute('requestAttr')}"></span>
httpServletRequest2:<span th:text="${#request.getAttribute('requestAttr')}"></span>

httpSession1:<span th:text="${#httpSession.getAttribute('sessionAttr')}"></span>
httpSession2:<span th:text="${session.sessionAttr}"></span>

ServletContext1:<span th:text="${#servletContext.getAttribute('servletCtx')}"></span>
ServletContext2:<span th:text="${application.servletCtx}"></span>

</body>
</html>

H、URL表达式

1、语法

在Thymeleaf中URL表达式的语法格式为@{}

2、URL类型

路径类型 实例 解释
绝对路径 <a th:href="@{http://www.baidu.com}">绝对路径打开百度</a> web的绝对路径
相对路径1 <a th:href="@{/show}">相对路径1</a> 相对于当前项目的根路径
相对路径2 <a th:href="@{~/otherProject/resources}">相对路径2</a> 相对于其他项目的路径,如果一个容器中存在多个项目的场景

3、URL中的参数传递

传参类型
<a th:href="@{/show?id=1&name='zhangsan'}">普通URL格式传参</a>
<a th:href="@{/show(id=1,name='zhangsan')}">普通URL格式传参</a>
<a th:href="@{'/show?id=' + ${id} + '&name=' + ${zhangsan}}">普通URL格式传参</a>
<a th:href="@{/show(id=${id},name=${name})}">普通URL格式传参</a>
<a th:href="@{/show/{id}(id=1)}">restful格式传参</a>
<a th:href="@{/show/{id}/(id=1,name='zhansan')}">restful格式传参</a>
<a th:href="@{/show/{id}/{name}(id=1,name='zhansan')}">restful格式传参</a>
<a th:href="@{/show/{id}(id=${id},name=${name})}">restful格式传参</a>

I、配置thymeleaf

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8

四、spring boot整合持久层技术

【1】整合jdbc

(1)项目依赖
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<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>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--跟换成阿里德鲁伊数据源-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
		</dependency>
(2)配置数据源
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=root

配置方式1:jdbc.properties配置;可以不配置在application.properties

@Configuration
@PropertySource("classpath:/config/jdbc.properties")
public class JdbcConfiguration {
    
    

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource getDataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(this.url);
        dataSource.setPassword(this.password);
        dataSource.setUsername(this.username);
        dataSource.setDriverClassName(this.driver);
        return dataSource;
    }
}

配置方式2:前面配置方式1中jdbc.properties中的配置必须配置在application.properties中

属性类:属性名称必须和配置的名称一致

@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
    
    

    private String driverClassName;

    private String url;

    private String username;

    private String password;

    public String getDriverClassName() {
    
    
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
    
    
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
    
    
        return url;
    }

    public void setUrl(String url) {
    
    
        this.url = url;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getPassword() {
    
    
        return password;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }
}

配置类

@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfiguration1 {
    
    

    @Autowired
    private JdbcProperties jdbcProperties;

    @Bean
    public DataSource getDataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(jdbcProperties.getUrl());
        dataSource.setPassword(jdbcProperties.getPassword());
        dataSource.setUsername(jdbcProperties.getUsername());
        dataSource.setDriverClassName(jdbcProperties.getDriverClassName());
        return dataSource;
    }
}

配置方式3:优雅配置

前提是jdbc中的属性和dataSource中需要注入的属性名称一致;并且属性配置再application配置文件中而不能配置在其他的配置文件中

@Configuration
public class JdbcConfiguration2 {
    
    

    @Bean
    @ConfigurationProperties(prefix = "jdbc")
    public DataSource getDataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}
(3)通过spring boot配置文件配置数据源

在spring boot1.x中spring-boot-starter-jdbc启动器中默认使用org.apache.jdbc.pool.DataSource作为数据源

在spring boot2.x中默认使用com.zaxxer.hikariDataSource作为数据源

可以通过修改配置来更改默认的数据源,通过这种配置方式无需再像前面三种一样配置特别的数据源

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
(4)增删改查

数据库建表等基础操作略过

A、添加数据

controller

    @RequestMapping("/addUser")
    @ResponseBody
    public String addUser(User user) {
    
    
        try {
    
    
            userService.insert(user);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

页面

<form action="/addUser" method="post">
    姓名:<input type="text" name="userName" /> <br>
    年龄:<input type="text" name="userAge"/> <br>
    性别:<input type="text" name="userSex"/> <br>
    <input type="submit" value="提交"/>
</form>

dao

    @Override
    public void addUser(User user) {
    
    
        String sql = "insert into user (name, age, sex) values (?, ?, ?)";
        jdbcTemplate.update(sql, user.getUserName(), user.getUserAge(), user.getUserSex());
    }

B、查询数据

controller

    @RequestMapping("/getAllUser")
    public String getAllUser(Model model) {
    
    
        List<User> userList = userService.getAll();
        model.addAttribute("userList", userList);
        return "userList";
    }

页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a th:href="@{/userAdd}">新增</a> <br>

<table border="1">
    <tr>
        <td>ID</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
        <td>修改</td>
    </tr>
    <tr th:each="user,statu : ${userList}">
        <td th:text="${user.id}"></td>
        <td th:text="${user.userName}"></td>
        <td th:text="${user.userAge}"></td>
        <td th:text="${user.userSex}"></td>
        <td><a th:href="@{/userInfo(id=${user.id})}">修改</a></td>
        <td><a th:href="@{/deleteUser(id=${user.id})}">删除</a></td>
    </tr>
</table>
</body>
</html>

dao

 @Override
    public List<User> queryAll() {
    
    
        String sql = "select * from user";
        return jdbcTemplate.query(sql, new RowMapper<User>() {
    
    
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
    
    
                User user = new User();
                user.setId(resultSet.getLong("id"));
                user.setUserName(resultSet.getString("name"));
                user.setUserAge(resultSet.getInt("age"));
                user.setUserSex(resultSet.getString("sex"));
                return user;
            }
        });
    }

C、预跟新数据

controller

    @RequestMapping("/userInfo")
    public String userInfo(Model model, Long id) {
    
    
        User user = userService.getUser(id);
        model.addAttribute("user", user);
        return "userInfo";
    }

页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/updateUser" method="post">
    姓名:<input type="text" name="userName" th:value="${user.userName}"/> <br>
    年龄:<input type="text" name="userAge" th:value="${user.userAge}"/> <br>
    性别:<input type="text" name="userSex" th:value="${user.userSex}"/> <br>
    <input type="hidden" name="id" th:value="${user.id}"/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

dao

@Override
    public User getUser(Long id) {
    
    
        String sql = "select * from user where id = ?";
        User user = new User();
        Object[] arr = new Object[]{
    
    id};
        jdbcTemplate.query(sql, arr, new RowCallbackHandler() {
    
    
            @Override
            public void processRow(ResultSet resultSet) throws SQLException {
    
    
                user.setId(resultSet.getLong("id"));
                user.setUserName(resultSet.getString("name"));
                user.setUserAge(resultSet.getInt("age"));
                user.setUserSex(resultSet.getString("sex"));
            }
        });
        return user;
    }

D、修改数据

controller

 @RequestMapping("/updateUser")
    @ResponseBody
    public String updateUser(User user) {
    
    
        try {
    
    
            userService.update(user);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

dao

@Override
    public void update(User user) {
    
    
        String sql = "update user set name=?, age=?, sex=? where id=?";
        jdbcTemplate.update(sql, user.getUserName(), user.getUserAge(), user.getUserSex(), user.getId());
    }

E、删除数据

controller

    @RequestMapping("/deleteUser")
    public String deleteUser(Long id) {
    
    
        userService.delete(id);
        return "redirect:/getAllUser";
    }

dao

@Override
    public void delete(Long id) {
    
    
        String sql = "delete from user where id = ?";
        jdbcTemplate.update(sql, id);
    }

完整实例

service和entity及页面省略,参考前面内容

controller

@Controller
public class UserController {
    
    

    @Autowired
    private UserService userService;

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

    @RequestMapping("/addUser")
    @ResponseBody
    public String addUser(User user) {
    
    
        try {
    
    
            userService.insert(user);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

    @RequestMapping("/updateUser")
    @ResponseBody
    public String updateUser(User user) {
    
    
        try {
    
    
            userService.update(user);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

    @RequestMapping("/getAllUser")
    public String getAllUser(Model model) {
    
    
        List<User> userList = userService.getAll();
        model.addAttribute("userList", userList);
        return "userList";
    }

    @RequestMapping("/userInfo")
    public String userInfo(Model model, Long id) {
    
    
        User user = userService.getUser(id);
        model.addAttribute("user", user);
        return "userInfo";
    }

    @RequestMapping("/deleteUser")
    public String deleteUser(Long id) {
    
    
        userService.delete(id);
        return "redirect:/getAllUser";
    }
}

dao

@Repository
public class UserDaoImpl implements UserDao {
    
    

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void addUser(User user) {
    
    
        String sql = "insert into user (name, age, sex) values (?, ?, ?)";
        jdbcTemplate.update(sql, user.getUserName(), user.getUserAge(), user.getUserSex());
    }

    @Override
    public User getUser(Long id) {
    
    
        String sql = "select * from user where id = ?";
        User user = new User();
        Object[] arr = new Object[]{
    
    id};
        jdbcTemplate.query(sql, arr, new RowCallbackHandler() {
    
    
            @Override
            public void processRow(ResultSet resultSet) throws SQLException {
    
    
                user.setId(resultSet.getLong("id"));
                user.setUserName(resultSet.getString("name"));
                user.setUserAge(resultSet.getInt("age"));
                user.setUserSex(resultSet.getString("sex"));
            }
        });
        return user;
    }

    @Override
    public List<User> queryAll() {
    
    
        String sql = "select * from user";
        return jdbcTemplate.query(sql, new RowMapper<User>() {
    
    
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
    
    
                User user = new User();
                user.setId(resultSet.getLong("id"));
                user.setUserName(resultSet.getString("name"));
                user.setUserAge(resultSet.getInt("age"));
                user.setUserSex(resultSet.getString("sex"));
                return user;
            }
        });
    }

    @Override
    public void update(User user) {
    
    
        String sql = "update user set name=?, age=?, sex=? where id=?";
        jdbcTemplate.update(sql, user.getUserName(), user.getUserAge(), user.getUserSex(), user.getId());
    }

    @Override
    public void delete(Long id) {
    
    
        String sql = "delete from user where id = ?";
        jdbcTemplate.update(sql, id);
    }
}

【2】整合mybatis

(1)依赖配置
<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.3</version>
		</dependency>
(2)配置数据源
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=UTC&useSSL=false
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
(3)配置maven的generator插件

A、添加generator插件坐标

<plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.38</version>
                    </dependency>
                </dependencies>

                <!-- mybatis用于生成代码的配置文件 -->
                <configuration>
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

B、添加generator配置文件

在resources路径下添加generatorConfig.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>
    <context id="default" targetRuntime="MyBatis3">
        <!-- optional,旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!--是否去除自动生成 的注释-->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--jdbc的数据库连接 -->
        <jdbcConnection
                driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/test?seUnicode=true; characterEncoding=UTF-8;serverTimezone=UTC;useSSL=false"
                userId="root"
                password="root">
        </jdbcConnection>
        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在该项目下所在的路径
        -->
        <javaModelGenerator targetPackage="com.handersome.springbootmybatis.entity" targetProject="./src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加 构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
        <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
                type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
        -->
        <!-- targetPackage:mapper接口dao生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.handersome.springbootmybatis.dao" targetProject="./src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <table tableName="user" domainObjectName="UserDto" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
            <columnOverride column="id" jdbcType="bigint"/>
            <columnOverride column="name" jdbcType="VARCHAR"/>
            <columnOverride column="age" jdbcType="int"/>
            <columnOverride column="sex" jdbcType="int"/>
        </table>
    </context>
</generatorConfiguration>

C、添加generator配置文件的dtd配置

http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd

报错

修改方法

在这里插入图片描述

D、运行generator插件生成代码

在这里插入图片描述

执行成功后会在指定的目录下自动生成dto和mapper和dao文件

在这里插入图片描述

(4)mybats映射文件扫描配置

A、pom文件的build节点中指定resources扫描的路径和文件

可以不配,但是如果配错误了,可能导致模板扫描不到

<resources>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.yml</include>
					<include>**/*.xml</include>
					<include>**/*.properties</include>
				</includes>
			</resource>
		</resources>

B、mybatis配置

方式1:生成的mapper文件放在了resource下面可以通过在application配置文件中指定

mybatis:
  ## 指定扫描的配置文件的路径
  mapper-locations: classpath:/mappers/*.xml
  ## 定义包别名,可以使在mapper.xml中使用dto时不引入包名
  type-aliases-package: com.handersome.springbootmybatis.entity

方式2:如果生成的mapper文件放在了src/main/java下面,那么需要加载启动类上添加@MapperScan注解并将mapper所在的包引进来

C、增删改查

controller类

@Controller
public class UserController {
    
    

    @Autowired
    private UserDtoMapper userDtoMapper;

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

    @RequestMapping("/addUser")
    @ResponseBody
    public String addUser(UserDto userDto) {
    
    
        try {
    
    
            userDtoMapper.insert(userDto);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

    @RequestMapping("/updateUser")
    @ResponseBody
    public String updateUser(UserDto userDto) {
    
    
        try {
    
    
            userDtoMapper.updateByPrimaryKey(userDto);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return "error";
        }
        return "ok";
    }

    @RequestMapping("/getAllUser")
    public String getAllUser(Model model) {
    
    
        List<UserDto> userList = userDtoMapper.selectAll();
        model.addAttribute("userList", userList);
        return "userList";
    }

    @RequestMapping("/userInfo")
    public String userInfo(Model model, Long id) {
    
    
        UserDto user = userDtoMapper.selectByPrimaryKey(id);
        model.addAttribute("user", user);
        return "userInfo";
    }

    @RequestMapping("/deleteUser")
    public String deleteUser(Long id) {
    
    
        userDtoMapper.deleteByPrimaryKey(id);
        return "redirect:/getAllUser";
    }
}

dao

generator自动生成的,但是没有添加@Mapper注解,要手动加上

@Mapper
public interface UserDtoMapper {
    
    
    int deleteByPrimaryKey(Long id);

    int insert(UserDto record);

    int insertSelective(UserDto record);

    UserDto selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(UserDto record);

    int updateByPrimaryKey(UserDto record);

    List<UserDto> selectAll();
}

五、spring boot异常处理

【1】自定义错误页面

​ springboot默认的异常处理机制已经提供了一套现有的异常处理策略,一旦程序中出现异常spring boot会想/error的URL发送请求,在spring boot中提供了一个名为BasicErrorController来处理/error请求,然后跳转到默认的异常显示页面来显示异常信息。

​ 如果需要所有的异常全部跳转到自定义的错误页面,需要向src/main/resources/templates目录下创建error.html页面。

【2】通过@ExceptionHandler注解处理异常

在showError1中抛出的异常会在errorTest中处理

@Controller
public class ErrorController {
    
    

    @RequestMapping("error1")
    @ResponseBody
    public String showError1() {
    
    
        Integer a = null;
        a.toString();
        return "ok";
    }

    @ExceptionHandler(value = {
    
    java.lang.NullPointerException.class})
    public String errorTest(Exception e, Model model) {
    
    
        model.addAttribute("err", e.toString());
        System.out.println("fffff" + e.toString());
        return "error1";
    }
}

【3】通过@ControllerAdvice和@ExceptionHandler处理

通过这种方式可以通用的处理所有的异常返回

创建全局异常处理类

@ControllerAdvice
public class GlobalException {
    
    

    @ExceptionHandler(value = {
    
    java.lang.NullPointerException.class})
    public String nullPointExceptionHandler(Exception e, Model model) {
    
    
        model.addAttribute("err", e.toString());
        System.out.println("GlobalException----" + e.toString());
        return "error1";
    }

    @ExceptionHandler(value = {
    
    java.lang.NumberFormatException.class})
    public String numberExceptionHandler(Exception e, Model model) {
    
    
        model.addAttribute("err", "数值错误" + e.toString());
        System.out.println("GlobalException----" + e.toString());
        return "error1";
    }
}

【4】通过SimpleMapiingExceptionResolver对象处理异常

@Configuration
public class GlobalException1 {
    
    

    @Bean
    public SimpleMappingExceptionResolver getBean() {
    
    
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        System.out.println("GlobalException1");
        properties.put("java.lang.NullPointerException", "error1");
        properties.put("java.lang.NumberFormatException", "error1");
        resolver.setExceptionAttribute("err");
        resolver.setExceptionMappings(properties);
        return resolver;
    }
}

【5】通过实现HandlerExceptionResolver处理

@Configuration
public class GlobalException2 implements HandlerExceptionResolver {
    
    

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
    
    
        ModelAndView mav = new ModelAndView();
        if (e instanceof NullPointerException) {
    
    
            mav.setViewName("error1");
        }

        if (e instanceof NumberFormatException) {
    
    
            mav.setViewName("error1");
        }
        System.out.println("GlobalException2");
        mav.addObject("err", e.toString());
        return mav;
    }
}

六、spring boot整合单元测试

注意Junit3,4,5有差异;springboot2.x使用Junit5作为单元测试依赖

1、引入依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<!--org.junit.vintage 支持Junit3和4-->
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

2、单元测试类

@SpringBootTest
class UserControllerTest {
    
    

    @Autowired
    private UserController userController;

    @Test
    void userAdd() {
    
    
        UserDto user = new UserDto();
        userController.addUser(user);
    }

}

七、其他

【1】服务端数据校验

spring boot中使用了Hibernate-validator校验框架对实体对象做数据校验

略过

【2】页面跳转参数异常

在跳转页面方法中注入一个对象,要求参数对象的变量名必须是对象类型名称首字母小写格式

@Controller
public class PageController {

    @RequestMapping("/{page}")
    public String page(UserDto userDto, @PathVariable String page) {
        return page;
    }
}

spring mvc会将对象放入到model中短笛,key 的名称会使用该对象的类名的驼峰命名规则作为key

可用通过@ModelAttribute注解修改key的名称

@Controller
public class PageController {
    
    

    @RequestMapping("/{page}")
    public String page(@ModelAttribute("suibian") UserDto userDto, @PathVariable String page) {
    
    
        return page;
    }
}

然后页面中就能够用${suibian.name}来获取对象属性

【3】spring boot热部署

通过devTools工具实现热部署,即改了代码后不需要手动重启,会自动重新编译加载

1、引入pom依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>

2、配置idea

settings–>compiler—>勾选build project automatically

在这里插入图片描述

3、设置 idea registry

通过ctrl + shift + alt + / 打开registry窗口;勾选compiler.automake.allow.when.app.running

在这里插入图片描述

【4】spring boot度量指标和健康检查

spring boot 采用actuator依赖进行监控与检查,acturator支持客户端暴露一些健康数据的端点供访问

(1)、server端构建

1、依赖

<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-server</artifactId>
			<version>2.2.3</version>
		</dependency>

2、修改启动类配置添加@EnableAdminServer注解

@SpringBootApplication
@EnableAdminServer
public class SpringbootActuratorServerApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(SpringbootActuratorServerApplication.class, args);
	}

}

3、通过 http://localhost:8080/applications 访问

在这里插入图片描述

4、注意事项

admin的版本号和spring的版本号有很强的绑定关系,2.1.x版本的admin不支持2.2.x版本的springboot

(2)、client端构建

1、依赖

<!--用于暴露端点-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

		<!--图形化数据客户端-->
		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-client</artifactId>
			<version>2.2.3</version>
		</dependency>

2、监控指标url介绍

端点 描述 HTTP方法
autoconfig 显示自动配置的信息 GET
beans 显示应用程序上下文所有的Spring Bean GET
configprops 显示所有@ConfigurationProperties的配置属性列表 GET
dump 显示线程活动快照 GET
env 显示应用的环境变量 GET
health 显示应用程序的监控指标,这些值由HealthIndicator的实现类提供 GET
info 显示应用的信息,可使用info.*属性自定义info端点公开的数据 GET
mappings 显示所有的URL路径 GET
metrics 显示应用的度量标准信息 GET
shutdown 关闭应用,默认不启用,通过设置endpoints.shutdown.enabled=true启用 GET
trace 显示跟踪信息,默认最近100个请求 GET

3、修改配置文件application.yml

management:
  endpoints:
    web:
      base-path: /actuator #配置访问端点的根路径
      exposure:
        exclude: beans,info #不暴露的访问端点

【5】日志管理

​ spring boot默认使用logback组件作为日志管理。logback是由log4j创始人设计的一个开源日志组件,在springboot中不需要添加外的logback的依赖,因为在spring-boot-starter或者spring-boot-starter-web中已经包含了logback的依赖。

​ logback读取配置文件的步骤

(1)如果在classpath下查找logback-test.xml如果不存在查找logback.xml

(2)如果两个文件都不存在,logback用BasicConfiguration自动对自己进行最小化配置,这样既实现了上面我们不需要添加任何配置就可以输出到控制台日志信息。

(3)logback配置文件

【6】多环境配置

语法结构:application-{profile}.properties/yml; profile代表某个配置环境的表示

例如

application-dev.properties

application-sit.properties

application-prd.properties

window环境下的启动方式

java -jar xxx.jar --spring.profiles.active=dev

linux 下的启动方式

安装上传文件的下载工具

yum install lrzsz -y

上传命令:rz

下载命令:sz 下载文件名

通过脚本的方式来启动,在后台运形

猜你喜欢

转载自blog.csdn.net/khuangliang/article/details/107398433