![[Java][JHipster]バリデーションチェックを行う](https://devio2023-media.developers.io/wp-content/uploads/2013/09/java.png)
[Java][JHipster]バリデーションチェックを行う
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回はJHipsterを使いScaffoldでデータをCRUDする機能を実装しました。今回はこれに、サーバ側でバリデーションを行う機能を追加する方法について書きたいと思います。
実装する機能について
前回作成したArticleのEntityを登録する際に、同じタイトルが既に登録されていたらエラーとするバリデーションを実装します。画面上では以下の様な感じとなります。

バリデーションの実装
上記のバリデーションを実現するには以下を実装する必要があります。
- (入力した)タイトルに一致するArticleを検索する機能
 - バリデーションの判定を行い、エラー時にはエラーを返却する機能
 - 画面にエラーメッセージを表示する機能
 
以下、それぞれの実装について見ていきたいと思います。
タイトルに一致するArticleを検索する機能
この機能はデータの検索機能となるため、Repository層に実装します。「src/main/java/org/jhipster/repository/ArticleRepository.java」に「findByCurrentUserAndTitle」という名前で作成します。
src/main/java/org/jhipster/repository/ArticleRepository.java
package org.jhipster.repository;
(中略)
/**
 * Spring Data JPA repository for the Article entity.
 */
@SuppressWarnings("unused")
public interface ArticleRepository extends JpaRepository<Article,Long> {
    (中略)
    @Query("select article from Article article where article.user.login = ?#{principal.username} and article.title = :title")
    List<Article> findByCurrentUserAndTitle(@Param("title")String title);
}
Articleはユーザ毎に作成されるため、検索条件にユーザ名とタイトルを指定してArticleを検索しています(同一ユーザ名のユーザが複数いる場合については・・・、今回は無視します)。「@Query」でSQL文を記述しているため直感的に分かるかと思います。
バリデーション判定
バリデーションの判定については、画面で入力したデータのPostリクエストを受け取るコントローラに実装しました。
/src/main/java/org/jhipster/web/rest/ArticleResource.java
    @PostMapping("/articles")
    @Timed
    public ResponseEntity<Article> createArticle(@Valid @RequestBody Article article) throws URISyntaxException {
        log.debug("REST request to save Article : {}", article);
        if (article.getId() != null) {
            return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new article cannot already have an ID")).body(null);
        }
        List<Article> articles = articleRepository.findByCurrentUserAndTitle(article.getTitle());
        if(!articles.isEmpty()){
            return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "article.titleexists", "Title already exist!")).body(null);
        }
        Article result = articleRepository.save(article);
        return ResponseEntity.created(new URI("/api/articles/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
            .body(result);
    }
8〜11行目が今回追加したソースです。8行目で先に実装した「findByCurrentUserAndTitle」を呼び出して、タイトルが一致するデータを取得しています。9〜11行目ではデータが存在するかを判定し、存在する場合にはエラーメッセージのキー(「article.titleexists」)を指定して返却しています。6行目のreturn文とほぼ同じなのに注目してください。これはエラーメッセージ以外はScaffoldで作成された仕組みを踏襲しているためです。
画面に表示するエラーメッセージ
JHipsterではメッセージの定義にi18nを使用しています。今回は使用言語がデフォルト(英語)の場合のみメッセージを定義しました。「/src/main/webapp/i18n/en/global.json」の「error」項目にメッセージを追加しました。
/src/main/webapp/i18n/en/global.json
    (中略)
    "error": {
        (中略)
        "emailexists": "E-mail is already in use!",
        "idexists": "A new {{ entityName }} cannot already have an ID",
        "article": {
            "titleexists": "Title already exist!"
        }
    (中略)
「error」の中に「article」を作成し、その中に「titleexists」というキー名でメッセージを定義しています。このキーは先のコントローラ内で「article.titleexists」として指定したキーとなります。
まとめ
バリデーションチェックでよくある、サーバ側でのデータ検索 → バリデーション判定 → エラーメッセージの表示、というパターンを実装してみました。Scaffoldで用意されたソースを元に、少ない変更で実装できることが分かりました。






