Jの衝動書き日記

さらりーまんSEの日記でございます。

standaloneを出したくないゾ

お仕事で、RestEasyを使う機会があったのだが、調査した時のメモを書いておく。
RestEasyで、XML形式の応答結果を返すのは簡単だ。
応答結果形式にマッピングしたオブジェクトを作成し、アノテーションをつけ、それをメソッドの返り値にすればJAXBでオブジェクトはXMLに変換される。
ただ、その変換されるXMLの内容でちょっと困ったことが起きた。
<?xml version="1.0" encoding="UTF-8"  standalone="yes"?>となり、standaloneと余計なものが入ってしまうのである。
これを消せないか、あれこれ調査した結果を書いておく。ちなみにバージョンは、1.2.1.GAであるので(Spring2.5.xに対応しているのがこれだった)、ひょっとしたら最新のバージョンではもっと簡単にいけるのかもしれない。

結論

RestEasyでは消せない。自前でオブジェクト→XMLへ変換する必要がある。RestEasyであれこれ設定して何とかするのはどうやら無理っぽい。

 

例えば、以下のような場合。

@GET
@Path(restserv)
@Produces("application/xml")
public Info restservice(@PathParam("user")int userId) ;


InfoがXMLマッピングしたオブジェクトだ。この場合、返却のContext-typeがapplication/xmlとなるので、RestEasy上でInfoをXMLへと変換し、それを返す。
これを行っているのはRestEasyのクラスだが、これを外部から制御する手段がないのだ。


なので、返り値をInfo→Stringへと変え、restservice内でInfoをXMLに変換する必要がある。
で、そのやり方は以下(例外処理は省略)。

 JAXBContext jc = JAXBContext.newInstance(Info.class);

 Marshaller marshaller = jc.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_ENCODING, "1.0");

 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
 XMLStreamWriter  xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(baos, "UTF-8");
 xmlStreamWriter.writeStartDocument(XML_ENCODING, "1.0");
 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

 /* オブジェクト→XMLの変換*/
 marshaller.marshal(info, xmlStreamWriter);
 xmlStreamWriter.writeEndDocument();
 return new String(baos.toByteArray());

 WriterにXMLStreamWriterを使えば、standloneは出てこない。
application/xmlの場合に、マッピングを行うクラスをRestEasyのものから、自前のものへ切り替えることができるのであれば、メソッドの返り値をStringに変える必要はないのだが、試してないので不明。