JAX-RS + Doma で 100% ハマルこと
Doma の Entity を JAX-RS で JSON/XML 化できないという話。
Doma が java.util.Date 使えないのも少しだけ不満なのですが、これは JAXB の問題ですね。
解決方法
Doma の制約は回避方法がないので、JAXB の XMLAdaptor を書いて解決します。
java.sql.Date 用
package adaptor; import javax.xml.bind.annotation.adapters.XmlAdapter; public class SqlDateAdaptor extends XmlAdapter<java.util.Date, java.sql.Date> { @Override public Date unmarshal(java.util.Date v) throws Exception { return new java.sql.Date(v.getTime()); } @Override public java.util.Date marshal(java.sql.Date v) throws Exception { return new java.util.Date(v.getTime()); } }
java.sql.Timestamp 用
package adaptor; import java.sql.Date; import java.sql.Timestamp; import javax.xml.bind.annotation.adapters.XmlAdapter; public class TimestampAdaptor extends XmlAdapter<java.util.Date, Timestamp> { @Override public Date marshal(Timestamp v) { return new Date(v.getTime()); } @Override public Timestamp unmarshal(java.util.Date v) throws Exception { return new Timestamp(v.getTime()); } }
これを全ての java.sql.Date フィールドに指定しても良いのだけれど、面倒なのでパッケージに指定します。
Doma の Entity を置いてあるパッケージに package-info.java を作成して以下のようにアノテーションを書きます。
package-info.java
@XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value = adaptor.SqlDateAdaptor.class, type = java.sql.Date.class), @XmlJavaTypeAdapter(value = adaptor.TimestampAdaptor.class, type = java.sql.Timestamp.class) }) package entity; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
さらっと書いてるけど、実際は3時間くらいハマッてました。