技術記事については、Qiitaにも稀に投稿しています。

NetBeansとJavaEEで、ポケモンの日英仏独韓の名前を返すRESTなAPIを開発してみた - 実装編 -

sleepCat

NetBeansとJavaEEを用いて、ポケモンの日本語名、英語名、ドイツ語名、フランス語名、韓国語名を返すRESTfulなAPIを開発してみようという記事の実装編です。

“NetBeansとJavaEEで、ポケモンの日英仏独韓の名前を返すRESTなAPIを開発してみた - 準備編 -”の続きです。

APIの流れ

作成したクラス群

前回の準備編で用意したクラスは以下の4つでした。

パッケージ / クラス名 用途
.pkmn.api
PkmnBaseApi.java
API本体のクラス。リクエストを受け取り、適切なLogicを呼び出し、値を返却する。
.pkmn.logic
PkmnBaseLogic.java
データの処理を行うクラス。APIからの呼び出しで、必要に応じてDAOを呼び出す。
.pkmn.dao
PkmnBaseDao.java
DB操作を行うクラス。Logicからの呼び出しでDBの値を取得・更新・削除する。
.pkmn.entity
PkmnBaseEntity.java
データ管理用のクラス。DBのレコードに対応している。

用途の欄にも記載してある通り、ブラウザからのリクエストを受けるのはAPI本体となるPkmnBaseApi.javaです。その後の流れは以下の通り。

apiFlow

基本的にはデータベースのレコードと対応した Entityクラスを箱として、DAOがデータを取得し、それをLogicがAPIに返す(必要ならここで何らかの処理をする?)みたいな流れです。

実装

用意したデータベース(pkmn_db)

pkmn_dbは以下のようなテーブル(pkmn_base)を持っています。中には図鑑番号をKeyとし、日本語名、英語名、ドイツ語名、フランス語名、韓国語名を格納できるようになっています。

mysql> show tables;
+--------------------+
| Tables_in__pkmn_db |
+--------------------+
| pkmn_base          |
+--------------------+
1 row in set (0.03 sec)

mysql> desc pkmn_base;
+------------------+-------------+------+-----+-------------------+-------+
| Field            | Type        | Null | Key | Default           | Extra |
+------------------+-------------+------+-----+-------------------+-------+
| number           | int(5)      | NO   | PRI | NULL              |       |
| jp_name          | varchar(10) | NO   |     | NULL              |       |
| en_name          | varchar(10) | YES  |     | NULL              |       |
| ge_name          | varchar(10) | YES  |     | NULL              |       |
| fr_name          | varchar(10) | YES  |     | NULL              |       |
| kr_name          | varchar(10) | YES  |     | NULL              |       |
| created_datetime | datetime    | NO   |     | CURRENT_TIMESTAMP |       |
| updated_datetime | datetime    | NO   |     | CURRENT_TIMESTAMP |       |
+------------------+-------------+------+-----+-------------------+-------+
8 rows in set (0.02 sec)

データを格納するEntityクラスを実装

上記ののテーブル構造に合わせた、Entity(PkmnBaseEntity.java)クラスを実装します。Fieldごとの変数を用意し、それぞれのセッター/ゲッターを作成します。

なお、@Entityや@Tableなどのアノテーションを付与すると、ちょいちょい警告が出ますが、その際は適切なimport(NetBeansが推薦してくれます)を追加していく必要があります。

PkmnBaseEntity.java

@Entity
@Table(name="PKMN_BASE")
public class PkmnBaseEntity implements Serializable {

    @Id
    private Integer number;

    private String jp_name;

(中略)

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public String getJp_name() {
        return jp_name;
    }

    public void setJp_name(String jp_name) {
        this.jp_name = jp_name;
    }
(以下略)

クライアントからのリクエストを受けるAPIクラスを実装

今回は、標準的なメソッドであるGETを使って、すべてのデータを取得するgetAllと、図鑑番号を指定して一体のみのデータを取得するgetを実装します。

PkmnBaseApi.java

値はJSON形式で返すので、returnはString型ですが、JSON.encode()としています。また、getメソッドにはnumberのパラメータが必要なので、QueryParamで渡します。

@Path("/pkmn")
public class PkmnBaseApi {

    @EJB
    private PkmnBaseLogic pkmnBaseLogic;

    @GET
    @Path("get")
    public String get(@QueryParam("number") Integer number) {
        PkmnBaseEntity pke = pkmnBaseLogic.get(number);
        return JSON.encode(pke);
    }

    @GET
    @Path("getAll")
    public String getAll() {
        List<PkmnBaseEntity> pkeList = pkmnBaseLogic.getAll();
        return JSON.encode(pkeList);
    }
}

ちなみに、各メソッド内で、PkmnBaseLogicクラスを使っているので、それを次に実装します。引数のデータ型や個数を間違えないよう注意。(間違ってたらNetBeansが指摘してくれるけど)

APIからの呼び出しで、実質的な処理を行うLogicクラスを実装

PkmnBaseLogic.java

APIからgetを呼ばれるか、getAllを呼ばれるかで挙動が異なります。

@Stateless
public class PkmnBaseLogic {

    @EJB
    private PkmnBaseDao pkmnBaseDao;

    public PkmnBaseEntity get(Integer number){
        return pkmnBaseDao.find(number);
    }

    public List<PkmnBaseEntity> getAll(){
        return pkmnBaseDao.getAll();
    }
}

いずれのメソッドもPkmnBaseDaoクラスを使っているので次はそれを実装します。

Logicからの呼び出しで、DBとのやり取りを行うDAOクラスを実装

PkmnBaseDao.java

entityManagerというものを使って、データベースへの検索を行います。

@Stateless
public class PkmnBaseDao {

    @PersistenceContext
    private EntityManager entityManager;

    //number指定検索
    public PkmnBaseEntity find(Integer number){
        return entityManager.find(PkmnBaseEntity.class, number);
    }

    //全てのデータを取得
    public List<PkmnBaseEntity> getAll(){
        CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
        cq.select(cq.from(PkmnBaseEntity.class));
        return entityManager.createQuery(cq).getResultList();
    }
}

データベースへの接続やクエリの発行についてはEntityManagerが請け負っている、という認識ですが、接続設定については人間の手で入れなければなりません。

それに関しては次回のDB設定・接続編で扱いたいと思います。

“DB設定編”へ続く

バックナンバー

“NetBeansとJavaEEで、ポケモンの日英仏独韓の名前を返すRESTなAPIを開発してみた - 準備編 -”