java Spring验证抽象请求参数类

vybvopom  于 2022-11-20  发布在  Java
关注(0)|答案(2)|浏览(149)

我尝试编写一个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是一个抽象类,其中存在多个具体实现。根据传递的类别,ReportFactory将示例化正确的Report。ReportRequestDTO是一个包含生成报表所需的所有参数的类。如果将其传递给generate()方法,则生成报表。
根据ReportCategory的不同,可能需要不同的参数并需要验证,但也可能有一些通用的参数。
有没有可能先有一个带有公共参数的抽象类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;
}

但是我不能使用抽象类作为DTO,因为它不能被示例化。而且这会尝试验证foobar,即使我在ReportB中不需要它。
基本上,我希望这个端点能够生成所有报告。由于我还不知道哪些报告存在,哪些报告可能在未来添加,以及它们需要哪些参数,我希望DTO是可扩展的,这样我就不必再接触端点,只需实现报告并创建一个DTO,该DTO使用该报告所需的参数扩展ReportRequestDTO。
因此,我需要一个可以用作ReportRequestDTO的对象,该对象可以使用所有报表的所有参数进行扩展,以便我可以在请求中传递这些参数,然后我将使用请求参数示例化特定报表的DTO并对其进行验证。

agxfikkp

agxfikkp1#

您可以使用后验证。我不明白您为什么需要它,因为在一个请求端点主体中只能有一个输入结构。您是否希望从请求中剪切数据并忽略未使用的数据?无论如何,这也是一个解决方案。

**选项1:**插入javax.validation.Validator接口并调用validate。它可以自动连接。API它只是结果Set
**选项2:**如果要抛出类似controller的异常,则必须创建一个或多个带有@Validated注解的Bean,例如:

第一个

ryevplcw

ryevplcw2#

因此,我最终将其更改为POST请求并允许JSON主体,然后将其解析为所需的DTO,如下所示:

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

getDTO()返回用JSON数据填充的具体DTO的示例,然后在@ Numichianswer中对其进行验证

相关问题