【Java EE】Spring Boot配置文件

【Java EE】Spring Boot配置文件 文章目录一、为什么需要配置文件二、SpringBoot两种配置文件2.1 文件存放位置与加载规则2.2 application.propertie 键值对格式1. 基础语法2. 读取配置Value3. properties缺点三、application.yml YAML树形配置3.1 语法3.2 yml支持全类型数据配置1. 基础数据类型2. 字符串单双引号特殊规则3. 配置对象4. 配置 List Map3.3 两种读取配置注解对比3.4 yml优缺点四、yml配置 Hutool图形验证码案例4.1 需求说明4.2 引入Hutool验证码依赖4.3 yml配置验证码参数4.4 创建配置映射实体CaptchaProperties4.5 后端Controller 生成校验验证码4.6 前端页面一、为什么需要配置文件开发中如果把端口、数据库账号、第三方密钥直接写死在代码里也就是硬编码会带来极大维护问题环境切换本地/测试/生产需要反复改代码、重新打包敏感信息暴露在源码中存在安全风险统一参数修改需要全局检索代码效率极低。配置文件的作用把可变参数抽离到独立文件程序启动自动读取统一管理所有外部配置。SpringBoot内置两套主流配置文件application.properties、application.yml(yaml)可以维护端口、数据库、日志、自定义业务参数等配置。二、SpringBoot两种配置文件2.1 文件存放位置与加载规则配置文件统一放在src/main/resources目录项目启动自动加载application.propertiesSpringBoot创建项目默认生成键值对格式application.yml/application.yaml新式树形层级格式是开发主流两者同时存在时二者取并集properties优先级更高同名配置会覆盖yml但是项目最好统一只用一种格式避免两套配置造成维护混乱。2.2 application.propertie 键值对格式1. 基础语法keyvalue#单行注释层级通过.分隔。# 修改Tomcat端口 server.port 9090 # MySQL数据库配置 spring.datasource.url jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding utf8useSSLfalse spring.datasource.username root spring.datasource.password root # 自定义业务配置 my.test.keydemo1232. 读取配置Value使用${配置key}读取参数适合零散、独立的配置仅支持单个简单值RestControllerRequestMapping(/prop)publicclassPropController{// 读取properties自定义参数Value(${my.test.key})privateStringtestKey;RequestMapping(/get)publicStringgetConfig(){return读取properties配置testKey;}}3. properties缺点多层级配置存在大量重复前缀spring.datasource.urlxxx spring.datasource.usernameroot spring.datasource.passwordroot每一行都要重复写spring.datasource层级越深冗余越严重三、application.yml YAML树形配置YAML全称Yet Another Markup Language另一种标记语言树形缩进结构可读性更强支持对象、集合、Map等复杂数据。3.1 语法基础格式key: value冒号后必须加英文空格缺少空格直接解析报错层级区分使用缩进2个空格代表父子层级注释#单行注释行内写法大括号{}简化单层对象/Map短横线-代表集合元素。数据库配置# application.ymlspring:datasource:url:jdbc:mysql://127.0.0.1:3306/testdb?characterEncodingutf8useSSLfalseusername:rootpassword:root对比propertiesyml消除重复前缀层级更清晰。3.2 yml支持全类型数据配置1. 基础数据类型# 字符串str:Hello SpringBoot# 布尔值bool:true# 数字num:666floatNum:3.14# null~代表空值empty:~# 空字符串emptyStr:2. 字符串单双引号特殊规则string:str1:Hello \n Boot# 无引号\n 原样输出不换行str2:Hello \n Boot# 单引号转义所有特殊字符\n仅作为文本str3:Hello \n Boot# 双引号保留转义字符\n会自动换行3. 配置对象# 标准缩进写法person:id:1name:daisyage:10# 行内简写,效果完全一致person:{id:1,name:daisy,age:10}注意对象不能用Value读取必须使用ConfigurationProperties批量绑定。ConfigurationProperties(prefixperson)ConfigurationDatapublicclassPerson{privateintid;privateStringname;privateintage;}4. 配置 List MapList集合db-types:name:-mysql-sqlserver-db2List和数组的配置完全相同可以使用List接收也可以使用数组接收Map键值对集合map-demo:map:k1:v1k2:v2# 行内简写map-demo:{map:{k1:v1,k2:v2}}DataComponentConfigurationProperties(prefixdbtypes)publicclassDBTypes{privateListStringname;privateMapString,Stringball;}3.3 两种读取配置注解对比特性ValueConfigurationProperties适用场景单个简单参数、零散配置批量绑定一组配置、对象/List/Map复杂类型不支持对象、集合、Map完美支持嵌套对象、List、Map松散绑定严格匹配key名称支持驼峰、短横线、下划线自动映射不论使用application.properties还是application.yml二者的读取方式都是通过这两个注解来完成因此读取方式基本相同3.4 yml优缺点✅ 优点树形层级清晰消除重复配置可读性极高原生支持对象、数组、Map等复杂数据结构跨语言通用Java、Go、Python、前端均可使用。❌ 缺点 格式要求严苛缩进、空格错误直接启动失败四、yml配置 Hutool图形验证码案例4.1 需求说明访问接口返回图形验证码图片验证码存入Session有效期1分钟前端输入验证码提交后端校验是否匹配、是否过期验证码宽高、Session键名全部抽离到yml配置统一管理。4.2 引入Hutool验证码依赖pom.xmldependencygroupIdcn.hutool/groupIdartifactIdhutool-captcha/artifactIdversion5.8.22/version/dependency4.3 yml配置验证码参数application.ymlcaptcha:width:150height:50session:key:CAPTCHA_SESSION_KEYdate:CAPTCHA_SESSION_DATE4.4 创建配置映射实体CaptchaPropertiesDataConfigurationConfigurationProperties(prefixcaptcha)publicclassCaptchaProperties{privateIntegerwidth;privateIntegerheight;privateSessionsession;DatapublicstaticclassSession{privateStringkey;privateStringdate;}}注意普通的内部类不能交给Spring管理因为要依托外内部类存在改成静态内部类就不再依托外部类可以交给Spring管理4.5 后端Controller 生成校验验证码RestControllerRequestMapping(/captcha)publicclassCaptchaController{AutowiredCaptchaPropertiescaptchaProperties;privatefinalstaticLongVALID_TIME60*1000L;RequestMapping(/getCaptcha)publicvoidgetCaptcha(HttpServletResponseresponse,HttpSessionsession)throwsIOException{response.setContentType(image/jpeg);//理论上由前端处理浏览器缓存问题response.setHeader(Pragma,No-cache);//生成验证码ShearCaptchashearCaptchaCaptchaUtil.createShearCaptcha(captchaProperties.getWidth(),captchaProperties.getHeight());StringcodeshearCaptcha.getCode();session.setAttribute(captchaProperties.getSession().getKey(),code);session.setAttribute(captchaProperties.getSession().getDate(),System.currentTimeMillis());shearCaptcha.write(response.getOutputStream());response.getOutputStream().close();}RequestMapping(/check)publicbooleancheck(Stringcaptcha,HttpSessionsession){//判空if(!StringUtils.hasLength(captcha))returnfalse;//验证ObjectcodeAttrsession.getAttribute(captchaProperties.getSession().getKey());ObjectdateAttrsession.getAttribute(captchaProperties.getSession().getDate());if(codeAttrnull||dateAttrnull)returnfalse;StringcodecodeAttr.toString();longdate(long)dateAttr;booleanisValidSystem.currentTimeMillis()-dateVALID_TIME;returncaptcha.equalsIgnoreCase(code)isValid;}}4.6 前端页面index.html 验证码输入页!DOCTYPEhtmlhtmllangenheadmetacharsetutf-8title验证码/titlestyle#inputCaptcha{height:30px;vertical-align:middle;}#verificationCodeImg{vertical-align:middle;}#checkCaptcha{height:40px;width:100px;}/style/headbodyh1输入验证码/h1dividconfirminputtypetextnameinputCaptchaidinputCaptchaimgidverificationCodeImgsrc/captcha/getCaptchastylecursor:pointer;title看不清换一张/inputtypebuttonvalue提交idcheckCaptcha/divscriptsrchttps://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js/scriptscript$(#verificationCodeImg).click(function(){$(this).hide().attr(src,/captcha/getCaptcha?dtnewDate().getTime()).fadeIn();});$(#checkCaptcha).click(function(){$.ajax({type:post,url:/captcha/check,data:{captcha:$(#inputCaptcha).val()},success:function(result){if(result)location.hrefsuccess.html;elsealert(验证码错误,请重新输入);}})});/script/body/html