【问题标题】:Mapstruct kotlin and @Named annotationMapstruct kotlin 和 @Named 注解
【发布时间】:2020-09-01 02:04:37
【问题描述】:

我正在将一些宠物项目从 java 转换为 kotlin,但遇到了一些无法解决的问题。在 java 中,所有编译都很好,但是在转换为 Kotlin 之后就不需要......

...
import org.mapstruct.Mapper
import org.mapstruct.Mapping
import org.mapstruct.Named
...

@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
interface EffectMapper {

    @Mapping(source = "icon", target = "icon", qualifiedByName = ["convertIcon"])
    fun toDS(effectDTO: EffectDTO): EffectDS

    fun toDSarr(effectDTOArrayList: ArrayList<EffectDTO>): ArrayList<EffectDS>

    @Named("convertIcon")
    fun convertIcon(obj: String?): ByteArray? {
        return if (obj != null) {
            Base64.decode(obj, Base64.DEFAULT)
        } else {
            null
        }
    }

    companion object {
        val MAPPER = Mappers.getMapper(EffectMapper::class.java)
    }
}

Gradle 返回错误

 error: Can't generate mapping method from non-iterable type to iterable type.
    public abstract byte[] convertIcon(@org.jetbrains.annotations.Nullable()

Can't map property "java.lang.String icon" to "byte[] icon". Consider to declare/implement a mapping method: "byte[] map(java.lang.String value)".
    @org.mapstruct.Mapping(source = "icon", target = "icon", qualifiedByName = {"convertIcon"})

Can't map property "java.lang.String effect" to "one.codium.funart.DataStructure.effect.Effect effect". Consider to declare/implement a mapping method: "one.codium.funart.DataStructure.effect.Effect map(java.lang.String value)".
    public abstract one.codium.funart.DataStructure.EffectDS toDS(@org.jetbrains.annotations.NotNull()

终于这样搞定了

@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR, uses = [EffectMapperImpl::class])
interface EffectMapper {

    fun toDS(effectDTO: EffectDTO): EffectDS

    fun toDSarr(effectDTOArrayList: ArrayList<EffectDTO>): ArrayList<EffectDS>

    companion object {
        val MAPPER: EffectMapper = Mappers.getMapper(EffectMapper::class.java)
    }
}

object EffectMapperImpl {

    fun convertIcon(obj: String?): ByteArray? {
        return if (obj != null) {
            Base64.decode(obj, Base64.DEFAULT)
        } else {
            null
        }
    }

    fun toEffect(s: String): Effect {
        return Effect(s)
    }
}

谢谢@Filip

【问题讨论】:

    标签: android kotlin mapstruct


    【解决方案1】:

    我使用的是 Kotlin 1.3.71-release-431,它可以与 @JvamDefault 一起正常工作,因此您只需在 (java) 中将转换方法 (toEffect) 设为静态即可。

    Mapping(source = "sourceFiledName", target = "destinationFiledName", qualifiedByName = ["converterMethod"])
    interface EffectMapper {
      fun toDS(effectDTO: EffectDTO): EffectDS
      
      fun toDSarr(effectDTOArrayList: ArrayList<EffectDTO>): ArrayList<EffectDS>
      
      companion object {
         @JvmStatic
         @Named("converterMethod")
         fun toEffect(s: String): Effect {
            return Effect(s)
          }
      }
    }
    

    【讨论】:

      【解决方案2】:

      您看到的问题是由于convertIcon 方法未被识别为EffectMapper 接口中的默认方法。

      即使您使用@JvmDefault,由于KT-25960,它也不起作用。我建议您将convertIcon 方法提取到另一个类中的公共静态方法中,然后通过Mapper#uses 使用它

      【讨论】:

      • public 静态类应该是 Java 类,也可以是 Kotlin。请提供一点代码。
      猜你喜欢
      • 2022-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 2021-10-25
      • 2018-05-14
      相关资源
      最近更新 更多