SpringBootで相関チェックのバリデーション

SpringBootで相関チェックのバリデーション

SpringBootで相関チェックのバリデーションを実装するには、カスタムバリデーションロジックを作成する必要があります。
相関チェックとは、複数のフィールドの値が特定の条件を満たす必要がある場合に使います。
たとえば、開始日と終了日があり、終了日が開始日よりも後であることを確認するケースです。

以下に、SpringBootで相関チェックを実装するための基本的な手順を示します。

1. バリデーションクラスの作成

まず、カスタムアノテーションを作成します。
これは、特定の条件を検証するためのメタデータを提供します。

@DateRange アノテーション
package com.example.validation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = DateRangeValidator.class)
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DateRange {
  String message() default "End date must be after start date";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

2. バリデータークラスの作成

次に、カスタムアノテーションを検証するバリデータークラスを作成します。

DateRangeValidator クラス
package com.example.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.LocalDate;

public class DateRangeValidator implements ConstraintValidator<DateRange, DateRangeDTO> {

  @Override
  public void initialize(DateRange constraintAnnotation) {}

  @Override
  public boolean isValid(DateRangeDTO dateRangeDTO, ConstraintValidatorContext context) {
    if (dateRangeDTO == null) {
      return true; // Null values are handled by @NotNull or other constraints
    }

    LocalDate startDate = dateRangeDTO.getStartDate();
    LocalDate endDate = dateRangeDTO.getEndDate();

    if (startDate == null || endDate == null) {
      return true; // Consider null dates as valid or handle nulls separately
    }

    return endDate.isAfter(startDate);
  }
}

3. DTO クラスの作成

相関チェックを適用するDTO(データ転送オブジェクト)クラスを作成します。
このクラスに、カスタムアノテーションを付加します。

DateRangeDTO クラス
package com.example.dto;

import com.example.validation.DateRange;
import java.time.LocalDate;

@DateRange
public class DateRangeDTO {
  private LocalDate startDate;
  private LocalDate endDate;

  // Getters and Setters
  public LocalDate getStartDate() {
    return startDate;
  }

  public void setStartDate(LocalDate startDate) {
    this.startDate = startDate;
  }

  public LocalDate getEndDate() {
    return endDate;
  }

  public void setEndDate(LocalDate endDate) {
    this.endDate = endDate;
  }
}

4. コントローラでのバリデーション

コントローラでDTOのバリデーションを実行します。

コントローラクラス
package com.example.controller;

import com.example.dto.DateRangeDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/api")
public class DateRangeController {

  @PostMapping("/validate")
  public ResponseEntity<String> validateDateRange(@Valid @RequestBody DateRangeDTO dateRangeDTO) {
    // バリデーションに成功した場合の処理
    return ResponseEntity.ok("Validation passed");
  }
}

この実装では、DateRange アノテーションを使用して相関チェックを行い、バリデーションに失敗した場合にはエラーメッセージを返します。
この方法を使うことで、複雑なビジネスルールに対するバリデーションを簡単に管理できます。