簡體   English   中英

Spring 驗證抽象請求參數 class

[英]Spring validate abstract request parameter class

我正在嘗試編寫一個 spring 端點,它根據請求參數生成不同的報告

@GetMapping
@ResponseBody
public ResponseEntity<String> getReport(
    @RequestParam(value = "category") String category,
    @Valid ReportRequestDTO reportRequestDTO) {
    
    Optional<ReportCategory> reportCategory = ReportCategory.getReportCategoryByRequest(category);
    if (reportCategory.isEmpty()) {
        throw new ApiRequestException("Requested report category does not exist.");
    }
    try {
        Report report = reportFactory.getReport(reportCategory.get());
        return ResponseEntity.ok().body(report.generate(reportRequestDTO));
    } catch (Exception e) {
        throw new ApiRequestException("Could not generate report.", HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

ReportCategory 是一個枚舉,Report 是一個抽象 class,其中存在多個具體實現。 根據傳遞的類別,ReportFactory 將實例化正確的報表。 ReportRequestDTO 是一個 class,其中包含生成報告所需的所有參數。 如果將其傳遞給 generate() 方法,則會生成報告。

根據 ReportCategory,可能需要不同的參數並需要對其進行驗證,但也可能有一些通用參數。

是否有可能有一個帶有公共參數的抽象 class ReportRequestDTO,然后是每個帶有其唯一參數的報告的具體 DTO 實現,在傳遞給 generate() 方法之前根據報告類別進行實例化和驗證?

編輯:

我想要這樣的共享參數:

@Data
public abstract class ReportRequestDTO  {
    @NotEmpty
    private String foo;

    @NotEmpty
    private String bar;

}

然后對於每個 Report 的各個參數:

@Data
public class ReportADTO extends ReportRequestDTO  {
    @NotEmpty
    private String foobar;
}

但是我不能使用和抽象class作為DTO,因為它不能被實例化。 這也會嘗試驗證foobar ,即使我在 ReportB 中不需要它。

基本上我希望這個端點能夠生成所有報告。 由於我還不知道哪些報告存在,將來可能會添加,以及它們需要哪些參數,我希望 DTO 可以擴展,這樣我就不必再接觸端點,只需實施報告和創建一個 DTO,它使用該報告所需的參數擴展 ReportRequestDTO。

所以我需要的是一個 Object,我可以將它用作 ReportRequestDTO,它可以使用所有報告的所有參數進行擴展,以便我可以根據請求傳遞它們,然后我將使用請求參數為特定報告實例化 DTO 並驗證它.

您可以使用后驗證。 我不明白你為什么需要它,因為在一個請求端點正文中你只能有一個輸入結構。 您想從請求中剪切數據並忽略未使用的數據嗎? 無論如何,這也是一種解決方案。

選項 1:注入javax.validation.Validator接口並調用validate 它可以自動裝配。 API就是結果Set

選項 2:如果您想拋出 controller 之類的異常,則必須使用 @Validated 注釋創建一個/多個 bean,例如:

public class ModelA {
    @NotEmpty
    private String text;
    
    // getter setter
}
@Component // or use @Configuration with @Bean
@Validated
public class ReportA {
    public void generate(@Valid ModelA model) { ... }
}

所以我最終將其更改為 POST 請求並允許 JSON 正文,然后將其解析為所需的 DTO,如下所示:

    ReportRequestDTO reportRequestDTO = report.getDto();
    reportRequestDTO = new ObjectMapper().readValue(paramsJson, 
                               reportRequestDTO.getClass());

getDTO() 返回具體 DTO 的一個實例,該實例填充了 JSON 數據,然后按照@Numichi 答案進行驗證

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM