場景:
用戶在頁面操作:添加一名學生資訊(學生姓名為必填,其余屬性均為選填)
package com.wisdom.qiqiao;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 學生類
*/
@Data
public class Student implements Serializable {
/**
* 學生姓名(必填)
*/
private String studentName;
/**
* 學生年齡(選填)
*/
private Integer studentAge;
/**
* 學生住址(選填)
*/
private String studentAddress;
/**
* 興趣愛好(選填)
*/
private List<Hobby> hobbyList;
}
/**
* 興趣愛好類
*/
@Data
class Hobby implements Serializable {
/**
* 興趣愛好名稱(必填)
*/
private String hobbyName;
/**
* 興趣愛好程度(1~10分)(非必填)
*/
private Integer hobbyDegree;
}
假設用戶將所有屬性都進行填寫,則前端傳給后端的JSON格式如下:
{
"studentName": "張三",
"studentAge": 18,
"studentAddress": "廣東",
"hobbyList": [
{
"hobbyName": "Java",
"hobbyDegree": 8
},
{
"hobbyName": "前端",
"hobbyDegree": 7
}
]
}
假設用戶只填寫了“必填項”(即 學生姓名),則前端傳給后端JSON格式將存在異議,大致有四種:
格式一:
{
"studentName": "張三"
}
格式二:
{
"studentName": "張三",
"studentAge": null,
"studentAddress": null,
"hobbyList": null
}
格式三:
{
"studentName": "張三",
"studentAge": null,
"studentAddress": null,
"hobbyList": []
}
格式四:
{
"studentName": "張三",
"studentAge": "",
"studentAddress": "",
"hobbyList": []
}
由于Spring Boot為我們集成了簡便的校驗注解,所以一般會采用優雅寫法接收前端入參:
package com.wisdom.qiqiao;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
/**
* 學生 保存DTO
*
* @author Jiahai
*/
@Data
public class StudentForSaveDTO implements Serializable {
/**
* 學生姓名(必填)
*/
@NotBlank(message = "學生姓名 不可為空")
@Length(min = 2, max = 5, message = "學生名字 不合法")
private String studentName;
/**
* 學生年齡(選填)
*/
@Range(min = 18, max = 30, message = "學生年齡 不合法")
private Integer studentAge;
/**
* 學生住址(選填)
*/
@Length(min = 2, max = 5, message = "學生名字 不合法")
private String studentAddress;
/**
* 興趣愛好(選填)
*/
@Valid
@Size(min = 2, max = 5, message = "興趣愛好 不合法")
private List<HobbyForSaveDTO> hobbyList;
}
/**
* 興趣愛好類
*/
@Data
class HobbyForSaveDTO implements Serializable {
/**
* 興趣愛好名稱(必填)
*/
@Length(min = 2, max = 6, message = "興趣愛好名稱 不合法")
private String hobbyName;
/**
* 興趣愛好程度(1~10分)(非必填)
*/
@Range(min = 1, max = 10, message = "興趣愛好程度 不合法")
private Integer hobbyDegree;
}
package com.wisdom.qiqiao;
import com.wisdom.qiqiao.base.response.APIResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 學生 API
*
* @author Jiahai
*/
@RestController
@RequestMapping("/student")
public class StudentController {
/**
* 新增
*
* @param studentForSaveDTO 學生 新增入參DTO
* @return
*/
@PostMapping
public APIResult save(@Validated @RequestBody StudentForSaveDTO studentForSaveDTO) {
// TODO 保存學生資訊...
return APIResult.success();
}
}
Spring Boot 為我們提供的校驗注解(來自 spring boot starter validation),可以使得后端靈活處理以下場景:
-
對于必填欄位,可要求前端必填(例如 @NotBlank(message = "學生姓名 不可為空")),且對入參值進行指定規則校驗(例如 @Length(min = 2, max = 5, message = "學生名字 不合法"))
-
對于選填欄位,可靈活處理 當前端傳了值,則可進入指定校驗;如果前端不傳值,則跳過校驗
個人看法:
- 后端只需要關注前端入參的必要欄位(例如,如果后端能根據學生ID獲取到學生的teacherId,則在新增學生資訊的時候無需前端傳teacherId);
- 拋開前后端資料接收格式來說,僅從網路帶寬而言,前端傳無意義的欄位給后端,后端并不接收,但會占用更多的服務器帶寬進行傳輸;
- 用戶并未填寫的欄位,也以null或者空字串""傳給后端,則上述優雅接收入參方式不可行,后端則需要寫很多if-else等做判斷;
- 后端回傳給前端資料也是入參,假設前端只需要studentId與studentName,而后端則回傳學生表所有欄位,盡管前端可以只接收需要的欄位,但是后端從資料庫查詢消耗性能與帶寬、從服務器回傳到用戶瀏覽器又消耗一次帶寬,沒有意義,
綜上所述:
- 最優方案為 格式一;
- 前后端分離優勢之一是為了將服務器的壓力分攤到客戶端,前端對資料進行適當處理(如入參校驗,不用每次非法字符都給服務器校驗),并不消耗服務器資源,多做一步處理并不是什么難事;
- 相反,后端也會根據前端所需欄位而進行處理再回傳,所以前端是否也應該對資料進行適當處理 再與后端互動呢?
本文僅為個人觀點,歡迎大家發表意見,謝謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/242868.html
標籤:java
上一篇:idea搭建ssm框架
下一篇:Java實作順序表
