u-ryo's blog

various information for coding...

Category: Jaxb

XML Marshaling in Spring Boot

| Comments

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.gradlecompile "...jackson-dataformat-xml"も必要でした。

しかしそうすると、今度はXMLを返すRESTの方で、 返されるXMLの形が微妙に違っていました。具体的には、

  1. @XmlRootElement(name=...)で指定した名前が効かない
  2. XML Object中でList要素がnestされる (<object></object><object></object>...だったのが <object><object></object><object></object>...</object>に)

@XmlRootElementはJAXBのannotation (javax.xml.bind.annotation.XmlRootElement)で、 これが効かないというのだからJAXBが効いてないのだろうと思い、 そういえばbuild.gradlejackson-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)すればいいんですね。