<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
SpringBoot 非常適合 Web 應用開發,我們可以使用它輕鬆地建立一個 Web 服務。在Spring Boot入門 裡面,我們已經使用其實現一個非常簡單的介面,輸出了 Hello World!下面我們模擬真實的場景來學習 SpringBoot 應用開發。
在實際的專案場景中,前後分離幾乎是所以專案的標配,全棧的時代的逐漸遠去,後端負責業務邏輯處理,前端負責資料展示成了一種固定的開發模式。一般來說,在後端提供的資料介面中,可能會存在兩種資料形式 Json 與 XML,具體會用到哪一種,往往會與公司的工程師文化相關。
對於 SpringBoot 來說 ,它預設會使用 Json 作為響應報文格式,我們用一個簡單的例子做一下測試:
首先,我們建立一個 UserController 用於處理前端的 Web 請求。
@Controller @RequestMapping("/sys/user") public class UserController { @RequestMapping("login") @ResponseBody public Map<String, String> login() { Map<String, String> hashMap = new HashMap<>(); hashMap.put("msg", "登入成功"); return hashMap; } }
相信這個事例對於大多數使用過 SpringMVC 的人來說都不會陌生,定義一個簡單的控制器及相當的對映,與通常返回 Url 的 Controller 不一樣的是,我們這裡使用了 @ResponseBody 註解,它表示此介面響應為純資料,不帶任何介面展示。請求對應的地址看到如下輸出:
很明顯,我們得到了想要的結果,一個標準格式的 Json 字串,是不是非常的簡單。
對於上面的程式碼來說,還可以做進一步的優化,由於所有的 Restful 介面都只是返回資料,所以我們可以直接在類級別上新增 @ResponseBody 註解。而大多數情況下,@Controller 與 @ResponseBody 又會一起使用,所以我們使用 @RestController 註解來替換掉它們,從而更加簡潔地實現功能。
@RestController @RequestMapping("/sys/user") public class UserController { @RequestMapping("login") public Map<String, String> login() { Map<String, String> hashMap = new HashMap<>(); hashMap.put("msg", "登入成功"); return hashMap; } }
大多數情況下,使用 Json 就可以滿足我們的需求了,但仍然存在某些特定的場景需要使用到 XML 形式的報文,如:微信公眾號開發。不過不用擔心,切換成 XML 報文也只需要做輕微的改動,新增相關依賴如下:
"com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.8"
然後就可以開始進行測試了,此處藉助一個模擬 HTTP 請求工具(Postman)來協助我們測試該介面,使用方法就不多說了,直接上圖:
在上面的測試範例裡,我們指定了 Accept 為 text/xml,這樣 SpringBoot 就會返回 XML 形式的資料。
對於每一家公司來說,都會定義自己的資料規範,一個統一且標準的資料規範對於系統維護來說是非常重要的,也在很在程度上提升了開發效率。
一般來說,介面響應至少需要告訴使用方三項資訊:狀態碼、描述、資料。其中,資料不是每個介面必須的,如果只是一個簡單修改的動作,可能就沒有必須返回資料了。下面我們定義一個 Result 類來封裝我們的響應報文。
public class Result { private int code; private String msg; private Object data; public Result(ResultCode resultCode, Object data) { this(resultCode); this.data = data; } public Result(ResultCode resultCode) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); } ... }
同時,定義一個列舉類來維護我們的狀態碼:
public enum ResultCode { SUCCESS(0, "請求成功"), WARN(-1, "網路異常,請稍後重試"); private int code; private String msg; ResultCode(int code, String msg) { this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; } }
這樣,我們的響應資料規範已基本建立。將上面程式碼中返回 Map 修改為返回 Result,按照指定規範返回資料,得到結果如下。
響應報文格式我們已經定義好了,那麼請求資料我們如何接收呢?一般來說,請求與響應會使用相同的報文形式,即,如果響應為Json,那麼請求也建議使用Json。如果想要為上面的登入請求新增輸入引數,需要完成以下幾步:
首先,我們定義好使用者實體:
public class User { private String username; private String password; ... }
然後,直接在對映方法裡面使用該實體進行引數接收,並將接收到的引數直接返回:
@RestController @RequestMapping("/sys/user") public class UserController { @RequestMapping("login") public Result login(@RequestBody User loginUser) { return new Result(ResultCode.SUCCESS, loginUser); } }
調出我們的Postman,填寫正確的Url,選擇POST方式傳送請求,選擇Body,將 Content-Type 設定成 application/json,填入 Json 格式的請求資料,點選 Send 即可得到如下結果。
資料接收非常成功,但在上面的響應報文中,存在著了一個非常嚴重的問題,那就是使用者的密碼也隨同使用者資訊一起返回給了使用者端,顯然這並不是一種正確的做法。我們需要對其進行一次過濾,由於 SpringBoot 預設使用 Jackson 作為 Json 序列化工具,如果想要過濾掉響應中的某些欄位,只需在過濾欄位對應的 get 方法上加上 @JsonIgnore 註解即可。但這樣又會引發另外一個問題,那就是請求中的欄位也被過濾掉了,對於這種問題,可以採用抽離請求引數模型的方式進行處理,即自定義一套引數接收的 Model,比如,接收使用者登入的會使用 UserModel 來進行引數接收,這樣使得請求引數模型與資料庫對映實體完全分離,在一定程度上提升了系統的安全性。
@RequestMapping("login") public Result login(@RequestBody UserModel userModel) { User user = new User(); user.setUsername(userModel.getUsername()); user.setPassword(userModel.getPassword()); return new Result(ResultCode.SUCCESS, user); }
替換成 Model 物件後,我們就可以在資料庫對映實體 User 上增加 @JsonIgnore 註解忽略該欄位的序列化,而不影響請求引數的輸入。
出於系統健壯性的考慮,一般來說,我們需要對所有的引數進行必要性校驗,如:登入請求時,如果沒有使用者名稱,程式應該立即駁回該請求。上面請求引數模型(Model)的抽象也使得我們對資料校驗更加方便,當然主要還是依賴於 SpringBoot 的 Validate 功能的強大支援。
對於登入介面來說,使用者名稱與密碼都是必輸的,那麼我們現在為其新增上對應的引數校驗,無需 if-else 判斷,簡單的幾個註解就可以幫助我們完成所有的工作。
@RequestMapping("login") public Result login(@RequestBody @Valid UserModel userModel) { ... } --- public class UserModel { private String username; private String password; @NotBlank(message = "使用者名稱不能為空") public String getUsername() { return username; } @NotBlank(message = "密碼不能為空") public String getPassword() { return password; } ... }
在上面的範例中,我們為請求引數的 Model 物件加上了 @Valid 註解,並在 Model 類中,對需要校驗欄位的 get 方法上新增相應的校驗註解。效果如下:
如果使用者的登入名為手機號,那麼就需要對登入名的格式做進一步的校驗,下面使用正規表示式來校驗手機號的合法性。
@NotBlank(message = "使用者名稱不能為空") @Pattern( regexp = "1(([38]\d)|(5[^4&&\d])|(4[579])|(7[0135678]))\d{8}", message = "手機號格式不合法" ) public String getUsername() { return username; }
在系統使用過程中,有很多地方需要對手機號的格式進行校驗,如:註冊、驗證碼傳送等。但校驗手機號的正規表示式又過於複雜,如果多處編寫,一旦運營商增加某個號段,對程式的維護人員來說就是一個噩耗。這時,可以使用自定義校驗註解來代替這些常用的校驗。
手機號校驗實現類 PhoneValidator:
public class PhoneValidator implements ConstraintValidator<Phone, String> { private Pattern pattern = Pattern.compile("1(([38]\d)|(5[^4&&\d])|(4[579])|(7[0135678]))\d{8}"); @Override public void initialize(Phone phone) { } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { return pattern.matcher(value).matches(); } }
手機號校驗註解 Phone:
@Constraint(validatedBy = PhoneValidator.class) @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Phone { String message() default "手機號格式不合法"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
Model 上的使用:
@Phone public String getUsername() { return username; }
這樣的話,如果因為某些不可抗拒因素導致校驗規則的變動,只需要修改一處理即可,維護成本大大降低。
專案的 github 地址:https://github.com/qchery/funda
到此這篇關於SpringBoot專案實戰之資料互動篇的文章就介紹到這了,更多相關SpringBoot資料互動內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45