新しいユーザーのためにusername(@NaturalId)
とpassword
を送信するフォームがあるとします。
一意のusername
を持つユーザーを追加したいと思います。 @Valid
アノテーションを使用してこの制約を検証するにはどうすればよいですか?そして、ユーザー名が一意でない場合、<form:error/>
を介してjspでこの情報をどのように表示できますか?
私の知る限り、これを行うための注釈はありません。 2つのオプションがあります
1つは、カスタムバリデータアノテーションを作成することです。 ここ は非常に良い例です。 DAOクラスを呼び出し、バリデーター実装の可用性を確認します
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
return userDAO.userNameAvailable(object); //some method to check username availability
}
[〜#〜]または[〜#〜]
エンティティクラスのプロパティでunique = trueを設定します。
@Column(unique = true)
private String userName;
ただし、これは@validでは機能せず、代わりに永続化時に例外をスローします。これを処理するには、適切なロジックを使用する必要があります。
最初の解決策は、完全な証拠ではありません。チェック this SOの回答。
2番目は失敗しません。
[〜#〜]更新[〜#〜]
NimChimpskyがコメントしたように、両方を一緒に使用することが具体的な解決策になります。
JSR-303は、必要なもの(@Unique
制約など)をサポートしていません。独自のバリデーターを作成する必要があります。これを行う方法については、ここで説明します。 https://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
しかし、それを行う前に、必ずこの回答を読んでください: https://stackoverflow.com/a/3499111/198172
そして、前の記事からのこの文:
@Uniqueが組み込みの制約の一部ではない理由は、検証中にSession/EntityManagerにアクセスすると、潜在的なファントムリードが開かれるためです。
UserDetailsServiceで準備されたSpringクラスを使用し、それを拡張してカスタマイズできます。
@Service
public class LoginDetailsServiceImpl implements UserDetailsService, Serializable {
@Autowired
LoginService loginService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username == "" || username.isEmpty()) {
throw new UsernameNotFoundException(String.format("User %s is invalid!", username));
}
Login login = loginService.find(username);
if (login == null) {
throw new UsernameNotFoundException(String.format("User %s does not exist!", username));
}
if (!loginService.scheduleChecking(login.getScheduled())) {
throw new UsernameNotFoundException(String.format("User %s is not authorized this time!", username));
}
//....