#始めに
simpleなJAX-RSアプリケーションについて書いてみます
実装するアプリはDBから値を取得して、json形式でブラウザに返すものです
アプリケーションサーバとか用意するのが面倒くさいので、HTTPサーバはJDK付属のHTTPサーバを使っています
#前提
- JAX-RSに関連するjarがすべてクラスパスに通っていること
- OpenJPAに関するjarがすべてクラスパスに通っていること
- jacksonに関するjarがすべてクラスパスに通っていること
- jerseyのHTTPサーバに関するjarがすべてクラスパスに通っていること
#アプリ作成の手順
- Open-JPAのモジュールを作成する
- JAX-RSモジュールを作成する
- HTTPサーバのモジュールを作成する
- 実行結果
#1. Open-JPAのモジュールを作成する
まずは、教科書通り、OpenJPAのエンティティクラスを記述する
Area.java
package entiry;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
@Entity
@NamedQuery(
name="namedQuerrySample",
query="SELECT i FROM Area i where i.areaCode =:code"
)
public class Area {
/**エリアコード */
@Id
@Column(name="area_code",length=4)
private String areaCode;
/**エリア名 */
@Column(name="area_name")
private String areaName;
/**管理担当者 */
@Column(name="kanri_Tantou",length=4)
private String kanriTantou;
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public String getKanriTantou() {
return kanriTantou;
}
public void setKanriTantou(String kanriTantou) {
this.kanriTantou = kanriTantou;
}
}
次に、DBから値を取り出すロジックスラスを作成する
MyLogic.java
package logic.dbh29;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import entiry.Area;
public class MyLogic {
public List<Area> doAreaSelect(){
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("myUnitInPersistenceXML");
EntityManager em = factory.createEntityManager();
return em.createNamedQuery("namedQuerrySample", Area.class)
.setParameter("code", "1111")
.getResultList();
}
}
#2.JAX-RSモジュールを作成する
JAX-RSモジュールからDBにアクセスするモジュールを呼び出し、JSON形式でレスポンスを返すクラスを作成する。
なお、DBから取得した値はListで返ってくるため、JSON形式に変換する際はひと工夫必要になる
具体的には
- JSONに変換するオブジェクトの型を指定するため、writerWithTypeを使う
- writerWithTypeの引数にはTypeReference<T>のサブクラスのインスタンスを渡す必要がある
- TypeReference<T>のTにはList<List含まれるクラス名>を指定する
- writerWithTypeの戻り値からwriteValueAsStringを呼び出し、引数にJSONに変換したいListを指定する
今回の例ではDBから取得した値はListで返ってくるためwriterWithTypeの引数には
new TypeReference<List<Area>>() {}
を指定してあげればよい
SampleRooter.java
package rooter;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import entiry.Area;
import logic.dbh29.MyLogic;
@Path("sample")
public class SampleRooter extends BaseRooter {
@Path("Area")
@GET
@Produces(MediaType.APPLICATION_JSON)
public String doLogic (
@QueryParam("x") String ax,
@QueryParam("y") String ay
)throws Exception{
return new ObjectMapper()
.writerWithType(new TypeReference<List<Area>>() {})
.writeValueAsString(new MyLogic().doAreaSelect());
}
}
#3.HTTPサーバのモジュールを作成する
2.で作成したJAX-RSモジュールをResourceConfig指定して、mainクラスからHTTPサーバーを実行するだけです
URLExe.java
package main;
import java.net.URI;
import rooter.SampleRooter;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import com.sun.net.httpserver.HttpServer;
public class URLExe {
public static void main(String[] args) {
URI uri = URI.create("http://localhost:8081/");
ResourceConfig rc = new ResourceConfig();
rc.register(SampleRooter.class);
HttpServer httpServer = JdkHttpServerFactory.createHttpServer(uri, rc);
Runtime.getRuntime().addShutdownHook(new Thread(() -> httpServer.stop(0)));
System.out.println("HTTPサーバーが開始されました");
}
}