SpringBootで@PathVariableのバリデーション

SpringBootで@PathVariableのバリデーション

SpringBootで@PathVariableのバリデーションを行う方法について説明します。
@PathVariableは、リクエストURIの一部をメソッドの引数として受け取るために使用されますが、これには通常バリデーションが必要です。
以下にその実装方法を詳しく説明します。

1. 依存関係の追加

まず、バリデーションの機能を使用するために、spring-boot-starter-validation依存関係をpom.xmlに追加します。
これにより、javax.validation APIが利用可能になります。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. バリデーション用のカスタムアノテーションの作成

例えば、IDが特定の範囲内であるべきというバリデーションを行いたい場合、カスタムアノテーションを作成することができます。
以下は、@ValidIdというカスタムアノテーションの例です。

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 = IdValidator.class)
@Target({ ElementType.PARAMETER, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidId {
  String message() default "Invalid ID";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

続いて、IdValidatorというクラスを作成します。
このクラスは、ValidIdアノテーションのバリデーションロジックを実装します。

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class IdValidator implements ConstraintValidator<ValidId, Long> {

  @Override
  public void initialize(ValidId constraintAnnotation) {
    // 初期化が必要な場合に実装
  }

  @Override
  public boolean isValid(Long value, ConstraintValidatorContext context) {
    // バリデーションロジックを実装
    // 例えば、IDが正の整数であることを確認
    return value != null && value > 0;
  }
}

3. コントローラーでのバリデーションの使用

作成したカスタムアノテーションをコントローラーで使用することで、リクエストパラメータのバリデーションを実施できます。
以下に、@PathVariableとカスタムバリデーションを使った例を示します。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

  @GetMapping("/items/{id}")
  public String getItem(@PathVariable @ValidId Long id) {
    // バリデーションに成功した場合の処理
    return "Item ID: " + id;
  }
}

4. エラーハンドリング

バリデーションエラーが発生した場合、SpringBootは自動的に適切なエラーレスポンスを生成します。
ただし、カスタムエラーレスポンスが必要な場合は、@ControllerAdviceを使ってエラーハンドリングをカスタマイズできます。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.MethodArgumentNotValidException;

@RestControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ResponseEntity<String> handleValidationExceptions(MethodArgumentNotValidException ex) {
    // バリデーションエラーの詳細なメッセージを取得してカスタマイズすることができます
    String errorMessage = "Invalid input: " + ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
    return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
  }
}

このようにして、SpringBootアプリケーションで@PathVariableに対してバリデーションを追加することができます。
バリデーションロジックの追加やエラーハンドリングは、アプリケーションの要件に合わせて調整してください。