Java使用validation攔截非法提交的數(shù)據(jù)的方法實現(xiàn)
注意:本文使用的是Springboot 2.x版本,如果使用其他版本會略有差異,本文僅作拋轉(zhuǎn)引義,開發(fā)時需結(jié)合自己項目的實際情況來定。
一.引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>二.提交數(shù)據(jù)的實體類添加驗證規(guī)則的注解
需根據(jù)屬性的類型和業(yè)務(wù)規(guī)則添加相應(yīng)的注解
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author:
* @Desc:
* @create: 2025-04-14 10:32
**/
@Data
public class StoreDeviceDTO {
@NotNull(message = "storeId不能為空")
private Long storeId;
@NotBlank(message = "設(shè)備名稱不能為空")
private String deviceName;
@NotBlank(message = "設(shè)備圖片不能為空")
@URL(message = "設(shè)備圖片必須是一個合法的URL地址")
private String deviceImage;
}
三.在控制器方法上添加@Valid注解
@PostMapping("/addApply")
public AjaxResult add(@Valid @RequestBody StoreApplyDTO storeApplyDTO)
{
storeApplyService.saveStoreApply(storeApplyDTO);
return AjaxResult.success();
}如果傳的集合類型的數(shù)據(jù),則比較特殊,需要在控制器類名上加上@Validated注解,同時方法中也要加上上@Validated注解,正確的使用方式如下:
@RestController
@Validated
public class StoreDeviceController {
@Autowired
private IStoreDeviceService storeDevicesService;
@PostMapping("/saveDevices")
public AjaxResult saveDevices(@RequestBody @Validated List<@Valid StoreDeviceDTO> deviceDTOList) {
storeDevicesService.saveDevices(deviceDTOList);
return AjaxResult.success();
}
}其中@Valid和@Validated引用的包為:
import org.springframework.validation.annotation.Validated; import javax.validation.Valid;
為了給前端返回時是可讀性強的文字說明,而不是一堆英文說明,需要在全局異常處理類中添加如下代碼:
@RestControllerAdvice
public class GlobalExceptionHandler
{
/**
* 自定義驗證異常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
{
//log.error(e.getMessage(), e);
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return AjaxResult.error(message);
}
}第一個返回示例:
{
"msg": "門店id不能為空",
"code": 500
}第二個返回示例(可進一步優(yōu)化):
{
"msg": "saveDevices.deviceDTOList[0].deviceName: 設(shè)備名稱不能為空, saveDevices.deviceDTOList[0].deviceImage: 設(shè)備圖片必須是一個合法的URL地址",
"code": 500
}拓展:分組校驗
很多時候,有新增和修改操作,需進行不同的驗證,比如新增時無需帶id,而修改時必須帶id,此時可通過分組檢驗,以實現(xiàn)區(qū)別對接。下面是實現(xiàn)的過程:
1.創(chuàng)建新建和修改的分組interface
//新增
public interface AddGroup {
}
//修改
public interface UpdateGroup {
}2.請求體添加分組注解
import com.bbc.validate.group.AddGroup;
import com.bbc.validate.group.UpdateGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.*;
import java.util.List;
/**
* @author:
* @Desc:
* @create: 2025-03-22 14:34
**/
@Data
@ApiModel(description = "認證項目請求體")
public class CertificateDTO {
@ApiModelProperty("申請認證ID")
@NotNull(message = "申請認證ID不能為空",groups ={UpdateGroup.class})
private Long id;
@NotNull(message = "storeId不能為空",groups ={AddGroup.class,UpdateGroup.class})
private Long storeId;
@NotBlank(message = "認證項目不能為空",groups ={AddGroup.class,UpdateGroup.class})
@ApiModelProperty("認證項目")
private String project;
@NotNull(message = "請上傳證書材料", groups = {AddGroup.class})
@Size(min = 1, max = 9, message = "請上傳1-9張證書材料圖片", groups = {AddGroup.class, UpdateGroup.class})
@ApiModelProperty("認證項目材料圖片(1-9張)")
private List<String> certificateMaterials;
@Size(max = 200, message = "認證說明最多200個字符")
@ApiModelProperty("認證說明/備注(最多200字)")
private String instructions;
}3.controller中的方法添加了分組
@ApiOperation("新增認證管理")
@Log(title = "認證管理", businessType = BusinessType.INSERT)
@PostMapping("/saveProject")
@RepeatSubmit(interval = 5000, message = "不允許重復(fù)提交,請稍候再試")
public AjaxResult add(@Validated(AddGroup.class) @RequestBody CertificateDTO certificateDTO)
{
certificateService.saveCertificateProject(certificateDTO);
return AjaxResult.success();
}
/**
* 修改認證管理
*/
@ApiOperation("修改認證管理")
@Log(title = "認證管理", businessType = BusinessType.UPDATE)
@PutMapping("/editProject")
public AjaxResult edit(@Validated(UpdateGroup.class) @RequestBody CertificateDTO certicateDTO)
{
certificateService.updateCertificateProject(certicateDTO);
return AjaxResult.success();
}避坑指南:
如果DTO類某個屬性添加了分組校驗,但Controller方法未指定校驗分組,會導(dǎo)致分組校驗失效,沒有添加分組注解的基礎(chǔ)校驗仍然有效。
情況說明:
1. 默認行為
- 未指定分組:當(dāng)Controller方法沒有使用
@Validated指定分組時,只會校驗沒有分組的約束注解 - 有分組注解:帶有
groups屬性的校驗注解將被跳過(因為沒有添加@Validated注解)
2. 示例分析
public class CertificateDTO {
@NotEmpty(message = "證書材料不能為空", groups = {AddGroup.class}) // 有分組
private List<String> certificateMaterials;
@Size(max = 200) // 無分組
private String instructions;
}在Controller中:
@PostMapping
public void save(@RequestBody @Valid StoreCertificateDTO dto) {
// 只會校驗instructions字段
// certificateMaterials不會被校驗,因為未指定AddGroup分組
}3. 解決方案
方案1:在Controller類上添加@Validated注解
@RestController
@Validated(AddGroup.class) // 指定默認分組
public class CertificateController {
@PostMapping
public void save(@RequestBody @Valid CertificateDTO dto) {
// 現(xiàn)在會校驗AddGroup分組和沒有分組的約束
}
}方案2:在方法參數(shù)上指定分組
@PostMapping
public void save(@RequestBody @Validated(AddGroup.class) StoreCertificateDTO dto) {
// 明確指定校驗分組
}方案3:混合使用(推薦)
@RestController
@Validated // 類級別啟用校驗
public class CertificateController {
@PostMapping("/add")
public void add(@RequestBody @Validated(AddGroup.class) StoreCertificateDTO dto) {
// 添加操作使用AddGroup分組
}
@PostMapping("/update")
public void update(@RequestBody @Validated(UpdateGroup.class) StoreCertificateDTO dto) {
// 更新操作使用UpdateGroup分組
}
}4. 重要注意事項
@Valid vs @Validated:
@Valid(JSR-303)不支持分組@Validated(Spring擴展)支持分組
默認校驗:
- 沒有分組的約束注解總是會被校驗
- 有分組的約束只在指定對應(yīng)分組時才會校驗
繼承關(guān)系:
- 分組可以繼承,父接口的分組會被子接口繼承
分組雖好,使用不當(dāng)可能會得不到預(yù)期的結(jié)果,那么什么情況下要分組,什么情況下不分組呢:
5. 使用建議
- 明確指定分組:重要的業(yè)務(wù)校驗都應(yīng)該明確指定分組
- 分層設(shè)計:
- 基礎(chǔ)校驗(非空、格式等)可以不分組
- 業(yè)務(wù)規(guī)則校驗使用分組
- 文檔注釋:在代碼中注明各分組的用途
- 測試覆蓋:編寫測試驗證分組校驗是否按預(yù)期工作
到此這篇關(guān)于Java使用validation攔截非法提交的數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Java使用validation攔截非法提交內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot項目javax.validation使用方法詳解
- java validation 后臺參數(shù)驗證的使用詳解
- java使用Validation進行數(shù)據(jù)校驗的方式總結(jié)
- JAVA中通過Hibernate-Validation進行參數(shù)驗證
- JAVA中的字段校驗(validation)
- 使用javax.validation.constraints對請求體進行統(tǒng)一校驗
- Java參數(shù)校驗中validation和validator的區(qū)別詳解
- Java Validation Api實現(xiàn)原理解析
- Java Validation Api如何實現(xiàn)自定義注解
- Javax Validation自定義注解進行身份證號校驗
相關(guān)文章
springmvc處理模型數(shù)據(jù)ModelAndView過程詳解
這篇文章主要介紹了springmvc處理模型數(shù)據(jù)ModelAndView過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01
Java Spring 中的監(jiān)聽器Listener詳解與實戰(zhàn)教程
Spring 提供了多種監(jiān)聽器機制,可以用于監(jiān)聽應(yīng)用生命周期、會話生命周期和請求處理過程中的事件,這篇文章主要介紹了Java Spring 之監(jiān)聽器(Listener)詳解與實戰(zhàn),需要的朋友可以參考下2025-06-06

