タツノオトシゴのブログ

主にJavaに関するものです。

アノテーション「@Validated」と「@Valid」

BeanValidation(JSR-303)のアノテーションとして「@Valid」がありますが、これは、Spring MVCでControllerでCommandに対して値を検証したい場合に利用できます。

また、Spring自体にも似たアノテーション@Validated」(org.springframework.validation.annotation.Validated)が存在します。
ただし、@Validatedは、Spring3.1から追加されたものです。


違いは、Springの「@Validated」では、グループが指定できるということです。
Spring MVCでは、通常は「@Validated」を使用するべきですが、公式のマニュアルを見ると、@Validatedではなく@Validでサンプルが説明されています。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.servlet.ModelAndView;

// Springの@Validatedは、グループを指定できます。
@Controller
public class SampleController {

    @RequestMapping(value="/search")
    public ModelAndView search(
               @ModelAttribute @Validated(Group1.class) SearchCondition command) {
        ・・・
    }
}


もともと、BeanValidationの@Validの用途としては、JavaBeanをプロパティに持つネストしたクラスも検証対象とするためのものです。

そのため、Spring MVCのControllerの引数のCommandに対して検証を行う場合は、本来はSpringの「@Validated」を使用すべきです。

ただし、従来の用途であるネストしたクラスも検証したい場合は、Bean Validationの@Validを使用する必要があります。

// BeanValidationの@Validの使用例
public interface Complete extends Default {}
public interface BasicPostal {}
public interface FullPostal extends BasicPostal {}

public class Address {
    @NotNull(groups=BasicPostal.class)
    String street1;

    String street2;

    @ZipCode(groups=BasicPostal.class)
    String zipCode;

    @CodeChecker(groups=FullPostal.class)
    String doorCode;
}

public class User {
    // @Validはネストしたクラスも検証対象とするためのもの
    @Valid
    @ConvertGroup.List( {
        @ConvertGroup(from=Default.class, to=BasicPostal.class),
        @ConvertGroup(from=Complete.class, to=FullPostal.class)
    } )
    Set<Address> getAddresses() { [...] }
}