欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java使用validation攔截非法提交的數(shù)據(jù)的方法實現(xiàn)

 更新時間:2025年07月28日 09:38:34   作者:moxiaoran5753  
這篇文章主要介紹了Java使用validation攔截非法提交的數(shù)據(jù),包含依賴引入、實體類注解配置、控制器@Valid/@Validated使用規(guī)范,具有一定的參考價值,感興趣的可以了解一下

注意:本文使用的是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;

為了給前端返回時是可讀性強(qiáng)的文字說明,而不是一堆英文說明,需要在全局異常處理類中添加如下代碼:

@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
}

第二個返回示例(可進(jìn)一步優(yōu)化):

{
    "msg": "saveDevices.deviceDTOList[0].deviceName: 設(shè)備名稱不能為空, saveDevices.deviceDTOList[0].deviceImage: 設(shè)備圖片必須是一個合法的URL地址",
    "code": 500
}

拓展:分組校驗

很多時候,有新增和修改操作,需進(jìn)行不同的驗證,比如新增時無需帶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 = "認(rèn)證項目請求體")
public class CertificateDTO {

    @ApiModelProperty("申請認(rèn)證ID")
    @NotNull(message = "申請認(rèn)證ID不能為空",groups ={UpdateGroup.class})
    private Long id;

    @NotNull(message = "storeId不能為空",groups ={AddGroup.class,UpdateGroup.class})
    private Long storeId;

    @NotBlank(message = "認(rèn)證項目不能為空",groups ={AddGroup.class,UpdateGroup.class})
    @ApiModelProperty("認(rèn)證項目")
    private String project;

    @NotNull(message = "請上傳證書材料", groups = {AddGroup.class})
    @Size(min = 1, max = 9, message = "請上傳1-9張證書材料圖片", groups = {AddGroup.class, UpdateGroup.class})
    @ApiModelProperty("認(rèn)證項目材料圖片(1-9張)")
    private List<String> certificateMaterials;

    @Size(max = 200, message = "認(rèn)證說明最多200個字符")
    @ApiModelProperty("認(rèn)證說明/備注(最多200字)")
    private String instructions;
}

3.controller中的方法添加了分組

@ApiOperation("新增認(rèn)證管理")
@Log(title = "認(rèn)證管理", 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();
}

/**
 * 修改認(rèn)證管理
 */
@ApiOperation("修改認(rèn)證管理")
@Log(title = "認(rèn)證管理", 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. 默認(rèn)行為

  • 未指定分組:當(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)  // 指定默認(rèn)分組
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擴(kuò)展)支持分組

默認(rèn)校驗

  • 沒有分組的約束注解總是會被校驗
  • 有分組的約束只在指定對應(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)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Springboot核心機(jī)制詳細(xì)介紹

    Springboot核心機(jī)制詳細(xì)介紹

    SpringBoot的核心機(jī)制包括自動配置、起步依賴、主類和運(yùn)行器、以及嵌入式服務(wù)器等,通過這些機(jī)制,SpringBoot簡化了應(yīng)用開發(fā)過程,本文給大家介紹Springboot核心機(jī)制,感興趣的朋友一起看看吧
    2024-11-11
  • springmvc處理模型數(shù)據(jù)ModelAndView過程詳解

    springmvc處理模型數(shù)據(jù)ModelAndView過程詳解

    這篇文章主要介紹了springmvc處理模型數(shù)據(jù)ModelAndView過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • 新手了解java 反射基礎(chǔ)知識

    新手了解java 反射基礎(chǔ)知識

    這篇文章主要介紹了Java反射機(jī)制的相關(guān)內(nèi)容,涉及了class類的動態(tài)加載,獲取成員變量、構(gòu)造函數(shù)信息等信息,需要的朋友可以參考下,希望對你有所幫助
    2021-07-07
  • Java Spring 中的監(jiān)聽器Listener詳解與實戰(zhàn)教程

    Java Spring 中的監(jiān)聽器Listener詳解與實戰(zhàn)教程

    Spring 提供了多種監(jiān)聽器機(jī)制,可以用于監(jiān)聽?wèi)?yīng)用生命周期、會話生命周期和請求處理過程中的事件,這篇文章主要介紹了Java Spring 之監(jiān)聽器(Listener)詳解與實戰(zhàn),需要的朋友可以參考下
    2025-06-06
  • SpringBoot實現(xiàn)驗證碼的案例分享

    SpringBoot實現(xiàn)驗證碼的案例分享

    驗證碼可以有效防止其他人對某一個特定的注冊用戶用特定的程序,破解方式進(jìn)行不斷的登錄嘗試,我們其實很經(jīng)??吹?登錄一些網(wǎng)站其實是需要驗證碼的,所以本文給大家分享了SpringBoot實現(xiàn)驗證碼的案例,需要的朋友可以參考下
    2024-11-11
  • Java StringBuilder的用法示例

    Java StringBuilder的用法示例

    這篇文章主要給大家介紹了關(guān)于Java StringBuilder用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java之如何讀取Excel獲取真實行數(shù)

    Java之如何讀取Excel獲取真實行數(shù)

    這篇文章主要介紹了Java之如何讀取Excel獲取真實行數(shù)問題,具有很好的參考價值,希望對大家有所幫助。
    2023-06-06
  • Java調(diào)用第三方接口封裝實現(xiàn)

    Java調(diào)用第三方接口封裝實現(xiàn)

    本文主要介紹了Java調(diào)用第三方接口封裝實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Java中的getBytes()方法使用詳解

    Java中的getBytes()方法使用詳解

    這篇文章主要介紹了Java中g(shù)etBytes()方法使用的相關(guān)資料,getBytes()方法有多個重載形式,可以根據(jù)需要指定字符集來進(jìn)行轉(zhuǎn)換,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-05-05
  • 深入淺析Java 虛擬線程

    深入淺析Java 虛擬線程

    Java21引入了虛擬線程,這是一種輕量級線程,適用于IO密集型的應(yīng)用,可以極大提高應(yīng)用的性能和吞吐量,虛擬線程是由傳統(tǒng)線程執(zhí)行的,由JVM控制上下文切換,創(chuàng)建和銷毀的開銷小,適用于高并發(fā)場景,本文介紹Java 虛擬線程的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2025-02-02

最新評論