WebアプリケーションにSpringを使用しています。 Personエンティティの作成などのフォームでユーザーの入力を検証するには、JSR 303検証を使用してnull /空ではない、または有効なパターンなどをチェックします。ただし、フィールドが一意であることを確認するなど、サービスレイヤーでチェックすることもあります。データベースで例外がスローされない場合。この例外をコントローラーでキャッチし、フィールドにエラーを追加します。
これは基本的に、ここでベンJがオプション1で行っていることです https://stackoverflow.com/questions/3224749/passing-errors-back-to-the-view-from-the-service-layer
サービス層
public Person createPerson(String username, String fullName, String specialCode)
throws DuplicateUsernameException {
// Check if username exists and throw exception otherwise create person.
if (checkUsernameExists(username)) {
throw new DuplicateUsernameException();
}
Person person = new Person(username, fullName, specialCode);
return personDao.create(person);
}
コントローラ
void createPerson(Form form, Errors errors) {
try {
service.createPerson(form.getUsername(), form.getFullName(),
form.getSpecialCode());
} catch (DuplicateUsernameException e) {
errors.add("username", "This username exists");
}
// render view
...
}
これまではこれでうまくいきましたが、2つのフィールドが個別に一意であり、ユーザーに通知したいことを確認する必要があります。上記の例で、specialCodeも一意であることを確認したい場合は、サービスレイヤーの既存のチェックの下に別のチェックを追加して、別のDuplicateSpecialCodeExceptionをスローできます。
サービス層
public Person createPerson(String username, String fullName, String specialCode)
throws DuplicateUsernameException, DuplicateSpecialCodeException {
if (checkUsernameExists(username)) {
throw new DuplicateUsernameException();
}
if (checkSpecialCodeExists(specialCode)) {
throw new DuplicateSpecialCodeException();
}
Person person = new Person(username, fullName, specialCode);
return personDao.create(person);
}
コントローラ
void createPerson(Form form, Errors errors) {
try {
service.createPerson(form.getUsername(), form.getFullName(),
form.getSpecialCode());
} catch (DuplicateUsernameException e) {
errors.add("username", "This username exists");
} catch (DuplicateSpecialCodeException e) {
errors.add("specialCode", "This special code exists");
}
// render view
...
}
問題は、ユーザーが重複したユーザー名と重複したSpecialCodeを送信すると、重複したユーザー名のみが通知されることです。両方のフィールドを表示したい。
これを行うきちんとした方法は何ですか?
これまでの私の考えは:
これらの方法はどちらも、フィールドの名前と適切なエラーコードを知っているサービスレイヤーに依存します。このエラーコードは、レイヤーを別々に保つことに反するようです。
ほとんどの言語では、例外は他のクラスと同じように機能するクラスです。プロパティまたはメソッドをそれらに追加できます。それでは、UnableToCreatePersonException()のコンストラクタでデータ構造または別の種類のエラーDTOまたはエラーDTOのリストを渡すことを許可しないのはなぜですか?例外の一部が実装するIMultipleErrorsExceptionのような、エラーDTOのリストを返すgetAllErrors()などのメソッドを持つインターフェイスを定義することもできます。各エラーDTOには、適切なエラーメッセージを含む翻訳のキーが含まれる場合があり、コントローラーの責任により、これらのメッセージが適切な言語でユーザーに返されるようになります。または、DTOは、サービス層の例外からフィールドやエラーメッセージへのマッピングを処理できる、より洗練されたタイプである可能性があります。