[SpringBoot] バリデーション – @Validated と @Valid の使い方
Spring Boot で REST API 作成時にバリデーションの方法を調べた。調査中に @Validated
と @Valid
が出てきて、書き方や使い方にもいくつかの方法があって、どういう場面でどう使ったらいいのかよく分からなかった。結果、「こうした!」という最終形態をメモ。
build.gradle
バリデーションのパッケージを追加する。
implementation 'org.springframework.boot:spring-boot-starter-validation'
Bean (エンティティ)
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Length;
import com.example.demo.infrastructure.validation.group.Update;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table
public class Hoge {
@NotNull
private Integer id;
@NotBlank(groups=Update.class) // ➀
@Length(max=30)
private String fieldA;
@Valid
private Foo foo;
@Size(min = 1, {Update.class, xxx.class}) // ➀ - 1
@Valid // ➁
private List<Foo> foos;
@NotEmpty
@Valid // ➁
private List<@NotBlank String> list;
}
ネストしている Bean
public class Foo {
@NotNull
private Integer id;
@NotBlank(groups=Update.class)
private String name;
}
➀ バリデーションのグループ化。特定の場面でのみ実行したいバリデーションを指定することができる。複数クラス指定する場合は、 ➀ – 1 のようにリスト形式で指定する。
➁ Bean やコレクションをネストしている場合、 @Valid
を付ける。 付けないと、ネスト先のバリデーションが効かない。
バリデーショングループのインタフェース
バリデーションのグループ化用のグループ。
import javax.validation.groups.Default;
public interface Update extends Default {
}
ここでは、javax.validation.groups.Default
を継承しているため、グループ指定したときは、Update
グループ + Default
グループ (グループ指定していないバリデーション)が実行される。
Controller
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.infrastructure.entity.Hoge;
import com.example.demo.infrastructure.validation.group.Update;
import lombok.RequiredArgsConstructor;
@RestController
@RequestMapping("/hoge")
@RequiredArgsConstructor
public class SampleController {
@PostMapping
public Hoge create(@Validated @RequestBody Hoge hoge) {
// 処理
}
@PutMapping("/{id}")
public Hoge update(@PathVariable("id") Integer id, @Validated(Update.class) @RequestBody Hoge hoge) {
// 処理
}
}
@RequestBody
の前に @Validated
を付ける。 @Validated(Update.class)
のようにグループもここで指定する。
create()
は、Default
グループ (グループ指定していないバリデーション)が実行される。