Spring BootでRESTやってて、XMLでdataを返したいと。 Java: Spring Boot で REST なアプリを作ってみるを見てみて、 @XmlRootElement
を付ければいい? ついでにtag名がclass名と違うので、 @XmlRootElement(name="annotation")
としました。
あと、Lombokを使ったせいなのか、 各fieldに@XmlElement
を付けないと、出て来ませんでした。 そういうもの?!
Spring BootでRESTやってて、XMLでdataを返したいと。 Java: Spring Boot で REST なアプリを作ってみるを見てみて、 @XmlRootElement
を付ければいい? ついでにtag名がclass名と違うので、 @XmlRootElement(name="annotation")
としました。
あと、Lombokを使ったせいなのか、 各fieldに@XmlElement
を付けないと、出て来ませんでした。 そういうもの?!
Spring Boot applicationで単一xml fileを返すREST作ってあって、 そこではxmlと同じ構造のJava bean作って返すだけで、 marshalingについてはframework側がよしなにやってくれました。 client側がHTTP Request HeaderにAccept: application/xml
とすれば。 そうでないとjsonになります。まぁそれはそれでいいんです。いいと思いました。
その後、複数xmlをまとめてZIPにして返すRESTを求められました。 そうすると、自分でXMLにmarshalingしなければなりません。 と、Gson? でもbuild.gradle
見ると折角jackson読み込んでいるようなので、 jacksonでmarshalしました。new ObjectMapper()
して、 mapper.write(ZipOutputStream)
みたいなことすると、 一回(=one file)書いただけでstreamを勝手に? closeするようなので、 一旦String
にしてからzos.write()
しました。 また、build.gradle
にcompile "...jackson-dataformat-xml"
も必要でした。
しかしそうすると、今度はXMLを返すRESTの方で、 返されるXMLの形が微妙に違っていました。具体的には、
@XmlRootElement(name=...)
で指定した名前が効かないList
要素がnestされる (<object></object><object></object>...
だったのが <object><object></object><object></object>...</object>
に)@XmlRootElement
はJAXBのannotation (javax.xml.bind.annotation.XmlRootElement
)で、 これが効かないというのだからJAXBが効いてないのだろうと思い、 そういえばbuild.gradle
にjackson-dataformat-xml
って書いたな、 というのを思い出し、 ZIP中でのXMLのmarshallingをJAXBのものでやるようにして build.gradle
からjackson-dataformat-xml
を追い出したら、 元に戻りました。
JAXBでのmarshalling、ちょこっと面倒ですが、 context = JAXBContext.newInstance(Bean.class)
して marshaller = context.createMarshaller()
作って、 marshaller.marshal(bean, zipOutputStream)
すればいいんですね。