著作一覧 |
JAX-RSを実戦(ちょっと違うかも)投入したのだが、実に気に食わない点がある。
WEB-INF/libの下にばかみたくたくさんjarを入れざるを得ない点だ。少なくともRESTEASYのディストリビューションのlibをそのままコピーすると10MBを超える。おれは、未だにFD換算するくせが抜けないから、なんとFD8枚分で、Windows3.1並だぐへーとなってしまう。
では、利用しないjarは削除するかと思ってもどれがどうからんでいるのか、さっぱりわからない(全部展開してjavapで調べるとかする気はまったく起きないし)。
このjarの山が実に気持ちが悪い。で、ついmvnで自力構築しようとすると、えんえんとダウンロードが始まって、しかもクールではないURLのやつがあって404になってリトライしてみたりするし、最低だ。
配備先がインターネットにつながっているとか、USBメモリ(CD-ROMでも良いけど)でソフトウェアを配布できるとか、セキュリティ意識が低かった20世紀ならともかく、今の世の中、まっとうなエンタープライズサーバーでそんなことができるわけがない。
で、それは良いとして、困ったところがあって、以下のように解決したが、もっときれいな方法があれば知りたいところ。
やりたいことは、常にJSONで返すことだ。たとえば
@Path("/foobar") public class FooBarService { public static class FooBarData { } @GET @Path("item/{id}") @Produces("application/json") public FooBarData item(String id) { FooBarData data = new FooBarData(); ... return data; } }
みたいなやつ。
で、問題は、ここで、FooBarServiceには、既にWCF REST実装があって、
[DataContract] public class FooBar { [DataMember] public string Name { get; set; } [DataMember] public bool Brave { get; set; } }
がJSONとしてクライアントへ届けられているということだ。
すると、
@XmlRootElement(name = "FooBarData") public static class FooBarData { String name; Boolean brave; @XmlElement public String getName() { return name; } @XmlElement public Boolean isBrave() { return brave; } }
とは書けない。上のように書くと、
{ "name": "...", "brave": true }
みたいに、小文字プロパティ名になってしまうからだ。
JavaBean規格としては良いけれど、あいにく.NET方式プロパティ規約だから、これではだめだ。
そこで、XmlElementアノテーションのname属性の存在を知り、以下のように書く。
@XmlRootElement(name = "FooBarData") public static class FooBarData { String name; Boolean brave; @XmlElement(name = "Name") public String getName() { return name; } @XmlElement(name = "Brave") public Boolean isBrave() { return brave; } }
うまくいきそうだが、変化しない。Jettisonのバグ? 考慮不足? とか思うが、へたにバージョンを変えるとJAXBと整合性が取れなくなるのではないか、RESTEasyと整合性が取れなくなるのではないか、では最新のRESTEasyにしてみようか、おっと、こいつはJava6用でビルドしてあるが、あいにく実行環境はJava5なのだ。ではソースからビルドだ。そうかpom.xmlだったなぁ、3時間かけていろいろダウンロードが始まって、おっと、RESTEasyはJDK5コンパチかも知れないけど、依存しているやつがpom.xmlに1.6とターゲットを明記していやがる、これを1.5と直す勇気はおれにはないなぁ、しょうがないあきらめた。
と、ここでも、jarがばかすか入っていることがまったく悪い方向にしか働いていない。DRYはすばらしいし、車輪の再発明はくだらないかも知れないが、もう少し自分のところで開発して依存するjarを減らせよ、と不快になる(少なくともJDK5コンパチじゃないのには依存するなよというか)。
で、少し考えて、フィールド名はBean規約もへったくれもなくそのままプロパティ名となることに気付く。
@XmlRootElement(name = "FooBarData") public static class FooBarData { @XmlElement public String Name; @XmlElement public Boolean Brave; }
できたうえに、C#並にコードもコンパクトになった。ばっちりだ。
が、C#バージョンではメソッドだが、こっちは生フィールド(しかもpublic)なわけだ。(コンストラクタインジェクション+finalという方法は知っているが、世の中はそんなに固定的では無い)
しょせん値オブジェクト(しかもデータ転送専用)だから、むき出し生フィールドでいいじゃんと心を落ち着かせようとしても、やはり気分的にはいやなものだ(フックできるポイントが減るのはどうにも落ち着かない貧乏性なのだ)。
でも、まあ、こんな感じでルーズな結合ができるのは良いことではある。
というわけで、やはりJAX-RSも良いものだ。
JavaによるRESTfulシステム構築(Bill Burke)ジェズイットを見習え |