spring-boot json數據交互


最近在弄監控主機項目,對javaweb又再努力學習。實際的項目場景中,先後分離幾乎是因此項目的標配,全棧的時代的逐漸遠去,後端負責業務邏輯處理,前端負責數據展現成了一種固定的開發模式。像thymeleaf這種東西無法實現先後端分離模板難學也只有寫java的才用吧,仍是用js模板引擎接受json好。html

1. Json報文

SpringBoot 默認會使用 Json 做爲響應報文格式。首先,咱們建立一個 UserController 用於處理前端的 Web 請求。
定義一個簡單的控制器,與一般返回 Url 的 Controller 不同的是,login() 使用了 @ResponseBody 註解,它表示此接口響應爲純數據,不帶任何界面展現,能夠得到標準Json前端

@Controller     //等同於springmvc @Controller 能夠返回字符串 跳轉至jsp等頁面
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    @ResponseBody
    public RespEntity login(@RequestBody ReqUser reqUser) {    //使用reqUser模型來接受,而不用User,實現 接收數據和實體的解耦和

        User user = new User();
        if(reqUser != null) {
            user.setName(reqUser.getName());
            user.setPassword(reqUser.getPassword());
        }

        return new RespEntity(RespCode.SUCCESS, user);    //返回的響應實體具體看下節
    }
}

【注】:java

使用@Controller 註解,在對應的方法上,視圖解析器能夠解析return 的jsp,html頁面,而且跳轉到相應頁面web

若返回json等內容到頁面,則須要加@ResponseBody註解正則表達式

對於上面的代碼來講,還能夠作進一步的優化,因爲全部的 Restful 接口都只是返回數據,因此咱們能夠直接在類級別上添加 @ResponseBody 註解。而大多數狀況下,@Controller 與 @ResponseBody 又會一塊兒使用,因此咱們使用 @RestController 註解來替換掉它們,從而更加簡潔地實現功能。spring

 

2. 接口規範

對於每一家公司來講,都會定義本身的數據規範,一個統一且標準的數據規範對於系統維護來講是很是重要的,也在很在程度上提高了開發效率。數據庫

2.1 響應報文規範

接口響應至少須要告訴使用方三項信息:狀態碼、描述、數據。其中,數據不是每一個接口必須的,若是隻是一個簡單修改的動做,可能就沒有必須返回數據了。下面咱們定義一個 RespEntity類來封裝咱們的響應報文model:json

public class RespEntity {
    private int code;
    private String msg;
    private Object data;

    public RespEntity(RespCode respCode) {
        this.code = respCode.getCode();
        this.msg = respCode.getMsg();
    }

    public RespEntity(RespCode respCode, Object data) {
        this(respCode);
        this.data = data;
    }

    ...    
}

 

同時,定義一個枚舉類來維護咱們的狀態碼:後端

public enum RespCode {

    SUCCESS(0, "請求成功"),
    WARN(-1, "網絡異常,請稍後重試");

    private int code;
    private String msg;

    RespCode(int code, String msg) {
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

 

這樣,咱們的響應數據規範已基本創建。安全

2.2 請求數據規範

響應報文格式咱們已經定義好了,那麼請求數據咱們如何接收呢?
通常來講,請求與響應會使用相同的報文形式。若是響應爲Json,那麼請求也建議使用Json。
爲登陸請求添加輸入參數,首先,須要咱們定義好用戶實體User類,直接在映射方法login() 使用該實體進行參數接收,並將接收到的參數直接返回,1.節代碼已實現。
調出Postman,(參考 postman 入門使用:http://www.javashuo.com/article/p-ubaxlawi-ge.html

填寫正確的Url,選擇POST方式發送請求,選擇Body,將 Content-Type 設置成 application/json,填入 Json 格式的請求數據,點擊 Send 便可獲得以下結果。

數據接收很是成功,但在上面的響應報文中,存在着了一個很是嚴重的問題,那就是用戶的密碼也隨同用戶信息一塊兒返回給了客戶端,顯然這並非一種正確的作法。
咱們須要對其進行一次過濾,因爲 SpringBoot 默認使用 Jackson 做爲 Json 序列化工具,若是想要過濾掉響應中的某些字段,只需在過濾字段對應的 get 方法上加上 @JsonIgnore 註解便可。
但這樣又會引起另一個問題,那就是請求中的字段也被過濾掉了,對於這種問題,能夠採用抽離請求參數模型的方式進行處理,即自定義一套參數接收的 Model,好比,接收用戶登陸的會使用 ReqUser 來進行參數接收,這樣使得請求參數模型與數據庫映射實體徹底分離,在必定程度上提高了系統的安全性。替換成 Model 對象後(1.節的代碼已經替換好了),咱們就能夠在數據庫映射實體 User 上增長 @JsonIgnore 註解忽略該字段的序列化,而不影響請求參數的輸入。

3. 參數校驗

出於系統健壯性的考慮,咱們須要對全部的參數進行必要性校驗,如:登陸請求時,若是沒有用戶名,程序應該當即駁回該請求。上面請求參數模型(Model)的抽象也使得咱們對數據校驗更加方便,固然主要仍是依賴於 SpringBoot 的 Validate 功能的強大支持。

3.1. 簡單參數校驗

對於登陸接口來講,用戶名與密碼都是必輸的,那麼咱們如今爲其添加上對應的參數校驗,無需 if-else 判斷,簡單的幾個註解就能夠幫助咱們完成全部的工做。

public class LoginController {

    @RequestMapping("/login")
    @ResponseBody
    public RespEntity login(@RequestBody @Valid ReqUser reqUser) {

    }
}
----
public class ReqUser {
    @NotBlank(message = "用戶名不能爲空")
    public String getName() {
        return name;
    }

    @NotBlank(message = "密碼不能爲空")
    public String getPassword() {
        return password;
    }
    ...
}

 

咱們爲請求參數的 Model 對象ReqUser 加上了 @Valid 註解,並在 Model 類中對須要校驗字段的 get 方法上添加相應的校驗註解。效果以下:

3.2. 複雜參數校驗

  • 正則表達式校驗
    若是用戶的登陸名爲手機號,那麼就須要對登陸名的格式作進一步的校驗,下面使用正則表達式來校驗手機號的合法性。
@NotBlank(message = "用戶名不能爲空")
@Pattern(
        regexp = "1(([38]\\d)|(5[^4&&\\d])|(4[579])|(7[0135678]))\\d{8}",
        message = "手機號格式不合法"
)
public String getUsername() {
    return username;
}

 

  • 自定義校驗註解
    在系統使用過程當中,有不少地方須要對手機號的格式進行校驗,如:註冊、驗證碼發送等。
    但校驗手機號的正則表達式又過於複雜,若是多處編寫,一旦運營商增長某個號段,對程序的維護人員來講就是一個噩耗。這時,可使用自定義校驗註解來代替這些經常使用的校驗。

手機號校驗註解 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 {};

}

 

手機號校驗實現類 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();
    }
}

 

Model 上的使用:

@Phone
public String getUsername() {
    return username;
}

 

這樣的話,若是由於某些不可抗拒因素致使校驗規則的變更,只須要修改一處理便可,維護成本大大下降。

4. Xml 報文

大多數狀況下,使用 Json 就能夠知足咱們的需求了,但仍然存在某些特定的場景須要使用到 XML 形式的報文,如:微信公衆號開發。不過不用擔憂,切換成 XML 報文也只須要作輕微的改動,添加相關依賴以下:"com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.8"
而後就能夠開始進行測試了,此處藉助一個模擬 HTTP 請求工具(Postman)來協助咱們測試該接口:
在上面的測試範例裏,咱們指定了 Accept 爲 text/xml,這樣 SpringBoot 就會返回 XML 形式的數據。

相關文章
相關標籤/搜索