Micronaut 自定義類型轉(zhuǎn)換器

2023-03-01 16:08 更新

Micronaut 包含一個(gè)可擴(kuò)展的類型轉(zhuǎn)換機(jī)制。要添加額外的類型轉(zhuǎn)換器,您需要注冊(cè) TypeConverter 類型的 bean。

以下示例顯示如何使用內(nèi)置轉(zhuǎn)換器之一(映射到對(duì)象)或創(chuàng)建您自己的轉(zhuǎn)換器。

考慮以下 ConfigurationProperties:

 Java Groovy  Kotlin 
@ConfigurationProperties(MyConfigurationProperties.PREFIX)
public class MyConfigurationProperties {

    public static final String PREFIX = "myapp";

    protected LocalDate updatedAt;

    public LocalDate getUpdatedAt() {
        return updatedAt;
    }
}
@ConfigurationProperties(MyConfigurationProperties.PREFIX)
class MyConfigurationProperties {

    public static final String PREFIX = "myapp"

    protected LocalDate updatedAt

    LocalDate getUpdatedAt() {
        updatedAt
    }
}
@ConfigurationProperties(MyConfigurationProperties.PREFIX)
class MyConfigurationProperties {

    var updatedAt: LocalDate? = null
        protected set

    companion object {
        const val PREFIX = "myapp"
    }
}

MyConfigurationProperties 類型有一個(gè)名為 updatedAt 的 LocalDate 類型的屬性。

要通過配置從地圖綁定此屬性:

 Java Groovy   Kotlin
private static ApplicationContext ctx;

@BeforeClass
public static void setupCtx() {
    ctx = ApplicationContext.run(
            new LinkedHashMap<String, Object>() {{
                put("myapp.updatedAt", // (1)
                        new LinkedHashMap<String, Integer>() {{
                            put("day", 28);
                            put("month", 10);
                            put("year", 1982);
                        }}
                );
            }}
    );
}

@AfterClass
public static void teardownCtx() {
    if(ctx != null) {
        ctx.stop();
    }
}
@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,
                "month" to 10,
                "year" to 1982
            )
        )
    )
}

@AfterEach
fun teardown() {
    ctx?.close()
}
  1. 請(qǐng)注意我們?nèi)绾卧谏厦娴?nbsp;MyConfigurationProperties 類中匹配 myapp 前綴和 updatedAt 屬性名稱

這在默認(rèn)情況下不起作用,因?yàn)闆]有從 Map 到 LocalDate 的內(nèi)置轉(zhuǎn)換。要解決此問題,請(qǐng)定義自定義 TypeConverter:

 Java Groovy  Kotlin 
import io.micronaut.core.convert.ConversionContext;
import io.micronaut.core.convert.ConversionService;
import io.micronaut.core.convert.TypeConverter;

import jakarta.inject.Singleton;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.util.Map;
import java.util.Optional;

@Singleton
public class MapToLocalDateConverter implements TypeConverter<Map, LocalDate> { // (1)
    @Override
    public 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 jakarta.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.day, Integer)
        Optional<Integer> month = ConversionService.SHARED.convert(propertyMap.month, Integer)
        Optional<Integer> year = ConversionService.SHARED.convert(propertyMap.year, Integer)
        if (day.present && month.present && year.present) {
            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 java.time.DateTimeException
import java.time.LocalDate
import java.util.Optional
import jakarta.inject.Singleton

@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. 該類實(shí)現(xiàn)了 TypeConverter,它有兩個(gè)通用參數(shù),一個(gè)是你要轉(zhuǎn)換的類型,一個(gè)是你要轉(zhuǎn)換成的類型

  2. 該實(shí)現(xiàn)委托默認(rèn)的共享轉(zhuǎn)換服務(wù)來轉(zhuǎn)換用于創(chuàng)建 LocalDate 的 Map 中的值

  3. 如果在綁定期間發(fā)生異常,則調(diào)用 reject(..) 將附加信息傳播到容器


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)