The following example shows how to use one of the built-in converters (Map to an Object) or create your own.
class MyConfigurationProperties {
public static final String PREFIX = "myapp"
protected LocalDate updatedAt
LocalDate getUpdatedAt() {
return this.updatedAt
}
}
@ConfigurationProperties(MyConfigurationProperties.PREFIX)
class MyConfigurationProperties {
var updatedAt: LocalDate? = null
protected set
companion object {
const val PREFIX = "myapp"
}
}
The type MyConfigurationProperties
features a property called updatedAt
which is of type .
@AutoCleanup
@Shared
ApplicationContext ctx = ApplicationContext.run(
"myapp.updatedAt": [day: 28, month: 10, year: 1982] (1)
)
lateinit var ctx: ApplicationContext
@BeforeEach
fun setup() {
ctx = ApplicationContext.run(
mapOf(
"myapp.updatedAt" to mapOf( (1)
"day" to 28,
"year" to 1982
)
)
}
@AfterEach
fun teardown() {
ctx?.close()
}
This won’t work by default, since there is no built in conversion from Map
to LocalDate
. To resolve this you can define a custom TypeConverter:
import io.micronaut.core.convert.ConversionContext
import io.micronaut.core.convert.ConversionService
import io.micronaut.core.convert.TypeConverter
import javax.inject.Singleton
import java.time.DateTimeException
import java.time.LocalDate
@Singleton
class MapToLocalDateConverter implements TypeConverter<Map, LocalDate> { (1)
@Override
Optional<LocalDate> convert(Map propertyMap, Class<LocalDate> targetType, ConversionContext context) {
Optional<Integer> day = ConversionService.SHARED.convert(propertyMap.get("day"), Integer.class)
Optional<Integer> month = ConversionService.SHARED.convert(propertyMap.get("month"), Integer.class)
Optional<Integer> year = ConversionService.SHARED.convert(propertyMap.get("year"), Integer.class)
if (day.isPresent() && month.isPresent() && year.isPresent()) {
try {
return Optional.of(LocalDate.of(year.get(), month.get(), day.get())) (2)
} catch (DateTimeException e) {
context.reject(propertyMap, e) (3)
return Optional.empty()
}
return Optional.empty()
}
}
import io.micronaut.core.convert.ConversionContext
import io.micronaut.core.convert.ConversionService
import io.micronaut.core.convert.TypeConverter
import javax.inject.Singleton
import java.time.DateTimeException
import java.time.LocalDate
import java.util.Optional
@Singleton
class MapToLocalDateConverter : TypeConverter<Map<*, *>, LocalDate> { (1)
override fun convert(propertyMap: Map<*, *>, targetType: Class<LocalDate>, context: ConversionContext): Optional<LocalDate> {
val day = ConversionService.SHARED.convert(propertyMap["day"], Int::class.java)
val month = ConversionService.SHARED.convert(propertyMap["month"], Int::class.java)
val year = ConversionService.SHARED.convert(propertyMap["year"], Int::class.java)
if (day.isPresent && month.isPresent && year.isPresent) {
try {
return Optional.of(LocalDate.of(year.get(), month.get(), day.get())) (2)
} catch (e: DateTimeException) {
context.reject(propertyMap, e) (3)
return Optional.empty()
}
}
return Optional.empty()
}
1 | The class implements which takes two generic arguments. The type you are converting from and the type you are converting to |
2 | The implementation delegate to the default shared conversion service to convert the parts of the map that make the day, month and year into a LocalDate |
3 | If an exception occurs you can call reject(..) which propagates additional information to the container if something goes wrong during binding |