タツノオトシゴのブログ

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

アノテーション「@GroupSequence」を使用した検証順序の指定

Bean Validationのアノテーションを1つのプロパティに複数付与し、検証時に複数件エラーとなる場合、エラーの表示順は実行するたびに異なります


通常は該当するエラー1つだけを表示し、かつ検証順を一定にしたいと思います。
このようなときは、アノテーション@GroupSequence」を使用して、順序を指定したグループを新たに定義します。

Commandの例

  • 順番がわかりやすくするために、グループのクラス「GroupOrder1〜3」を定義します。
  • アノテーションの属性「groups」に優先順に従いそれぞれ異なるグループを指定します。
// Commandの例
import javax.annotation.Resource;
import javax.validation.GroupSequence;
import javax.validation.constraints.Max;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.NotBlank;


// グループの定義
public interface GroupOrder1 {}
public interface GroupOrder2 {}
public interface GroupOrder3 {}

public static class SampleCommand {
    
    // グループ定義なし
    @NotBlank
    @Max(value=100)
    @Pattern(regexp="[0-9a-zA-Z]+")
    private String name1;
    
    // グループ指定あり
    // 各アノテーションの属性”group”は、優先順に従い付与します。
    @NotBlank(groups={GroupOrder1.class})
    @Max(value=100, groups={GroupOrder2.class})
    @Pattern(regexp="[0-9a-zA-Z]+", groups={GroupOrder3.class})
    private String name2;
    
    // getter/setterは省略
}

Controllerの定義例

  • アノテーション「@GroupSequence」を付与したグループ「GroupOrder」を新たに定義します。
    • 引数には、既に定義済のグループを検証したい順に指定します。
  • Controllerの引数のアノテーション「@Validated」のデフォルト属性に、新たに定義したグループを指定します。
import javax.validation.GroupSequence;

import org.springframework.validation.annotation.Validated;

@Controller
@RequestMapping("/beanvalidation/orderedValidation")
public class OrderedValidationController {
    
    ・・・省略
    
    // 順序を指定したグループの定義
    @GroupSequence({GroupOrder1.class, GroupOrder2.class, GroupOrder3.class})
    public interface GroupOrder {}
    
    // グループ指定あり(@GroupSequenceで定義)
    @RequestMapping(method=RequestMethod.POST, params="groupsequence")
    public ModelAndView doAction3(
            @ModelAttribute("orderedCommand")
            @Validated(GroupOrder.class) SampleCommand command,
            BindingResult bindingResult) {
        
        // エラーがある場合、自画面遷移する
        if(bindingResult.hasErrors()) {
            ModelAndView mav = new ModelAndView();
            mav.getModel().putAll(bindingResult.getModel());
            return mav;
        }
        
        ModelAndView mav = new ModelAndView("forward:/hello.html");
        
        return mav;
    }

}