2017-02-02 5 views
1

このメソッドのコード行は検証ロジックで占有されており、ここでは新しい検証ケースを追加し続けています。春サービスメソッドと私の春/ブートJavaプロジェクトでは、複雑な検証ロジック/ルール

このメソッドをリファクタリングして、このメソッドの外部で検証ロジックをより適切な場所に移動したいと考えています。それがSpringフレームワークでどのようにできるかをお勧めします。

+3

これのほとんどにJSR-303を使用し、コンポジットlogivをチェックするカスタム検証クラスを使用することもできます。例えば、最初のいくつかの小切手は '@ NotEmpty'に減らすことができます。 – chrylis

答えて

2

コメントにchrylisが記載されているので、JSR-303 bean検証を使用してこの目標を達成できます。

public class DecisionInput { 
    @NotEmpty 
    private String name; 
    @NotEmpty 
    private String description; 
    @NotEmpty 
    private String url; 
    @NotEmpty 
    private String imageUrl; 
    private Decision parentDecision; 
    private Tenant tenant; 
    @NotNull 
    private User user; 

    // Constructors, getters, setters, ... 
} 

@NotEmpty注釈があることに注意してください:あなたは、たとえば、検証注釈の追加を開始することができ、その後

public class DecisionInput { 
    private String name; 
    private String description; 
    private String url; 
    private String imageUrl; 
    private Decision parentDecision; 
    private Tenant tenant; 
    private User user; 

    // Constructors, getters, setters, ... 
} 

:最初のステップは、入力パラメータを含むクラスを作成することです標準的なJSR-303アノテーションではなく、Hibernateアノテーションです。標準のJSR-303を使用したい場合は、独自のカスタムバリデーターをいつでも作成できます。あなたのテナントとあなたの決定には、確かにカスタムバリデーターが必要です。まず注釈を作成してください(例:@ValidTenant)。あなたの注釈のクラスでは、例えば、@Constraint注釈を追加してください:

@Constraint(validatedBy = TenantValidator.class) // Your validator class 
@Target({ TYPE, ANNOTATION_TYPE }) // Static import from ElementType, change this to METHOD/FIELD if you want to create a validator for a single field (rather than a cross-field validation) 
@Retention(RUNTIME) // Static import from RetentionPolicy 
@Documented 
public @interface ValidTenant { 
    String message() default "{ValidTenant.message}"; 
    Class<?>[] groups() default { }; 
    Class<? extends Payload>[] payload() default { }; 
} 

は今、あなたは、たとえば、TenantValidatorクラスを作成し、それがConstraintValidator<ValidTenant, DecisionInput>を実装行う必要があります。

@Component 
public class TenantValidator implements ConstraintValidator<ValidTenant, DecisionInput> { 
    @Autowired 
    private TenantDAO tenantDao; 

    @Override 
    public void initialize(ValidTenant annotation) { 
    } 

    @Override 
    public boolean isValid(DecisionInput input, ConstraintValidatorContext context) { 
     List<Tenant> userTenants = tenantDao.findTenantsForUser(input.getUser().getId()); 
     return userTenants.contains(input.getTenant()); 
    } 
} 

同じ缶親の決定の検証のために行われなければならない。今、あなたはちょうどこれにあなたのサービスメソッドをリファクタリングすることができます:あなたがあなた自身のエラーメッセージを使用したい場合は

public Decision create(@Valid DecisionInput input) { 
    // No more validation logic necessary 
} 

、私はthis answerを読んで示唆しています。基本的にはValidationMessages.propertiesファイルを作成してそこにメッセージを入れます。

+0

詳細な回答ありがとう!もう1つの質問 - すべての検証呼び出しがサービスメソッドと同じトランザクションで実行されていますか? – alexanoid

+1

@alexanoid私は100%確信していませんが、私が知っている限り、アスペクトは同じトランザクションコンテキストで実行されるので、検証ロジックも同じコンテキストで実行されると思います。 – g00glen00b

関連する問題