您好,登錄后才能下訂單哦!
這篇文章主要介紹“SpringBoot如何實現(xiàn)數(shù)據(jù)交互”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“SpringBoot如何實現(xiàn)數(shù)據(jù)交互”文章能幫助大家解決問題。
在實際的項目場景中,前后分離幾乎是所以項目的標配,全棧的時代的逐漸遠去,后端負責(zé)業(yè)務(wù)邏輯處理,前端負責(zé)數(shù)據(jù)展示成了一種固定的開發(fā)模式。一般來說,在后端提供的數(shù)據(jù)接口中,可能會存在兩種數(shù)據(jù)形式 Json 與 XML,具體會用到哪一種,往往會與公司的工程師文化相關(guān)。
對于 SpringBoot 來說 ,它默認會使用 Json 作為響應(yīng)報文格式,我們用一個簡單的例子做一下測試:
首先,我們創(chuàng)建一個 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; } }
相信這個事例對于大多數(shù)使用過 SpringMVC 的人來說都不會陌生,定義一個簡單的控制器及相當(dāng)?shù)挠成?,與通常返回 Url 的 Controller 不一樣的是,我們這里使用了 @ResponseBody 注解,它表示此接口響應(yīng)為純數(shù)據(jù),不帶任何界面展示。請求對應(yīng)的地址看到如下輸出:
很明顯,我們得到了想要的結(jié)果,一個標準格式的 Json 字符串,是不是非常的簡單。
對于上面的代碼來說,還可以做進一步的優(yōu)化,由于所有的 Restful 接口都只是返回數(shù)據(jù),所以我們可以直接在類級別上添加 @ResponseBody 注解。而大多數(shù)情況下,@Controller 與 @ResponseBody 又會一起使用,所以我們使用 @RestController 注解來替換掉它們,從而更加簡潔地實現(xiàn)功能。
@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; } }
大多數(shù)情況下,使用 Json 就可以滿足我們的需求了,但仍然存在某些特定的場景需要使用到 XML 形式的報文,如:微信公眾號開發(fā)。不過不用擔(dān)心,切換成 XML 報文也只需要做輕微的改動,添加相關(guān)依賴如下:
"com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.8"
然后就可以開始進行測試了,此處借助一個模擬 HTTP 請求工具(Postman)來協(xié)助我們測試該接口,使用方法就不多說了,直接上圖:
在上面的測試范例里,我們指定了 Accept 為 text/xml,這樣 SpringBoot 就會返回 XML 形式的數(shù)據(jù)。
對于每一家公司來說,都會定義自己的數(shù)據(jù)規(guī)范,一個統(tǒng)一且標準的數(shù)據(jù)規(guī)范對于系統(tǒng)維護來說是非常重要的,也在很在程度上提升了開發(fā)效率。
一般來說,接口響應(yīng)至少需要告訴使用方三項信息:狀態(tài)碼、描述、數(shù)據(jù)。其中,數(shù)據(jù)不是每個接口必須的,如果只是一個簡單修改的動作,可能就沒有必須返回數(shù)據(jù)了。下面我們定義一個 Result 類來封裝我們的響應(yīng)報文。
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(); } ... }
同時,定義一個枚舉類來維護我們的狀態(tài)碼:
public enum ResultCode { SUCCESS(0, "請求成功"), WARN(-1, "網(wǎng)絡(luò)異常,請稍后重試"); private int code; private String msg; ResultCode(int code, String msg) { this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; } }
這樣,我們的響應(yīng)數(shù)據(jù)規(guī)范已基本建立。將上面代碼中返回 Map 修改為返回 Result,按照指定規(guī)范返回數(shù)據(jù),得到結(jié)果如下。
響應(yīng)報文格式我們已經(jīng)定義好了,那么請求數(shù)據(jù)我們?nèi)绾谓邮漳??一般來說,請求與響應(yīng)會使用相同的報文形式,即,如果響應(yīng)為Json,那么請求也建議使用Json。如果想要為上面的登錄請求添加輸入?yún)?shù),需要完成以下幾步:
首先,我們定義好用戶實體:
public class User { private String username; private String password; ... }
然后,直接在映射方法里面使用該實體進行參數(shù)接收,并將接收到的參數(shù)直接返回:
@RestController @RequestMapping("/sys/user") public class UserController { @RequestMapping("login") public Result login(@RequestBody User loginUser) { return new Result(ResultCode.SUCCESS, loginUser); } }
調(diào)出我們的Postman,填寫正確的Url,選擇POST方式發(fā)送請求,選擇Body,將 Content-Type 設(shè)置成 application/json,填入 Json 格式的請求數(shù)據(jù),點擊 Send 即可得到如下結(jié)果。
數(shù)據(jù)接收非常成功,但在上面的響應(yīng)報文中,存在著了一個非常嚴重的問題,那就是用戶的密碼也隨同用戶信息一起返回給了客戶端,顯然這并不是一種正確的做法。我們需要對其進行一次過濾,由于 SpringBoot 默認使用 Jackson 作為 Json 序列化工具,如果想要過濾掉響應(yīng)中的某些字段,只需在過濾字段對應(yīng)的 get 方法上加上 @JsonIgnore 注解即可。但這樣又會引發(fā)另外一個問題,那就是請求中的字段也被過濾掉了,對于這種問題,可以采用抽離請求參數(shù)模型的方式進行處理,即自定義一套參數(shù)接收的 Model,比如,接收用戶登錄的會使用 UserModel 來進行參數(shù)接收,這樣使得請求參數(shù)模型與數(shù)據(jù)庫映射實體完全分離,在一定程度上提升了系統(tǒng)的安全性。
@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 對象后,我們就可以在數(shù)據(jù)庫映射實體 User 上增加 @JsonIgnore 注解忽略該字段的序列化,而不影響請求參數(shù)的輸入。
出于系統(tǒng)健壯性的考慮,一般來說,我們需要對所有的參數(shù)進行必要性校驗,如:登錄請求時,如果沒有用戶名,程序應(yīng)該立即駁回該請求。上面請求參數(shù)模型(Model)的抽象也使得我們對數(shù)據(jù)校驗更加方便,當(dāng)然主要還是依賴于 SpringBoot 的 Validate 功能的強大支持。
對于登錄接口來說,用戶名與密碼都是必輸?shù)模敲次覀儸F(xiàn)在為其添加上對應(yīng)的參數(shù)校驗,無需 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; } ... }
在上面的示例中,我們?yōu)檎埱髤?shù)的 Model 對象加上了 @Valid 注解,并在 Model 類中,對需要校驗字段的 get 方法上添加相應(yīng)的校驗注解。效果如下:
如果用戶的登錄名為手機號,那么就需要對登錄名的格式做進一步的校驗,下面使用正則表達式來校驗手機號的合法性。
@NotBlank(message = "用戶名不能為空") @Pattern( regexp = "1(([38]\\d)|(5[^4&&\\d])|(4[579])|(7[0135678]))\\d{8}", message = "手機號格式不合法" ) public String getUsername() { return username; }
在系統(tǒng)使用過程中,有很多地方需要對手機號的格式進行校驗,如:注冊、驗證碼發(fā)送等。但校驗手機號的正則表達式又過于復(fù)雜,如果多處編寫,一旦運營商增加某個號段,對程序的維護人員來說就是一個噩耗。這時,可以使用自定義校驗注解來代替這些常用的校驗。
手機號校驗實現(xiàn)類 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; }
這樣的話,如果因為某些不可抗拒因素導(dǎo)致校驗規(guī)則的變動,只需要修改一處理即可,維護成本大大降低。
關(guān)于“SpringBoot如何實現(xiàn)數(shù)據(jù)交互”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。