In the tutorial, Grokonez show you how to create Kotlin SpringBoot XML RestAPIs and PostgreSQL with Post/Get/Put/Delete requests using jaxb-api
& jackson-dataformat-xml
Contents
Technologies
– Kotlin SpringBoot
– PostgreSQL
– Postman Rest-Client
Practices
Project Structure ->
Create SpringBoot project
– We use SpringToolSuite to create a Kotlin SpringBoot project with below dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> |
– The jackson-dataformat-xml
adds Jackson XML serializer and deserializer.
Model
– We use @JacksonXmlRootElement
& @JacksonXmlProperty
to create Customer.kt
model:
@JacksonXmlProperty
is used to set an attribute of the element in the XML output.@JacksonXmlRootElement
is used to set the name for the XML output root element.
package com.grokonez.kotlin.restapi.model import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; @Entity @Table(name = "customers") @JacksonXmlRootElement(localName = "Customer") class Customer( @JacksonXmlProperty @Column(name = "firstname") var firstname: String = "", @JacksonXmlProperty @Column(name = "lastname") var lastname: String = "", @JacksonXmlProperty @Column(name = "age") var age: Int = -1, @Id @GeneratedValue(strategy = GenerationType.AUTO) @JacksonXmlProperty(isAttribute = true) var id: Long = -1 ){} |
– Create an Customers.kt
helper class:
package com.grokonez.kotlin.restapi.model import com.grokonez.kotlin.restapi.model.Customer import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; @JacksonXmlRootElement class Customers { @JacksonXmlProperty(localName = "Customers") @JacksonXmlElementWrapper(useWrapping = false) var customers = listOf<Customer>(); } |
-> We use @JacksonXmlProperty
& @JacksonXmlElementWrapper
annotations to set a list of Customer
to be elements of Customers
element in XML output.
JPA Repository
– Create JPA repository CustomerRepository.kt
->
package com.grokonez.kotlin.restapi.repository import com.grokonez.kotlin.restapi.model.Customer import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository interface CustomerRepository : JpaRepository<Customer, Long>{ } |
Controller RestAPIs
– We create 4 RestAPIs with Post/Get/Put/Delete XML request-mapping:
package com.grokonez.kotlin.restapi.controller import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.grokonez.kotlin.restapi.repository.CustomerRepository import com.grokonez.kotlin.restapi.model.Customer import com.grokonez.kotlin.restapi.model.Customers @RestController @RequestMapping("/api") class CustomerRestAPIs { @Autowired lateinit var customerRepository: CustomerRepository; @PostMapping("/customer", produces=arrayOf("application/xml")) fun postCustomer(@RequestBody customer: Customer): Customer { return customerRepository.save(customer); } @GetMapping("/customer", produces=arrayOf("application/xml")) fun getAllCustomers(): Customers { var _customers = Customers() _customers.customers = customerRepository.findAll() return _customers } @GetMapping("/customer/{id}", produces=arrayOf("application/xml")) fun getCustomerById(@PathVariable id: Long): Customer { var optCustomer = customerRepository.findById(id); if(optCustomer.isPresent()) { return optCustomer.get(); } throw RuntimeException("Not Found a customer with id = " + id); } @PutMapping("/customer/{id}", produces=arrayOf("application/xml")) fun putCustomer(@PathVariable id: Long, @Valid @RequestBody customerUpdated: Customer): Customer { val optCustomer = customerRepository.findById(id) if(optCustomer.isPresent()) { var _customer: Customer = optCustomer.get() _customer.firstname = customerUpdated.firstname _customer.lastname = customerUpdated.lastname _customer.age = customerUpdated.age return customerRepository.save(_customer); } throw RuntimeException("Customer not found with id = " + id) } @DeleteMapping("/customer/{id}") fun deleteCustomer(@PathVariable id: Long): String { var optCustomer = customerRepository.findById(id) if(optCustomer.isPresent()){ customerRepository.delete(optCustomer.get()); return "Delete Successfully!"; } throw RuntimeException("Customer not found with id = " + id) } } |
-> With MediaType.APPLICATION_XML_VALUE
, Spring uses a message converter to produces XML data.
Application configuration
– Open file application.properties
, add configuration:
spring.datasource.url=jdbc:postgresql://localhost/testdb spring.datasource.username=postgres spring.datasource.password=123 spring.jpa.generate-ddl=true |
Run & Check Results
– Run Kotlin SpringBoot application & start PostgreSQL database.
-> Make post requests:
-> Get customers:
-> Put a customer:
– Delete a customer: