在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    spring Boot必用依賴框架

    spring Boot必用依賴框架

    使用Lombok框架

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

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

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

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

    //依賴 org.projectlombok lombok true

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

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

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

    小辣椒插件

    【注】:無論是否安裝插件,都不影響代碼的編寫和運行!

    Slf4j日志框架

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

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

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

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

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

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

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

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

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

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

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

    在使用Slf4j時,通過`log`調(diào)用的每種級別的方法都被重載了多次(各級別對應(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個參數(shù)是將要輸出的字符串的模式(模版),在此字符串中,如果需要包含某個變量值,則使用`{}`表示,如果有多個變量值,均是如此,然后,再通過第2個參數(shù)(是可變參數(shù))依次表示各`{}`對應(yīng)的值,例如:

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

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

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

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

    密碼加密(額外知識點)

    【這并不是Spring Boot框架的知識點】

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

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

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

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

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

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

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

    @Component // 實例化到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; }/** * 密碼對比 * @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); }}

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

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

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

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

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

    Validation框架

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

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

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

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

    //依賴項 org.springframework.boot spring-boot-starter-validation

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

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

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

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

    重啟項目,通過不提交用戶名的URL(例如:http://localhost:8080/admins/add-new)進(jìn)行訪問,在瀏覽器上會出現(xiàn)400錯誤頁面,并且,在IntelliJ IDEA的控制臺會出現(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īng)的規(guī)則時),會出現(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)于錯誤提示信息,以上內(nèi)容中出現(xiàn)了`不能為null`的字樣,是默認(rèn)的提示文本,可以通過`@NotNull`注解的`message`屬性進(jìn)行配置,例如:

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

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

    @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);}

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

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

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

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

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

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

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

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

    相關(guān)推薦

    聯(lián)系我們

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