首页
在线工具
搜索
1
Kuboard与KubeSphere的区别:Kubernetes管理平台对比
2
ShardingSphere使用中的重点问题剖析
3
Flowable工作流引擎源码深度解析
4
用AI生成的原型设计稿效果还可以
5
如何将Virtualbox和VMware虚拟机相互转换
杂谈与随笔
工具与效率
源码阅读
技术管理
运维
数据库
前端开发
后端开发
Search
标签搜索
Angular
Docker
Phabricator
SpringBoot
Java
Chrome
SpringSecurity
SpringCloud
DDD
Git
Mac
K8S
Kubernetes
ESLint
SSH
高并发
Eclipse
Javascript
Vim
Centos
Jonathan
累计撰写
86
篇文章
累计收到
0
条评论
首页
栏目
杂谈与随笔
工具与效率
源码阅读
技术管理
运维
数据库
前端开发
后端开发
页面
搜索到
4
篇与
的结果
2025-02-16
记录下从SpringBoot2.7升级到SpringBoot3.2.4问题处理
Dataroom从SpringBoot2.7升级到SpringBoot3.2.4 为了使用让DataRoom引入MCP,整合Spring AI体系,升级SrpingBoot 升级到Jakarta EE Java EE 已更改为 Jakarta EE,Spring Boot 3.x 的所有依赖项 API 也从 Java EE 升级为 Jakarta EE。 简单来说,您需要将所有 javax 的 imports 都替换为 jakarta。具体如下: javax.persistence.* -> jakarta.persistence.* javax.validation.* -> jakarta.validation.* javax.servlet.* -> jakarta.servlet.* javax.annotation.* -> jakarta.annotation.* javax.transaction.* -> jakarta.transaction.* 换mybatis依赖 Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 所以升级 Mybatis-Plus 版本为 3.5.5 版本即可,需要注意下 Maven 的坐标标识 是mybatis-plus-spring-boot3-starter,这点和SpringBoot 2 的依赖坐标mybatis-plus-boot-starter有所区别 第一步:注释spring-boot-starter <!-- <dependency>--> <!-- <groupId>com.baomidou</groupId>--> <!-- <artifactId>mybatis-plus-boot-starter</artifactId>--> <!-- <version>${mybatis.plus.version}</version>--> <!-- </dependency>--> 第二步:引入新的依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId> <version>3.5.5</version> </dependency> 第三步 <dependencyManagement> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency> </dependencies> </dependencyManagement> 动态数据源修改 第一步注释如下代码 <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.5.0</version> </dependency> 第二步:引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <version>4.2.0</version> </dependency>
2025年02月16日
2017-05-09
SpringBoot Validator入门
大纲 入门例子 国际化 在代码中添加错误信息 入门例子 Validator 主要是校验用户提交的数据的合理性的,比如是否为空了,密码长度是否大于 6 位,是否是纯数字的,等等。那么在 spring boot 怎么使用这么强大的校验框架呢。 在这里我们主要是使用注解进行学习。我们先说说我们的需求: 我们有一个 demo.html,在页面上有两个元素 姓名输入框,密码输入框,提交按钮。 提交到后台之后,使用 Validator 进行校验,然后如果存在错误,转发到 demo.html。 我们先编写一个实体类接收用户的输入,以及使用 Validator 注解校验: package com.kfit.demo; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotEmpty; public class Demo { private long id; @NotEmpty(message="姓名不能为空") private String name; @NotEmpty(message="密码不能为空") @Length(min=6,message="密码长度不能小于6位") private String password; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "Demo [id=" + id + ", name=" + name + ", password=" + password + "]"; } } 这个实体类在属性上加入了注解 @NotEmpty,@Length,那么常用的注解有: 约束注解名称 约束注解说明 @null 验证对象是否为空 @notnull 验证对象是否为非空 @asserttrue 验证 boolean 对象是否为 true @assertfalse 验证 boolean 对象是否为 false @min 验证 number 和 string 对象是否大等于指定的值 @max 验证 number 和 string 对象是否小等于指定的值 @decimalmin 验证 number 和 string 对象是否大等于指定的值,小数存在精度 @decimalmax 验证 number 和 string 对象是否小等于指定的值,小数存在精度 @size 验证对象(array,collection,map,string)长度是否在给定的范围之内 @digits 验证 number 和 string 的构成是否合法 @past 验证 date 和 calendar 对象是否在当前时间之前 @future 验证 date 和 calendar 对象是否在当前时间之后 @pattern 验证 string 对象是否符合正则表达式的规则 @Email 验证邮箱 实际例子: @size (min=3, max=20, message="用户名长度只能在3-20之间") @size (min=6, max=20, message="密码长度只能在6-20之间") @pattern (regexp="[a-za-z0-9._%+-]+@[a-za-z0-9.-]+\\.[a-za-z]{2,4}", message="邮件格式错误") @Length(min = 5, max = 20, message = "用户名长度必须位于5到20之间") @Email(message = "比如输入正确的邮箱") @NotNull(message = "用户名称不能为空") @Max(value = 100, message = "年龄不能大于100岁") @Min(value= 18 ,message= "必须年满18岁!" ) @AssertTrue(message = "bln4 must is true") @AssertFalse(message = "blnf must is falase") @DecimalMax(value="100",message="decim最大值是100") @DecimalMin(value="100",message="decim最小值是100") @NotNull(message = "身份证不能为空") @Pattern(regexp="^(\\d{18,18}|\\d{15,15}|(\\d{17,17}[x|X]))$", message="身份证格式错误") 好了,这个不是我们这节的重点,这里简单说一下而已,那么之后我们应该怎么做呢?我们需要编写一个 Controller 进行访问的时候,能访问到 demo.html 以及点击提交按钮的处理方法,具体看如下代码: @RequestMapping("/demo") public String demo(Model model){ model.addAttribute("demo",new Demo()); return "/demo"; } @RequestMapping("/demoAdd") public String demoAdd(@Valid Demo demo,BindingResult result,Model model){ //有错误信息. model.addAttribute("demo",demo); if(result.hasErrors()){ List<ObjectError> list = result.getAllErrors(); for(ObjectError error:list){ System.out.println(error.getCode()+"---"+error.getArguments()+"---"+error.getDefaultMessage()); } return "demo"; } return "/demo"; } 这里的代码还是需要简单说明下,我们使用 @Valid 指定要校验的实体类。 BindingResult 所有的错误信息都会保存在这个类中,我们可以使用 result.hasErrors() 判断是否有错误信息,有的话,我们转发到我们原先访问的 hello.html,如果没有的话,我们正常应该是跳转到 list.html 之类的,这里只是为了方便测试跳回了 demo.html,但是如果没有任何错误信息的话,那么在页面上是不会显示错误信息的。 好了,接下来我们看看 demo.html 是怎么编写的吧? <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>hello spring boot</title> </head> <body> <form action="/demoAdd" method="post" th:object="${demo}"> <p>姓名:<input type="text" name="name" th:value="*{name}" /> </p> <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p> <p>密码:<input type="text" name="password" th:value="*{password}" /> </p> <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}">password Error</p> <p><button>提交</button></p> </form> </body> </html> 这里我们使用的 thymeleaf 进行展示数据的,使用 jsp 的代码需要用到 tag 标签,也能实现相同的效果,自行百度学习。这里核心代码就是: <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p> 这句代码一旦后台有返回异常信息的话,就会显示 name 对应的 message,如果满足了两个条件的话,是会返回两个的,之间是用 <br/> 进行处理的,就如我们的 password 什么都不填写的情况下是会显示如下信息的: 密码: 密码不能为空 密码长度不能小于6位 国际化 在上一节我们就讲过国际化了,那么如何在 Validator 加入国际化呢,很简单的,只需要在国际化配置文件加入相应的配置如: demo.name = `name` is not empty. 这里需要注意的地方是: 必须放在 classes 目录下,而且必须用 ValidationMessages 这个名字 也就是文件名称需要命名为: ValidationMessages.properties ValidationMessages_en.properties 那么修改 Demo.java 文件: @NotEmpty(message="{demo.name}") 在代码中添加错误信息 有些代码是很难使用 Validator 的注解来实现的,那么我们怎么在返回的信息添加我们自己的判断呢,比如我们现在要求用户输入的 name 不能重复,那么势必我们会有这么一段代码: 如果存在 name,那么返回“该 name 已经存在了”。其实这个也是很简单,只需要一句话代码就可以添加自定义错误字段的信息了: result.rejectValue("name", "misFormat", "这个name已经注册过了!"); 当然在添加的时候,外层应该有一个 if(isExist(“name”)) 这样的代码,这里没有进行编写,就直接添加了,实际开发请自行从数据库获取,然后进行判断。
2017年05月09日
2017-04-26
如何用 Docker 构建、运行、发布来一个 spring Boot 应用
如何用 Docker 构建、运行、发布来一个 spring Boot 应用。 Docker 简介 Docker 是一个 Linux 容器管理工具包,具备“社交”方面,允许用户发布容器的 image (镜像),并使用别人发布的 image。Docker image 是用于运行容器化进程的方案,在本文中,我们将构建一个简单的 Spring Boot 应用程序。 有关 Docker 的详细介绍,可以移步至 《简述 Docker》 前置条件 JDK 1.8+ Maven 3.0+ Docker 最新版。有关 Docker 在的安装,可以参阅 《Docker 在 CentOS 下的安装、使用》。 如果你的电脑不是 Linux 系统,最好装个虚拟机,在虚拟机里面装个 Linux ,因为 Docker 的依赖 Linux。 用 Maven 构建项目 创建目录结构 项目的目录结构因符合 Maven 的约定。 在 *nix 系统下执行 mkdir -p src/main/Java/docker_spring_boot ,生产如下结构 : └── src └── main └── java └── com └── lzh └── docker_spring_boot 创建 pom.xml 文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.lzh</groupId> <artifactId>docker-spring-boot</artifactId> <packaging>jar</packaging> <version>1.0.0</version> <name>docker-spring-boot</name> <description>Getting started with Spring Boot and Docker</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> <relativePath/> </parent> <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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- tag::plugin[] --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.3</version> <configuration> <imageName>${docker.image.prefix}/${project.artifactId}</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> <!-- end::plugin[] --> </plugins> </build> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <docker.image.prefix>lzh</docker.image.prefix> <spring.boot.version>1.3.3.RELEASE</spring.boot.version> </properties> </project> Spring Boot Maven plugin 提供了很多方便的功能: 它收集的类路径上所有 jar 文件,并构建成一个单一的、可运行的“über-jar”,这使得它更方便地执行和传输服务。 它搜索的 public static void main() 方法来标记为可运行的类。 它提供了一个内置的依赖解析器,用于设置版本号以匹配 Spring Boot 的依赖。您可以覆盖任何你想要的版本,但它会默认选择的 Boot 的版本集。 Spotify 的 docker-maven-plugin 插件是用于构建 Maven 的 Docker Image imageName指定了镜像的名字,本例为 lzh/docker-spring-boot dockerDirectory指定 Dockerfile 的位置 resources是指那些需要和 Dockerfile 放在一起,在构建镜像时使用的文件,一般应用 jar 包需要纳入。本例,只需一个 jar 文件。 编写 Spring Boot 应用 编写一个简单的 Spring Boot 应用 : src/main/java/com/lzh/docker_spring_boot/Application.java: package com.lzh.docker_spring_boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 主应用入口 * @author lzh * @date 2017年3月19日 */ @SpringBootApplication @RestController public class Application { @RequestMapping("/") public String home() { return "Hello Docker World." + "<br />Welcome to SpringBoot</li>"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 解释下上面的代码: 类用 @SpringBootApplication @RestController 标识,可用 Spring MVC 来处理 Web 请求。 @RequestMapping 将 / 映射到 home() ,并将”Hello Docker World” 文本作为响应。 main() 方法使用 Spring Boot 的 SpringApplication.run() 方法来启动应用。 运行程序 使用 Maven 编译: mvn package 运行: java -jar target/docker-spring-boot-1.0.0.jar 访问项目 如果程序正确运行,浏览器访问 http://localhost:8080/,可以看到页面 “Hello Docker World.” 字样。 将项目容器化 Docker 使用 Dockerfile 文件格式来指定 image 层, 创建文件 src/main/docker/Dockerfile: FROM frolvlad/alpine-oraclejdk8:slim VOLUME /tmp ADD docker-spring-boot-1.0.0.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 解释下这个配置文件: VOLUME 指定了临时文件目录为/tmp。其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp。改步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到 Docker 数据文件夹,因为 Spring Boot 使用的内嵌 Tomcat 容器默认使用/tmp作为工作目录 项目的 jar 文件作为 “app.jar” 添加到容器的 ENTRYPOINT 执行项目 app.jar。为了缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/urandom” 作为 Entropy Source 构建 Docker Image 执行构建成为 docker image: mvn package docker:build 运行 运行 Docker Image docker run -p 8080:8080 -t lzh/docker-spring-boot [root@lzh spring-boot]# docker run -p 8080:8080 -t lzh/docker-spring-boot . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.3.3.RELEASE) 2016-03-20 08:45:51.276 INFO 1 --- [ main] c.lzh.docker_spring_boot.Application : Starting Application v1.0.0 on 048fb623038f with PID 1 (/app.jar started by root in /) 2016-03-20 08:45:51.289 INFO 1 --- [ main] c.lzh.docker_spring_boot.Application : No active profile set, falling back to default profiles: default 2016-03-20 08:45:51.722 INFO 1 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc: startup date [Sun Mar 20 08:45:51 GMT 2016]; root of context hierarchy 2016-03-20 08:45:54.874 INFO 1 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]] 2016-03-20 08:45:57.893 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2016-03-20 08:45:57.982 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat 2016-03-20 08:45:57.984 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.32 2016-03-20 08:45:58.473 INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2016-03-20 08:45:58.473 INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 6877 ms 2016-03-20 08:45:59.672 INFO 1 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2016-03-20 08:45:59.695 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2016-03-20 08:45:59.701 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2016-03-20 08:45:59.703 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2016-03-20 08:45:59.703 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter:'requestContextFilter' to: [/*] 2016-03-20 08:46:00.862 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc: startup date [Sun Mar 20 08:45:51 GMT 2016]; root of context hierarchy 2016-03-20 08:46:01.166 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.lzh.docker_spring_boot.Application.home() 2016-03-20 08:46:01.189 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2016-03-20 08:46:01.190 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2016-03-20 08:46:01.302 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-20 08:46:01.302 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-20 08:46:01.438 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-20 08:46:01.833 INFO 1 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2016-03-20 08:46:02.332 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2016-03-20 08:46:02.343 INFO 1 --- [ main] c.lzh.docker_spring_boot.Application : Started Application in 13.194 seconds (JVM running for 15.828) 推送 image 到 Docker Hub 首先,你在 Docker Hub 要有注册账号,且创建了相应的库; 其次,docker 推送前,先要登录,否则报unauthorized: access to the requested resource is not authorized的错误 执行: docker login [root@lzhspring-boot]# docker login Username: root Password: Email: idinu@gmail.com WARNING: login credentials saved in /root/.docker/config.json Login Succeeded - 执行推送 docker push lzh/docker-spring-boot [root@lzhspring-boot]# docker push lzh/docker-spring-boot The push refers to a repository [docker.io/lzh/docker-spring-boot] 751d29eef02e: Layer already exists 4da3741f39c7: Pushed 5f70bf18a086: Layer already exists 7e4d0cb13643: Layer already exists 8f045733649f: Layer already exists latest: digest: sha256:eb4d5308ba1bb27489d808279e74784bda6761b3
2017年04月26日
2016-08-18
Spring-boot-configuration-processor 作用
在application.properties文件中添加自定义属性 (1)在application.properties文件中添加自定义属性(单个属性使用) 在这里我们新建一个maven java project进行测试,取名为:spring-boot-hello4。 对pom.xml基本的spring boot 配置,主要用到的一个核心依赖是: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> 官方中对于spring-boot-configuration-processor是这么说明的: 通过使用spring-boot-configuration-processor jar, 你可以从被@ConfigurationProperties注解的节点轻松的产生自己的配置元数据文件。该jar包含一个在你的项目编译时会被调用的Java注解处理器。想要使用该处理器,你只需简单添加spring-boot-configuration-processor依赖。 好了,官方已经说得很清楚了,这个依赖主要可以在代码中轻松的使用@ConfigurationProperties注解注入属性文件配置的属性值。 单属性注入的比较简单,只需要在application.properties加入配置,如下: #key = value的形式; filePathLocation = d:/data/files 那么在对应需要使用的类中使用如下代码进行引入: @Value("${filePathLocation}") private String filePathLocation; 这里使用@Value注解就可以为我们的变量filePathLocation设置上我们在application.properties文件中设置的key值了。 在实际开发中可能我们期望的是,如果没有设置key的话,设置一个默认值,使用如下代码即可实现(以上@Value的使用方式如果在没有设置key的话是会抛出异常的): @Value("${filePathLocation1:d:/data/myfiles}") private String filePathLocation1; 这里的filePathLocation1我们并没有在application.properties文件中进行指定,但是查看打印信息是可以看到我们设置的默认值的,所以设置默认值的方式就是: @Value(“${key:defaultVlaue}”) 的形式进行设置。 (2)在application.properties文件中添加自定义属性(多个属性使用) 多属性的设置也可以属性单属性的注入方式,但是这种方式不好,那么怎么比较优雅的注入多个属性值进行使用了。假设我们在application.properties定义了如下的属性: #公司简称; com.kfit.company.name =知远信科 #公司位置; com.kfit.company.location =北京海淀区 #公司联系方式; com.kfit.company.mobile = 110****1195 #公司员工人数; com.kfit.company.employCount = 100 接下来我们定义一个ComapnyProperties类进行设置这些参数。 package com.kfit.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; //prefix设置key的前缀; @ConfigurationProperties(prefix = "com.kfit.company") @Component public class CompanyProperties { private String name; private String location; private String mobile; private int employCount; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public int getEmployCount() { return employCount; } public void setEmployCount(int employCount) { this.employCount = employCount; } @Override public String toString() { return "CompanyProperties [name=" + name + ", location=" + location + ", mobile=" +mobile + ", employCount=" + employCount + "]"; } } 那么之后我们就可以使用如下代码注入到要使用的这些属性的类进行使用了: @Autowired private CompanyProperties companyProperties; 这里需要注意下: 第一:我们使用了@ConfigurationProperties(prefix = "com.kfit.company") 快速注入我们的属性,这里prefix是key的公共部分。 第二:这里我们使用@Component 注解为spring 管理的类,那么在别的类才可以进行注入使用。 第三:在之前的文章中我们并没有使用@Component进行注册为spring 容器中,而是使用了@EnableConfigurationProperties({WiselySettings.class}) 这样的方式进行注入的。这两种方式都可以。 (3)配置数组注入 我们在application.properties定义数组: # 员工列表 com.kfit.company.employs[0]=张三 com.kfit.company.employs[1]=李四 com.kfit.company.employs[2]=王五 类似这样的定义那么在对应的CompanyProperties文件中怎么接收呢?很简单,定义List<String>接收就可以了,代码如下: private List<String> employs = new ArrayList<String>(); 这里的属性名称employs需要和application.properties文件的key是对应的。 这样employs注入了配置中的数据,打印为如下: [张三, 李四, 王五] (4)松散的绑定 Spring Boot使用宽松的规则用于绑定属性到@ConfigurationProperties beans,所以Environment属性名和bean属性名不需要精确匹配。常见的示例中有虚线分隔的(比如,context-path绑定到contextPath),环境属性大写转为小写字母(比如:PORT绑定port)。 示例: 在application.properties文件中的配置: com.kfit.company.firstName = lin com.kfit.company.logo-path = d:/data/files/logo.png com.kfit.company.COMPANY_FULLNAME =北京知远科技公司 对应的CompanyProperties类中的对应定义: //对应:com.kfit.company.firstName = lin private String firstName; //对应:com.kfit.company.logo-path = d:/data/files/logo.png private String logoPath; //对应:com.kfit.company.COMPANY_FULLNAME = 北京知远科技公司 private String companyFullname; private List<String> employs = new ArrayList<String>(); 看到这里,你是否终于知道为什么context-path,spring.jpa.show-sql 其实是被解释为contextPath和showSql了,不然要是指定定义一个show-sql变量是无法编译通过的,oh,原来是这么回事呢,这真是太神奇了,就是因为编程无奇不有,所以才有那么多人爱编程。 (5)参数的引用 在application.properties中的各个参数之间也可以直接引用来使用,就像下面的设置: com.kfit.blog.desc=${com.kfit.blog.name}正在写《${com.kfit.blog.title}》 这个就很好理解了,使用${key} 的方式进行引用。 (6)随机数 在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。 # 随机字符串 com.kfit.blog.value=${random.value} # 随机int com.kfit.blog.number=${random.int} # 随机long com.kfit.blog.bignumber=${random.long} # 10以内的随机数 com.kfit.blog.test1=${random.int(10)} # 10-20的随机数 com.kfit.blog.test2=${random.int[10,20]} 好了,这些在之前的文章都有介绍过了,就不多说了。 (7)使用自定义的配置文件company.properties怎么操作 如果我们自己定义一个company.properties文件, #key = value的形式; filePathLocation = d:/data/files #公司简称; com.kfit.company.name =知远信科-custom #公司位置; com.kfit.company.location =北京海淀区-custom #公司联系方式; com.kfit.company.mobile = 110****1195-custom #公司员工人数; com.kfit.company.employCount = 100 # 员工列表 com.kfit.company.employs[0]=张三-custom com.kfit.company.employs[1]=李四-custom com.kfit.company.employs[2]=王五-custom com.kfit.company.firstName = lin-custom com.kfit.company.logo-path = d:/data/files/logo.png-custom com.kfit.company.COMPANY_FULLNAME =北京知远科技公司-custom 这个定义就是我们刚刚提到的一些配置,那么怎么引入了,如果使用上面的CompanyProperties的方式肯定是不行了,那么怎么呢?其实很简单,只需要在CompanyProperties稍微修改下即可,修改的地方如下: @ConfigurationProperties( prefix = "com.kfit.company", locations="classpath:company.properties") 大家注意,这里唯一不一样的地方是加入了一个属性locations指定了我们要使用的配置文件路径和名称,如果我们的配置文件不在application.properties下,可以这么定义: classpath:config/company.properties。 好了这一个知识点就这么简单,只要掌握要点,一句代码就可以搞定。 (8)在方法上使用@Bean的时候如何进行注入 这个需求点是怎么产生的呢?我们经常会配置多个数据源,那么我们有些配置还是希望从application.properties文件中进行读取,那么自然而然的在我们定义的@bean中就需要能够读取配置文件的属性。这里我们简单做个试验,我们定义CompanyProperties3,具体代码如下: package com.kfit.properties; import java.util.ArrayList; import java.util.List; public class CompanyProperties3 { private String name; private String location; private String mobile; private int employCount; //对应:com.kfit.company.firstName = lin private String firstName; //对应:com.kfit.company.logo-path = d:/data/files/logo.png private String logoPath; //对应:com.kfit.company.COMPANY_FULLNAME = 北京知远科技公司 private String companyFullname; private List<String> employs = new ArrayList<String>(); public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLogoPath() { return logoPath; } public void setLogoPath(String logoPath) { this.logoPath = logoPath; } public String getCompanyFullname() { return companyFullname; } public void setCompanyFullname(String companyFullname) { this.companyFullname = companyFullname; } public List<String> getEmploys() { return employs; } public void setEmploys(List<String> employs) { this.employs = employs; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public int getEmployCount() { return employCount; } public void setEmployCount(int employCount) { this.employCount = employCount; } @Override public String toString() { return "CompanyProperties [name=" + name + ", location=" + location + ", mobile=" + mobile + ", employCount=" + employCount + ", firstName=" + firstName + ", logoPath=" + logoPath + ", companyFullname=" + companyFullname + ", employs=" + employs + "]"; } } 注意这里的代码和以上不一样的是类上的注解全没有了,之后我们在App.java启动类中或者其它的类也是可以的,使用@Bean的方式进行注入。 @Bean @ConfigurationProperties(prefix = "com.kfit.company") public CompanyProperties3 companyProperties3(){ return new CompanyProperties3(); } 那么在其它的类中我们就使用@Autowired进行注入使用了,如下: @Autowired private CompanyProperties3 companyProperties3; 是不是很好玩呢。 (9)自定义结构 对于复杂的配置或嵌套的kv,我们可以编写自定义结构属性以更好的方式进行管理。 比如我们在application.properties文件中有如下信息: com.kfit.employForzs.name =张三 com.kfit.employForzs.age = 20 com.kfit.employForzs.gender =男 com.kfit.employForls.name =李四 com.kfit.employForls.age = 25 com.kfit.employForzs.gender =女 com.kfit.properties.CompanyEmployee的代码如下: package com.kfit.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; //prefix设置key的前缀; @ConfigurationProperties(prefix = "com.kfit") @Component public class CompanyEmployee { private CompanyEmployeeInfo employForzs; private CompanyEmployeeInfo employForls; public CompanyEmployeeInfo getEmployForzs() { return employForzs; } public void setEmployForzs(CompanyEmployeeInfo employForzs) { this.employForzs = employForzs; } public CompanyEmployeeInfo getEmployForls() { return employForls; } public void setEmployForls(CompanyEmployeeInfo employForls) { this.employForls = employForls; } public static class CompanyEmployeeInfo { private String name; private int age; private String gender; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "EmployForzs [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } } @Override public String toString() { return "CompanyEmployee [employForzs=" + employForzs + ", employForls=" + employForls + "]"; } } 观察以上的代码我们定义了一个内部静态类进行处理相同的属性,那么在外部类中定义两个变量进行接收application.properties文件中的配置信息。 之后在其它类就可以使用@Autowired进行注入使用了。 (10)校验 当我们使用@ConfigurationProperties的时候,我们希望对一些参数进行校验,比如有些参数为空或者数字超出的限制就抛出异常信息,那么这个怎么操作呢? 在application.properties文件中加入: com.kfit.company.url = http://www.kfit.com 在CompanyProperties类中加入: @URL private String url; 这里使用了@URL对url进行校验,如果是非法的url在启动的时候是会抛出异常信息的。 其中@URL对应的包路径为:org.hibernate.validator.constraints.URL 那么还有其它的什么校验器呢?看下文: @Max(value = 99) private int employCount; 定义最大值只能是99,那么如果运行的话,显然就会报错了,因为之前我们配置的值是100,那么就会看到控制台抛出异常信息: default message [最大不能超过99] 这里只是截取了一小部分异常信息,具体的异常信息是可以参数那个参数的设置有问题的。 既然有最大值就有最小值的配置: @Max(value = 1000) @Min(value = 1) private int employCount; 接着往下看: @NotNull private String name; @NotNull说明name不能为null,如果为null就抛出异常。 接着往下看: @NotEmpty private String location; @NotEmpty不能为空,当没有定义key和key的值为空字符的时候都会抛出异常信息。 在validation-api下包javax.validation.constraints下还有其它的校验器,大家可以根据需要自行学习。当然校验器是可以自定定义的,大家可以自己在扩展下,好了这个章节就介绍到这里了。
2016年08月18日