前回の続き。コードは手動ですべて書いたが、現在のメジャーバージョンである6.1(開発中の6.5ではない!)ですでに、データベースからエンティティクラスを全自動で生成、そのエンティティクラスからJAX-RSでCRUD(GET,POST,PUT,DELETE)もすべて生成される。
Web上などで公開されたアプリケーションではさすがにこのまま使うわけにはいかないが、クライアントサーバーから手軽に3層式のアプリケーションに変更する機会のいいチャンスかな。
JAXBのコードは前回のコードと同様に一覧を持ったBeansと単体のEntityをラップしたBeansが生成される。あの書き方でよかったみたい。
さらにJPAの管理するコードも自動的に作成されていた。JPAを知らない人でもすぐに試せるのはいい。コードを見るとスレッドローカルでEntityManagerをちゃんと処理するようになっていたので実運用でも問題はないと思う。
ただ単体のリソースのコードに書かれた「updateEntity」のコードだけがちょっと気になってる。OneToMany側からコレクションのremoveするだけでManyToOne側のエンティティは消えたっけ?「cascade=CascadeType.ALL」とかいれとけば大丈夫なのかな?
というか、RESTみたいな場合カスケードでどうするか、フェッチタイプをどうするか、トランザクションをどうするかなど疑問な箇所が多い。みんなはどうしてるんだろ。
DBの構造がURLに現れても便利なことはないよね。データの取得だけならともかく。
あと気がついたのは
@ProduceMime({"application/xml", "application/json"})
というところ。こうしておけば2つ選択して取得することが出来るようだ。
HTTPヘッダの「Accept」をいれてテストしてみる。
package jaxrs; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MimeTest { private static void print(String path , String accept) throws Exception{ URL url = new URL("http://localhost:8080/WebApplication5/"+path); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); if(accept.isEmpty() == false){ con.setRequestProperty("Accept", accept); } con.connect(); InputStreamReader ir = new InputStreamReader(con.getInputStream() , "UTF-8"); BufferedReader br = new BufferedReader(ir); String line = ""; while((line = br.readLine()) != null){ System.out.println(line); } br.close(); System.out.println(); } public static void main(String[] args) throws Exception{ String json = "application/json"; String xml = "application/xml"; String blank = ""; { String path = "resources/customers"; print(path , json); print(path , xml); print(path , blank); } { String path = "resources/customers/shin"; print(path , json); print(path , xml); print(path , blank); } } }
実行結果
{ "得意先名一覧":{"一覧":["shin","shinsan","しんさん"]} } <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <得意先名一覧> <一覧>shin</一覧><一覧>shinsan</一覧><一覧>しんさん</一覧> </得意先名一覧> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <得意先名一覧> <一覧>shin</一覧><一覧>shinsan</一覧><一覧>しんさん</一覧> </得意先名一覧> { "得意先":{"名前":"shin", "住所":"shinの住所"} } <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <得意先> <名前>shin</名前><住所>shinの住所</住所> </得意先> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <得意先> <名前>shin</名前><住所>shinの住所</住所> </得意先>
デフォルトはProduceMimeの最初に書いたほうになる模様。未対応のAcceptを入れた場合例外がかえる。あくまでも例外はクライアントのみでサーバーに例外が現れるわけではない。サーバーのコードは不正なURL等を意識する必要はないということ。