亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                spring Boot必用依賴框架

                spring Boot必用依賴框架

                使用Lombok框架

                在編寫POJO類型(包括實(shí)體類、VO、DTO等)時(shí),都有統(tǒng)一的編碼規(guī)范,例如:

              1. 屬性都是私有的
              2. 所有屬性都有對(duì)應(yīng)的Setter & Getter方法
              3. 應(yīng)該重寫`equals()`和`hashCode()`方法,以保證:如果2個(gè)對(duì)象的字面值完全相同,則`equals()`對(duì)比結(jié)果為`true`,且`hashCode()`返回值相同,如果2個(gè)對(duì)象的字面值不相同,則`equals()`對(duì)比結(jié)果為`false`,且`hashCode()`返回值不同
              4. 實(shí)現(xiàn)`Serializable`接口
              5. 為了便于觀察對(duì)象的各屬性值,通常還會(huì)重寫`toString()`方法。
              6. 由于以上操作方式非常固定,且涉及的代碼量雖然不難,但是篇幅較長(zhǎng),并且,當(dāng)類中的屬性需要修改時(shí)(包括修改原有屬性、或增加新屬性、刪除原有屬性),對(duì)應(yīng)的其它方法都需要修改(或重新生成),管理起來(lái)比較麻煩。

                使用Lombok框架可以極大的簡(jiǎn)化這些操作,此框架可以通過(guò)注解的方式,在編譯期來(lái)生成Setters & Getters、`equals()`、`hashCode()`、`toString()`,甚至生成構(gòu)造方法等,所以,一旦使用此框架,開發(fā)人員就只需要在類中聲明各屬性、實(shí)現(xiàn)`Serializable`、添加Lombok指定的注解即可。

                在Spring Boot中,添加Lombok依賴,可以在創(chuàng)建項(xiàng)目時(shí)勾選,也可以后期自行添加,依賴項(xiàng)的代碼為:

                //依賴 org.projectlombok lombok true

                完成后,在各POJO類型中,將不再需要在源代碼添加Setters & Getters、`equals()`、`hashCode()`、`toString()`這些方法,只需要在POJO類上添加`@Data`注解即可!

                當(dāng)添加`@Data`注解,且刪除相關(guān)方法后,由于源代碼中沒有相關(guān)方法,則調(diào)用了相關(guān)代碼的方法可能會(huì)報(bào)錯(cuò),但是,并不影響程序運(yùn)行!

                為了避免IntelliJ IDEA判斷失誤而提示了警告和錯(cuò)誤,推薦安裝Lombok插件,可參考:

                小辣椒插件

                【注】:無(wú)論是否安裝插件,都不影響代碼的編寫和運(yùn)行!

                Slf4j日志框架

                在開發(fā)實(shí)踐中,不允許使用`System.out.println()`或類似的輸出語(yǔ)句來(lái)輸出顯示關(guān)鍵數(shù)據(jù)(核心數(shù)據(jù)、敏感數(shù)據(jù)等),因?yàn)?,如果是這樣使用,無(wú)論是在開發(fā)環(huán)境,還是測(cè)試環(huán)境,還是生產(chǎn)環(huán)境中,這些輸出語(yǔ)句都將輸出相關(guān)信息,而刪除或添加這些輸出語(yǔ)句的操作成本比較高,操作可行性低。

                推薦的做法是使用日志框架來(lái)輸出相關(guān)信息!

                當(dāng)添加了Lombok依賴后,可以在需要使用日志的類上添加`@Slf4j`注解,然后,在類的任意中,均可使用名為`log`的變量,且調(diào)用其方法來(lái)輸出日志(名為`log`的變量也是Lombok框架在編譯期自動(dòng)補(bǔ)充的聲明并創(chuàng)建對(duì)象)!

                在Slf4j日志框架中,將日志的可顯示級(jí)別根據(jù)其重要程度(嚴(yán)重程度)由低到高分為:

              7. – trace:跟蹤信息
              8. – debug:調(diào)試信息
              9. – info:一般信息,通常不涉及關(guān)鍵流程和敏感數(shù)據(jù)
              10. – warn:警告信息,通常代碼可以運(yùn)行,但不夠完美,或不規(guī)范
              11. – error:錯(cuò)誤信息
              12. 在配置文件中,可以通過(guò)`logging.level.包名.類名`來(lái)設(shè)置當(dāng)前類的日志顯示級(jí)別,例如:

                // yml文件寫法logging: level: cn.celinf.boot.demo: info// .properties文件格式寫法logging.level.cn.celinf.boot.demo: info

                當(dāng)設(shè)置了顯示的日志級(jí)別后,僅顯示設(shè)置級(jí)別和更重要的級(jí)別的日志,例如,設(shè)置為`info`時(shí),只顯示`info`、`warn`、`error`,不會(huì)顯示`debug`、`trace`級(jí)別的日志!

                當(dāng)輸出日志時(shí),通過(guò)`log`變量調(diào)用`trace()`方法輸出的日志就是`trace`級(jí)別的,調(diào)用`debug()`方法輸出的日志就是`debug()`級(jí)別的,以此類推,可調(diào)用的方法還有`info()`、`warn()`、`error()`。

                在開發(fā)實(shí)踐中,關(guān)鍵數(shù)據(jù)和敏感數(shù)據(jù)都應(yīng)該通過(guò)`trace()`或`debug()`進(jìn)行輸出,在開發(fā)環(huán)境中,可以將日志的顯示級(jí)別設(shè)置為`trace`,則會(huì)顯示所有日志,當(dāng)需要交付到生產(chǎn)環(huán)境中時(shí),只需要將日志的顯示級(jí)別調(diào)整為`info`即可!

                默認(rèn)情況下,日志的顯示級(jí)別是`info`,所以,即使沒有在配置文件中進(jìn)行正確的配置,所有info、warn、error級(jí)別的日志都會(huì)輸出顯示。

                • 在配置時(shí),屬性名稱中的`logging.level`部分是必須的,在其后,必須寫至少1級(jí)包名
                • 發(fā)實(shí)踐中,屬性名稱通常配置為`logging.level.項(xiàng)目根包`

                在使用Slf4j時(shí),通過(guò)`log`調(diào)用的每種級(jí)別的方法都被重載了多次(各級(jí)別對(duì)應(yīng)除了方法名稱不同,重載的次數(shù)和參數(shù)列表均相同),推薦使用的方法是參數(shù)列表為`(String format, Object… arguments)`的,例如:

                public void trace(String format, Object… arguments);public void debug(String format, Object… arguments);public void info(String format, Object… arguments);public void warn(String format, Object… arguments);public void error(String format, Object… arguments);

                以上方法中,第1個(gè)參數(shù)是將要輸出的字符串的模式(模版),在此字符串中,如果需要包含某個(gè)變量值,則使用`{}`表示,如果有多個(gè)變量值,均是如此,然后,再通過(guò)第2個(gè)參數(shù)(是可變參數(shù))依次表示各`{}`對(duì)應(yīng)的值,例如:

                log.debug(“加密前的密碼:{},加密后的密碼:{}”, password, encodedPassword);

                使用這種做法,可以避免多變量時(shí)頻繁的拼接字符串,另外,日志框架會(huì)將第1個(gè)參數(shù)進(jìn)行緩存,以此提高后續(xù)每一次的執(zhí)行效率。

                在開發(fā)實(shí)踐中,應(yīng)該對(duì)程序執(zhí)行關(guān)鍵位置添加日志的輸出,通常包括:

              13. – 每個(gè)方法的第1行有效語(yǔ)句,表示代碼已經(jīng)執(zhí)行到此方法內(nèi),或此方法已經(jīng)被成功調(diào)用
              14. – 如果方法是有參數(shù)的,還應(yīng)該輸出參數(shù)的值
              15. – 關(guān)鍵數(shù)據(jù)或核心數(shù)據(jù)在改變之前和之后
              16. – 例如對(duì)密碼加密時(shí),應(yīng)該通過(guò)日志輸出加密前和加密后的密碼
              17. – 重要的操作執(zhí)行之前
              18. – 例如嘗試插入數(shù)據(jù)之前、修改數(shù)據(jù)之前,應(yīng)該通過(guò)日志輸出相關(guān)值
              19. – 程序走到某些重要的分支時(shí)
              20. – 例如經(jīng)過(guò)判斷,走向拋出異常之前
              21. 其實(shí),Slf4j日志框架只是日志的一種標(biāo)準(zhǔn),并不是具體的實(shí)現(xiàn)(感覺上與Java中的接口有點(diǎn)相似),常見有具體實(shí)現(xiàn)了日志功能的框架有l(wèi)og4j、logback等,為了統(tǒng)一標(biāo)準(zhǔn),所以才出現(xiàn)了Slf4j,同時(shí),由于log4j、logback等框架實(shí)現(xiàn)功能并不統(tǒng)一,所以,Slf4j提供了對(duì)主流日志框架的兼容,在Spring Boot工程中,`spring-boot-starter`就已經(jīng)依賴了`spring-boot-starter-logging`,而在此依賴下,通常包括Slf4j、具體的日志框架、Slf4j對(duì)具體日志框架的兼容。

                密碼加密(額外知識(shí)點(diǎn))

                【這并不是Spring Boot框架的知識(shí)點(diǎn)】

                對(duì)密碼進(jìn)行加密,可以有效的保障密碼安全,即使出現(xiàn)數(shù)據(jù)庫(kù)泄密,密碼安全也不會(huì)受到影響!為了實(shí)現(xiàn)此目標(biāo),需要在對(duì)密碼進(jìn)行加密時(shí),使用不可逆的算法進(jìn)行處理!

                通常,不可以使用加密算法對(duì)密碼進(jìn)行加密碼處理,從嚴(yán)格定義上來(lái)看,所有的加密算法都是可以逆向運(yùn)算的,即同時(shí)存在加密和解密這2種操作,加密算法只能用于保證傳輸過(guò)程的安全,并不應(yīng)該用于保證需要存儲(chǔ)下來(lái)的密碼的安全!

                哈希算法都是不可逆的,通常,用于處理密碼加密的算法中,典型的是一些消息摘要算法,例如MD5、SHA256或以上位數(shù)的算法。

                消息摘要算法的主要特征有:

              22. – 消息相同時(shí),摘要一定相同
              23. – 某種算法,無(wú)論消息長(zhǎng)度多少,摘要的長(zhǎng)度是固定的
              24. – 消息不同時(shí),摘要幾乎不會(huì)相同
              25. 在消息摘要算法中,以MD5為例,其運(yùn)算結(jié)果是一個(gè)128位長(zhǎng)度的二進(jìn)制數(shù),通常會(huì)轉(zhuǎn)換成十六進(jìn)制數(shù)顯示,所以是32位長(zhǎng)度的十六進(jìn)制數(shù),MD5也被稱之為128位算法。理論上,會(huì)存在2的128次方種類的摘要結(jié)果,且對(duì)應(yīng)2的128次方種不同的消息,如果在未超過(guò)2的128次方種消息中,存在2個(gè)或多個(gè)不同的消息對(duì)應(yīng)了相同的摘要,則稱之為:發(fā)生了碰撞。一個(gè)消息摘要算法是否安全,取決其實(shí)際的碰撞概率,關(guān)于消息摘要算法的破解,也是研究其碰撞概率。

                存在窮舉消息和摘要的對(duì)應(yīng)關(guān)系,并利用摘要在此對(duì)應(yīng)關(guān)系進(jìn)行查詢,從而得知消息的做法,但是,由于MD5是128位算法,全部窮舉是不可能實(shí)現(xiàn)的,所以,只要原始密碼(消息)足夠復(fù)雜,就不會(huì)被收錄到所記錄的對(duì)應(yīng)關(guān)系中去!

                為了進(jìn)一步提高密碼的安全性,在使用消息摘要算法進(jìn)行處理時(shí),通常還會(huì)加鹽!鹽值可以是任意的字符串,用于與密碼一起作為被消息摘要算法運(yùn)算的數(shù)據(jù)即可,例如:

                @Component // 實(shí)例化到spring容器中public class PasswordEncoder { /** * 加密 * @param rawPassword 源密碼 * @return */ public String encode(String rawPassword) { //鹽 UUID不重復(fù)隨機(jī)字符串 String salt = UUID.randomUUID().toString().replace(“-“,””); String encodedPassword = DigestUtils.md5DigestAsHex((salt+rawPassword).getBytes()); return salt+encodedPassword; }/** * 密碼對(duì)比 * @param rawPassword 原密碼 * @param encodedPassword 加密的密碼 * @return */ public Boolean decode(String rawPassword,String encodedPassword) { //鹽 String salt = encodedPassword.substring(0,32); String newPassword = DigestUtils.md5DigestAsHex((salt+rawPassword).getBytes()); //判斷是否相等 return newPassword.equals(encodedPassword); }}

                加鹽的目的是使得被運(yùn)算數(shù)據(jù)變得更加復(fù)雜,鹽值本身和用法并沒有明確要求!

                甚至,在某些用法或算法中,還會(huì)使用隨機(jī)的鹽值,則可以使用完全相同的原消息對(duì)應(yīng)的摘要卻不同!

                > 推薦了解:預(yù)計(jì)算的哈希鏈、彩虹表、雪花算法。

                為了進(jìn)一步保證密碼安全,還可以使用多重加密,即反復(fù)調(diào)用消息摘要算法。

                除此以外,還可以使用安全系數(shù)更高的算法,例如SHA-256是256位算法,SHA-384是384位算法,SHA-512是512位算法。

                Validation框架

                當(dāng)客戶端向服務(wù)器提交請(qǐng)求時(shí),如果請(qǐng)求數(shù)據(jù)出現(xiàn)明顯的問(wèn)題(例如關(guān)鍵數(shù)據(jù)為`null`、字符串的長(zhǎng)度不在可接受范圍內(nèi)、其它格式錯(cuò)誤),應(yīng)該直接響應(yīng)錯(cuò)誤,而不是將明顯錯(cuò)誤的請(qǐng)求參數(shù)傳遞到Service!

                > 關(guān)于判斷錯(cuò)誤,只有涉及數(shù)據(jù)庫(kù)中的數(shù)據(jù)才能判斷出結(jié)果的,都由Service進(jìn)行判斷,而基本的格式判斷,都由Controller進(jìn)行判斷。

                Validation框架是專門用于解決檢查數(shù)據(jù)基本格式有效性的,最早并不是Spring系列的框架,目前,Spring Boot提供了更好的支持,所以,通常結(jié)合在一起使用。

                在Spring Boot項(xiàng)目中,需要添加`spring-boot-starter-validation`依賴項(xiàng),例如:

                //依賴項(xiàng) org.springframework.boot spring-boot-starter-validation

                在控制器中,首先,對(duì)需要檢查數(shù)據(jù)格式的請(qǐng)求參數(shù)添加`@Valid`或`@Validated`注解(這2個(gè)注解沒有區(qū)別),例如:

                @RequestMapping(“/add-new”)public JsonResult addNew(@Validated AdminAddNewDTO adminAddNewDTO) { adminService.addNew(adminAddNewDTO); return JsonResult.ok();}

                真正需要檢查的是`AdminAddNewDTO`中各屬性的值,所以,接下來(lái)需要在此類的各屬性上通過(guò)注解來(lái)配置檢查的規(guī)則,例如:

                @Datapublic class AdminAddNewDTO implements Serializable {@NotNull // 驗(yàn)證規(guī)則為:不允許為nullprivate String username;@NotNullprivate String password;// ===== 原有其它代碼 =====}

                重啟項(xiàng)目,通過(guò)不提交用戶名的URL(例如:http://localhost:8080/admins/add-new)進(jìn)行訪問(wèn),在瀏覽器上會(huì)出現(xiàn)400錯(cuò)誤頁(yè)面,并且,在IntelliJ IDEA的控制臺(tái)會(huì)出現(xiàn)以下警告:

                //警告2022-06-07 11:37:53.424 WARN [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException:org.springframework.validation.BeanPropertyBindingResult: 1 errorsField error in object ‘adminAddNewDTO’ on field ‘username’: rejected value [null]; codes [NotNull.adminAddNewDTO.username,NotNull.username,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [adminAddNewDTO.username,username]; arguments []; default message [username]]; default message [不能為null]]

                從警告信息中可以看到,當(dāng)驗(yàn)證失敗時(shí)(不符合所使用的注解對(duì)應(yīng)的規(guī)則時(shí)),會(huì)出現(xiàn)`org.springframework.validation.BindException`異常,則自行處理此異常即可!

                首先,在`State`中添加新的枚舉:

                public enum State {OK(200),ERR_USERNAME(201),ERR_PASSWORD(202),ERR_BAD_REQUEST(400), // 新增ERR_INSERT(500);// ===== 原有其它代碼 =====}

                然后,在`GlobalExceptionHandler`中添加新的處理異常的方法:

                @ExceptionHandler(BindException.class)public JsonResult handleBindException(BindException e) {return JsonResult.fail(State.ERR_BAD_REQUEST, e.getMessage());}

                關(guān)于錯(cuò)誤提示信息,以上內(nèi)容中出現(xiàn)了`不能為null`的字樣,是默認(rèn)的提示文本,可以通過(guò)`@NotNull`注解的`message`屬性進(jìn)行配置,例如:

                @Datapublic class AdminAddNewDTO implements Serializable { @NotNull(message = “添加管理員失敗,請(qǐng)?zhí)峤挥脩裘?#8221;) private String username; @NotNull(message = “添加管理員失敗,請(qǐng)?zhí)峤幻艽a!”) private String password;// ===== 原有其它代碼 =====}

                然后,在處理異常時(shí),通過(guò)異常信息獲取自定義的提示文本:

                @ExceptionHandler(BindException.class)public JsonResult handleBindException(BindException e) {BindingResult bindingResult = e.getBindingResult();String defaultMessage = bindingResult.getFieldError().getDefaultMessage();return JsonResult.fail(State.ERR_BAD_REQUEST, defaultMessage);}

                再次運(yùn)行,在不提交用戶名和密碼的情況下,會(huì)隨機(jī)的提示用戶名或密碼驗(yàn)證失敗的提示文本中的某1條。

                在Validation框架中,還有其它許多注解,用于進(jìn)行不同格式的驗(yàn)證,例如:

              26. – `@NotEmpty`:只能添加在`String`類型上,不許為空字符串,例如`””`即視為空字符串
              27. – `@NotBlank`:只能添加在`String`類型上,不允許為空白,例如普通的空格可視為空白,使用TAB鍵輸入的內(nèi)容也是空白,(雖然不太可能在此處出現(xiàn))換行產(chǎn)生的空白區(qū)域也是空白
              28. – `@Size`:限制大小
              29. – `@Min`:限制最小值
              30. – `@Max`:限制最大值
              31. – `@Range`:可以配置`min`和`max`屬性,同時(shí)限制最小值和最大值
              32. – `@Pattern`:只能添加在`String`類型上,自行指定正則表達(dá)式進(jìn)行驗(yàn)證
              33. – 其它
              34. 以上注解,包括`@NotNull`是允許疊加使用的,即允許在同一個(gè)參數(shù)屬性上添加多個(gè)注解!

                以上注解均可以配置`message`屬性,用于指定驗(yàn)證失敗的提示文本。

                通常:(開發(fā)中)

              35. – 對(duì)于必須提交的屬性,都會(huì)添加`@NotNull`
              36. – 對(duì)于數(shù)值類型的,需要考慮是否添加`@Range`(則不需要使用`@Min`和`@Max`)
              37. – 對(duì)于字符串類型,都添加`@Pattern`注解進(jìn)行驗(yàn)證
              38. 常用檢驗(yàn)注解

                學(xué)習(xí)記錄,如有侵權(quán)請(qǐng)聯(lián)系刪除

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年6月12日 21:09
                下一篇 2022年6月12日 21:10

                相關(guān)推薦

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息