春の研究ノートデータバインディング、バリデーション、BeanWrapperとプロパティエディタ

春の結合データ、パリティ、BeanWrapper、アトリビュートエディタ


データバインディング

(データバインディングが)便利であるデータのバインディングので、それができ、動的にアプリケーション(またはユーザー入力を処理するためのオブジェクト)のバインドを持つユーザー入力ドメインモデルへ。春は、この機能を完了するために、いわゆるのDataBinderを提供します。検証パッケージアップバリデータとのDataBinderは主に春FrameworkのMVCで使用されています。もちろん、彼らはまた、他の地域のニーズのために使用することができます。

バリデーション

春4.0バージョンの当初から、春のフレームワークは、ビーンVaildation 1.0(JSR-303)と豆Vaildation 1.1(JSR-349)をサポートしています

使用スプリング検証インタフェース
Springフレームワークは、バリデータオブジェクトへのインタフェースを提供します。ときバリデータのエラー動作させるために検証を行うことであなたは、オブジェクトを確認するためにそれを使用することができ、Validatorは、エラーオブジェクトを報告しないことを確認できます。
エラー:オブジェクトと関連付けられたエラーチェック情報にバインドされたデータを格納し、露光用。

public interface Validator {
    boolean supports(Class<?> var1);
    void validate(Object var1, Errors var2);
}

サポート(クラスVAR1):認証パラメータクラス支持体は、このクラスのインスタンスを検証します。
検証(オブジェクトVAR1を、エラーがVAR2) :検証エラーが発生した場合、指定されたオブジェクトを確認し、それがエラーに失敗のすべてをチェックするに反対します

public class Person implements Validator {
	private String name;
	private int    age;

	@Override public boolean supports(Class<?> aClass) {
		return Person.class.equals(aClass);
	}

	@Override public void validate(Object o, Errors errors) {
		// 校验 name 属性是否为空
		ValidationUtils.rejectIfEmpty(errors, "name", "name.empty");
		Person p = (Person) o;
		// 校验 age 是否符合业务规则
		if (p.getAge() < 0) {
			errors.rejectValue("age", "negativevalue");
		} else if (p.getAge() > 110) {
			errors.rejectValue("age", "too.darn.old");
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

我々は、それが認証によって拒否され、「名前」属性がnullまたは空の文字列の場合は、name属性をチェックするために(...)で静的メソッドrejectIfEmpty ValidationUtilsを使用しました。

その組み込みのプロパティクラスを確認するために、単一のクラスのバリデータを実装することは確かに可能であるが、好ましくは、内蔵されたクラスの各次バリデータを実装するため。例えば、Customerクラスは、2つの文字列プロパティfristNameとsecondNameを持って、オブジェクトの属性Addressクラスへの参照があります。アドレスオブジェクトには、独立したAddressValidatorを達成するために、Customerオブジェクトの独立していてもよいです。あなたはCustomerValidatorは内部AddressValidatorのロジックを再利用することではなく、ペーストをコピーしたくない場合は、あなたはあなたの中にCustomerValidatorに注射AddressValidatorオブジェクトを依存関係、または1つを作成することができます。

public class CustomerValidator implements Validator {
    private final Validator addressValidator;

    public CustomerValidator(Validator addressValidator) {
        if (addressValidator == null) {
            throw new IllegalArgumentException("The supplied [Validator] is " +
                "required and must not be null.");
        }
        if (!addressValidator.supports(Address.class)) {
            throw new IllegalArgumentException("The supplied [Validator] must " +
                "support the validation of [Address] instances.");
        }
        this.addressValidator = addressValidator;
    }


    public boolean supports(Class clazz) {
        return Customer.class.isAssignableFrom(clazz);
    }

    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
        Customer customer = (Customer) target;
        try {
            errors.pushNestedPath("address");
            ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
    }
}

豆処理とBeanWrapper

org.springframework.beansパッケージは、標準のJavaBeanを、以下、JavaBeanクラスは、デフォルトコンストラクタは、パラメータはありませんです。クラス属性は、setterメソッドがゲッター、命名規則に従ってください。どのbingoMadness getBingoMadnessとsetBingoMadness呼び出されるメソッドによって、このような性質を持っています。

org.springframework.beansパッケージには、非常に重要なクラスBeanWrapperインタフェースを有し、その実装クラスはBeanWrapperImplに対応します。
BeanWrapperは、プロパティ記述子を取得し、設定して(個別に、または一括で)プロパティ値を取得するために設けられ、クエリが読み取り専用または書き込み可能および他の機能だけでなく、ネストされたBeanWrapper特性をサポートします。
BeanWrapperは、ターゲットクラスのコードを支援を必要とせずに標準のJavaBeanのPropertyChangeListenersとのVetoableChangeListenersを追加する機能をサポートしています。BeanWrapperはまた、インデックス付きプロパティのセットを提供します。通常の状況下で、我々は直接BeanWrapperが、のDataBinderやたBeanFactoryアプリケーションを使用しないでください。
BeanWrapper名前自体がその機能を示唆:豆のパッケージの振る舞いを、このような特性を設定して検索すると。

設定した属性値を取得し、参照属性の
設定を完了するまでにsetPropertyValue、setPropertyValues、getPropertyValueのgetPropertyValuesとメソッドを使用してプロパティを取得。

プロパティの例

表現 説明
それぞれ、プロパティ名とメソッドのgetName()isName、または()とのsetName(...)を表示します。
アカウント名 基準点は、対応するgetAccount()。SetNameメソッド()とgetAccount、プロパティアカウントの属性名()。関連項目GetName()
アカウント[2] 参照は、第三の要素を考慮するポイント属性、インデックス付きプロパティリスト(リスト)または他の天然に順序付けられ、アレイ(配列)であってもよいです。
アカウント[COMPANYNAME] アカウントエンティティキーのCOMPANYNAMEへの地図のポイントに対応する(キー)値

サンプル・クラス

public class Company {

    private String name;
    private Employee managingDirector;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Employee getManagingDirector() {
        return this.managingDirector;
    }

    public void setManagingDirector(Employee managingDirector) {
        this.managingDirector = managingDirector;
    }
}

public class Employee {

    private String name;

    private float salary;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getSalary() {
        return salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }
}

企業と従業員のクラスの上記の2つの例のプロパティを取得および設定する方法の例:

BeanWrapper company = new BeanWrapperImpl(new Company());
company.setPropertyValue("name", "Some Company Inc.");
PropertyValue value = new PropertyValue("name", "Some Company Inc.");
company.setPropertyValue(value);

BeanWrapper jim = new BeanWrapperImpl(new Employee());
jim.setPropertyValue("name", "Jim Stravinsky");
company.setPropertyValue("managingDirector", jim.getWrappedInstance());
Float salary = (Float) company.getPropertyValue("managingDirector.salary");

内蔵PropertyEditorは達成
スプリングオブジェクト間と文字列の効率的な変換のためのPropertyEditorはを使用します。例えば、日付雇用者より容易に理解することができる方法は、(「2007-14-09」の文字列)を示しています。同時に、私たちは、人々がオリジナルのプリミティブ型の日付に形成する可能性が高いことを理解することができます(あるいは人間が読める入力の形式で任意の日付に対応するDateオブジェクトに変換することができます)。あなたがする必要がある場合は、この動作は、カスタムエディタのjava.bean.propertyeditorタイプを登録することによって達成することができます。

属性の編集は、次の2つの方法で使用されます。

  1. Beanプロパティを設定するのPropertyEditorを使用します。XMLファイルで宣言されたBeanのプロパティの値として文字列を使用する場合は、ClassEditorを使用して春には(クラス・パラメータの対応するプロパティのセッターであれば)クラスオブジェクトにパラメータを解決しようとします。
  2. パースHTTPリクエスト・パラメータが行われ、各種のPropertyEditorを使用して実装され、これらのCommandControllerにMVCフレームワークSpringのすべてのサブクラスをバインド手動で実装することができます。

春は私たちの仕事を簡素化し、多くのPropertyEditorを実装しています。org.springframework.beans.propertyeditorsパッケージで。デフォルトでは、ほとんどがBeanWrapperImpl実装クラスに登録された適切なデフォルトを持っています。

カテゴリ 説明
ByteArrayPropertyEditor バイト配列のためのエディタ。文字列は、単純にそれに対応するバイト形式に変換されます。BeanWrapperImplではより良いデフォルトで登録。
ClassEditor これは、実際のクラスオブジェクトまたは周りに他の方法で解決すべきクラス名の文字列として表示されます。このクラスが見つからない場合は、それがより良いデフォルトで登録されてBeanWrapperImplではIllegalArgumentException例外がスローされます。
CustomBooleanEditor ブール型プロパティカスタムプロパティエディタの場合。BeanWrapperImpl良いではデフォルトで登録されたが、彼らの行動をカバーし、ユーザー定義エディタインスタンスすることができます。
CustomCollectionEditor コレクション(コレクション)エディタ、任意のソースコレクション(コレクション)は、ターゲットの種類のオブジェクトの集合に変換されます。
CustomDateEditor カスタムたDateFormatのユーザーを支援java.util.Date用のカスタムプロパティエディタについて。BeanWrapperImplのデフォルトは、ユーザーが適切な形式を指定して登録する必要があり、登録されていません。
CustomNumberEditor プロパティエディタのカスタムサブクラス整数、ロング、フロート、ダブル、など数。BeanWrapperImpl良いではデフォルトで登録されたが、彼らの行動をカバーし、ユーザー定義エディタインスタンスすることができます。
FileEditor java.io.Fileのオブジェクトに文字列を分解できる。BeanWrapperImpl良いではデフォルトで登録されました。
InputStreamEditor 一方向プロパティエディタ、テキスト文字列と入力ストリーム(中間ResourceEditorおよびリソースを介して)ことができるので、入力ストリームのプロパティは直接文字列として設定することができます。(注)デフォルトでは、このプロパティは、あなたのためのInputStreamを閉じません。BeanWrapperImplではより良いデフォルトで登録。
LocaleEditor Stringオブジェクトとオブジェクトのロケールとの相互変換。(文字列は、[言語]で[国立】良好デフォルトで登録BeanWrapperImplにおけるローカルオブジェクトのtoString()メソッドが得られること[変数]、同じ結果)。
PatternEditor JDKは、パターンオブジェクト、およびその逆の文字列に変換することができます。
PropertiesEditor 文字列プロパティオブジェクトが(フォーマットの種類を所定のJavaDoc java.lang.Propertiesにより)に変換することができます。BeanWrapperImplではより良いデフォルトで登録。
StringTrimmerEditor NULL値オプションを持つ空の文字列を変換するには、(トリム)、String型のプロパティエディタをトリミングするための一つ。デフォルトは、登録されていない、必要なときにユーザが登録しておく必要があります。
URLEditor URLの文字列表現は、特定のURLオブジェクトに変換することができます。BeanWrapperImplではより良いデフォルトで登録。

カスタムPropertyEditorは登録
時に文字列値にBeanプロパティ、春のIoCコンテナは、最終的には、これらの属性にJavaBeansのPropertyEditorは、複雑な文字列の標準タイプを使用しています。春には多くのカスタムPropertyEditorは実装を予め登録します。

あなたがPropertyEditorは、独自の定義を登録したい場合は、その後、いくつかの異なるメカニズムがあります。

  1. (通常は不便でお勧めします)ほとんどの手動による方法は、ConfigurableBeanFactoryインタフェースregisterCustomEditor()メソッドを使用することです。ビーンファクトリポストプロセッサは、たBeanFactoryで実現することができるが一緒に使用されるが、プロパティを確立するための基準があります。したがって、それは強く推奨されたアプローチは、ApplicationContextのと一緒にそれを使用することです。これは、知覚とコンテナを使用しながら展開する同様に、他のBeanと、それは同じになるだろう。
  2. CustomEditorConfigurerプロセッサという特別な豆の工場を使用して
public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered {}

public class ExoticType {

    private String name;

    public ExoticType(String name) {
        this.name = name;
    }
}

public class DependsOnExoticType {

    private ExoticType type;

    public void setType(ExoticType type) {
        this.type = type;
    }
}

次に我々は、XMLのtype属性を設定するために指定した文字列Beanの値を宣言する必要があり、その後のPropertyEditorは舞台裏で、あなたが実際のオブジェクトに変換するために役立つだろうExoticType

<bean id="sample" class="example.DependsOnExoticType">
    <property name="type" value="aNameForExoticType"/>
</bean>

PropertyEditorはの実現

public class ExoticTypeEditor extends PropertyEditorSupport {

    public void setAsText(String text) {
        setValue(new ExoticType(text.toUpperCase()));
    }
}

最後に、その後、ApplicationContextのニーズに応じてそれを使用することができ、CustomEditorConfigurerを使用する新しいPropertyEditorはのApplicationContextを登録

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="example.ExoticType" value="example.ExoticTypeEditor"/>
        </map>
    </property>
</bean>

PropertyEditorRegistrarsを使用して
別の方法にプロパティエディタのSpringコンテナを登録するPropertyEditorRegistrarを作成して使用することです。別の例では、あなたが(例えば、対応する書き込みレジスタはその後、多くの場合、それを再利用する場合があります)同じプロパティエディタを必要とするときインタフェースは特に便利です。ワークとPropertyEditorRegistrars PropertyEditorRegistryインターフェース、BeanWrapper(とのDataBinder)のスプリングによって実現PropertyEditorRegistryインタフェース。この場合とのDataBinderスプリングMVCコントローラは容易に追加CustomEditorConfigurer PropertyEditorRegistrarsを共有することができる:。PropertyEditorRegistrarsは特に便利、CustomEditorConfigurerと併せて使用される場合、CustomEditorConfigurerはsetPropertyEditorRegistrars(...)メソッドと呼ばれる公開さ また、カスタムエディタは、もはや同期させる必要がありません:PropertyEditorRegistrarを毎回作成したBeanは、新しいPropertyEditorはを作成します。

各プロパティエディタの新しいインスタンスを作成しますregisterCustomEditors(...)メソッドを実装する際に作成するために、どのように自分自身のPropertyEditorRegistrarを実現しました。

public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
    }
}

CustomEditorConfigurerを設定し、インスタンスのCustomPropertyEditorRegistrarを注入する方法:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="propertyEditorRegistrars">
        <list>
            <ref bean="customPropertyEditorRegistrar"/>
        </list>
    </property>
</bean>

<bean id="customPropertyEditorRegistrar"
    class="com.foo.editors.spring.CustomPropertyEditorRegistrar"/>

最終的に(例えばSimpleFormControllerなど)データバインディングPropertyEditorRegistrarsコントローラ(ためのスプリングMVCウェブフレームの)組み合わせて使用​​することが容易です。次の例では、initBinderのpropertyeditorregistry(...)メソッドの実現を使用しています。

public final class RegisterUserController extends SimpleFormController {

    private final PropertyEditorRegistrar customPropertyEditorRegistrar;

    public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
        this.customPropertyEditorRegistrar = propertyEditorRegistrar;
    }

    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        this.customPropertyEditorRegistrar.registerCustomEditors(binder);
    }
}

これは、コード登録モードPropertyEditorは、より簡潔にすることができ(initBinder(...)のみ一行に実装されている)、そしてその後必要コントローラと同数で共有クラスにカプセル化された一般的なPropertyEditor登録コードを、可能にします。

おすすめ

転載: blog.csdn.net/qq_16830879/article/details/92086705