Skip to content

Instantly share code, notes, and snippets.

@deepakshrma
Last active June 19, 2022 16:38
Show Gist options
  • Save deepakshrma/b7ef7d9a9ccf94ff6150bd1ddd9cdd8b to your computer and use it in GitHub Desktop.
Save deepakshrma/b7ef7d9a9ccf94ff6150bd1ddd9cdd8b to your computer and use it in GitHub Desktop.
Working with XML Serialization and Response in Java and Kotlin
# Working with XML Serialization and Response in Java and Kotlin
## PreRequisite
- Java 17+
- [Optional] Kotlin 1.6+, Few examples will be in Kotlin
- [Optional] IntelliJ CE, You can use your preferred IDE
## Blogs Post
[Deepak Vishwakarma's Medium](https://medium.com/@deepak-v)
// imports
@SpringBootApplication
@RestController
public class XmlDemoApplication {
public static void main(String args[]) {
SpringApplication.run(XmlDemoApplication.class, args);
}
@RequestMapping(
value = "/xml",
method = RequestMethod.GET,
produces = {"application/xml"}
)
public String xml(
@RequestParam(value = "name", defaultValue = "John Doe")
String name
) {
return String.format("<name>%s</name>", name);
}
}
// Imports
@SpringBootApplication
@RestController
public class XmlDemoApplication {
public static void main(String args[]) {
SpringApplication.run(XmlDemoApplication.class, args);
}
@RequestMapping(value = "/xml", method = RequestMethod.POST, produces = {"application/xml"})
public String xml(@RequestBody() Person person) {
return """
<?xml version="1.0" encoding="UTF-8" ?>
<Person>
<age>%s</age>
<name>%s</name>
<company>%s</company>
<email>%s</email>
<address>
<street>%s</street>
<city>%s</city>
<state>%s</state>
<zip>%s</zip>
</address>
</Person>
""".formatted(
person.age, person.name, person.company, person.email,
person.address.street, person.address.city,
person.address.state, person.address.zip
);
}
}
class Person {
public int age;
public String name;
public String company;
public String email;
public Address address;
}
class Address {
public String street;
public String city;
public String state;
public int zip;
}
// XmlDemoApplication.java
@SpringBootApplication
@RestController
public class XmlDemoApplication {
static Mustache mustache = new DefaultMustacheFactory().compile("person-response.mustache");
@RequestMapping(
value = "/template",
method = RequestMethod.POST,
produces = {"application/xml"}
)
public String template(@RequestBody() Person person) throws IOException {
StringWriter writer = new StringWriter();
mustache.execute(writer, person).flush();
return writer.toString();
}
}
@SpringBootApplication
@RestController
public class XmlDemoApplication {
@RequestMapping(
value = "/serialize",
method = RequestMethod.POST,
produces = {"application/xml"}
)
public Person serialize(@RequestBody() Person person) throws IOException {
person.name = "[Updated] %s".formatted(person.name);
return person;
}
}
@JacksonXmlRootElement
@JsonRootName("person")
class Person {
public int age;
public String name;
public String company;
public String email;
public Address address;
}
@SpringBootApplication
@RestController
@RequestMapping(path = ["/kt/"])
class XmlDemoKt {
@RequestMapping(value = ["/xml"], method = [RequestMethod.GET], produces = ["application/xml"])
fun xml(
@RequestParam(value = "name", defaultValue = "John Doe") name: String?
) = String.format("<name>%s</name>", name)
}
fun main(args: Array<String>) {
runApplication<XmlDemoKt>(*args)
}
@SpringBootApplication
@RestController
@RequestMapping(path = ["/kt/"])
class XmlDemoKt {
@RequestMapping(value = ["/xml"], method = [RequestMethod.POST], produces = ["application/xml"])
fun xml(
@RequestBody p: PersonKt
): String {
return """
<?xml version="1.0" encoding="UTF-8" ?>
<Person>
<age>${p.age}</age>
<name>${p.name}</name>
<company>${p.company}</company>
<email>${p.email}</email>
<address>
<street>${p.address.street}</street>
<city>${p.address.city}</city>
<state>${p.address.state}</state>
<zip>${p.address.zip}</zip>
</address>
</Person>
""".trimIndent()
}
}
fun main(args: Array<String>) {
runApplication<XmlDemoKt>(*args)
}
data class PersonKt(
val age: Long,
val name: String,
val company: String,
val email: String,
val address: AddressKt
)
data class AddressKt(
val street: String,
val city: String,
val state: String,
val zip: Long
)
// XmlDemoKt.kt
@SpringBootApplication
@RestController
@RequestMapping(path = ["/kt/"])
class XmlDemoKt {
@RequestMapping(
value = ["/template"],
method = [RequestMethod.POST],
produces = ["application/xml"]
)
fun template(@RequestBody p: PersonKt): String {
val writer = StringWriter()
mustache.execute(writer, p).flush()
return writer.toString()
}
companion object {
val mustache = DefaultMustacheFactory()
.compile("person-response.mustache")
}
}
@SpringBootApplication
@RestController
@RequestMapping(path = ["/kt/"])
class XmlDemoKt {
@Bean
@Primary
fun objectMapper() = ObjectMapper() .registerModule(kotlinModule())
@RequestMapping(
value = ["/serialize"],
method = [RequestMethod.POST],
produces = ["application/xml"]
)
fun serialize(@RequestBody p: PersonKt): PersonKt {
return p.copy(name = "[Updated] ${p.name}")
}
}
@JacksonXmlRootElement
@JsonRootName("person")
data class PersonKt(
val age: Long,
val name: String,
val company: String,
val email: String,
val address: AddressKt
)
<?xml version="1.0" encoding="UTF-8" ?>
<Person>
<age>{{age}}</age>
<name>{{name}}</name>
<company>{{company}}</company>
<email>{{email}}</email>
<address>
<street>{{address.street}}</street>
<city>{{address.city}}</city>
<state>{{address.state}}</state>
<zip>{{address.zip}}</zip>
</address>
</Person>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>dev.dechipher.xml</groupId>
<artifactId>xml-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>xml-demo</name>
<description>Demo app for xml writing in Kotlin and Java</description>
<properties>
<java.version>17</java.version>
<kotlin.version>1.6.21</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.4</version>
</dependency>
<dependency>
<groupId>dev.dechipher.xml</groupId>
<artifactId>xml-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
package dev.dechipher.xml.xmldemo;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.StringWriter;
// Imports
@SpringBootApplication
@RestController
public class XmlDemoApplication {
static Mustache mustache = new DefaultMustacheFactory().compile("person-response.mustache");
public static void main(String args[]) {
SpringApplication.run(XmlDemoApplication.class, args);
}
@RequestMapping(
value = "/serialize",
method = RequestMethod.POST,
produces = {"application/xml"}
)
public Person serialize(@RequestBody() Person person) throws IOException {
person.name = "[Updated] %s".formatted(person.name);
return person;
}
@RequestMapping(
value = "/template",
method = RequestMethod.POST,
produces = {"application/xml"}
)
public String template(@RequestBody() Person person) throws IOException {
StringWriter writer = new StringWriter();
mustache.execute(writer, person).flush();
return writer.toString();
}
@RequestMapping(value = "/xml", method = RequestMethod.POST, produces = {"application/xml"})
public String xml(@RequestBody() Person person) {
return """
<?xml version="1.0" encoding="UTF-8" ?>
<Person>
<age>%s</age>
<name>%s</name>
<company>%s</company>
<email>%s</email>
<address>
<street>%s</street>
<city>%s</city>
<state>%s</state>
<zip>%s</zip>
</address>
</Person>
""".formatted(
person.age, person.name, person.company, person.email,
person.address.street, person.address.city,
person.address.state, person.address.zip
);
}
}
@JacksonXmlRootElement
@JsonRootName("person")
class Person {
public int age;
public String name;
public String company;
public String email;
public Address address;
}
class Address {
public String street;
public String city;
public String state;
public int zip;
}
package dev.dechipher.xml.xmldemo
import com.fasterxml.jackson.annotation.JsonRootName
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement
import com.fasterxml.jackson.module.kotlin.kotlinModule
import com.github.mustachejava.DefaultMustacheFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController
import java.io.StringWriter
@SpringBootApplication
@RestController
@RequestMapping(path = ["/kt/"])
class XmlDemoKt {
companion object {
val mustache = DefaultMustacheFactory()
.compile("person-response.mustache")
}
@Bean
@Primary
fun objectMapper() = ObjectMapper().registerModule(kotlinModule())
@RequestMapping(
value = ["/serialize"],
method = [RequestMethod.POST],
produces = ["application/xml"]
)
fun serialize(@RequestBody p: PersonKt): PersonKt {
return p.copy(name = "[Updated] ${p.name}")
}
@RequestMapping(
value = ["/template"],
method = [RequestMethod.POST],
produces = ["application/xml"]
)
fun template(@RequestBody p: PersonKt): String {
val writer = StringWriter()
mustache.execute(writer, p).flush()
return writer.toString()
}
@RequestMapping(value = ["/xml"], method = [RequestMethod.POST], produces = ["application/xml"])
fun xml(
@RequestBody p: PersonKt
): String {
return """
<?xml version="1.0" encoding="UTF-8" ?>
<Person>
<age>${p.age}</age>
<name>${p.name}</name>
<company>${p.company}</company>
<email>${p.email}</email>
<address>
<street>${p.address.street}</street>
<city>${p.address.city}</city>
<state>${p.address.state}</state>
<zip>${p.address.zip}</zip>
</address>
</Person>
""".trimIndent()
}
}
fun main(args: Array<String>) {
runApplication<XmlDemoKt>(*args)
}
@JacksonXmlRootElement
@JsonRootName("person")
data class PersonKt(
val age: Long,
val name: String,
val company: String,
val email: String,
val address: AddressKt
)
data class AddressKt(
val street: String,
val city: String,
val state: String,
val zip: Long
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment