Spring с десериализацией Kotlin & Jackson: свойство lateinit <attribute>не было инициализировано - PullRequest
0 голосов
/ 25 октября 2018

Я должен признать, что я довольно новичок в Kotlin и полностью новичок в Spring, но это инструменты, которые я должен использовать, так что вот и я.

У меня есть пользовательский Jackson Deserializer, которому нужен экземпляр внешне настроенного (Spring Boot файла свойств) класса, чтобы выполнить свою работу, но, несмотря на мои попытки, я всегда получаю следующую ошибку:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is kotlin.UninitializedPropertyAccessException: lateinit property cordaRPC has not been initialized

Я действительно не знаю, как поступить из-за псевдоавтоматического Spring'а… Думаю, возможно, что инструментарий Джексона произойдет до настройки класса свойства, но я буду ждать вашей помощи.


Чтобы предоставить некоторый контекст, вот некоторые из прототипов работы:

Источник ошибки - cordaRPC в DumpDataDeserializer.kt.

Файл: CordaGateway.kt:

@Component
@ConfigurationProperties(prefix = "corda.rpc")
class CordaGateway(@Value("\${$CORDA_NODE_HOST_ADDRESS}") private val host: String,
                   @Value("\${$CORDA_NODE_RPC_PORT}") private val port: Int,
                   @Value("\${$CORDA_NODE_RPC_USERNAME}") private val username: String,
                   @Value("\${$CORDA_NODE_RPC_PASSWORD}") private val password: String)
    : AutoCloseable
{
    lateinit var rpcConnection: CordaRPCConnection
    lateinit var proxy: CordaRPCOps

    private val logger = LoggerFactory.getLogger(CordaGateway::class.java)

    @PostConstruct
    fun initialiseNodeRPCConnection() {
        val rpcAddress = NetworkHostAndPort(host, port)
        val rpcClient = CordaRPCClient(rpcAddress)
        val rpcConnection = rpcClient.start(username, password)
        proxy = rpcConnection.proxy
    }

    @PreDestroy
    override fun close() {
        rpcConnection.notifyServerAndClose()
    }
}

Файл: DumpData.kt:

// Untouchable external class
import net.corda.core.identity.Party

data class DumpData(val value: Int, val test: String, val user: Party)

Файл: DumpDataDeserializer.kt

class DumpDataDeserializer(vc: Class<*>? = null) : StdDeserializer<DumpData>(vc) {

    private val logger = LoggerFactory.getLogger(TestController::class.java)

    @Autowired
    private lateinit var cordaRPC: CordaGateway

    override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): DumpData {
        val node: JsonNode = jp.codec.readTree(jp)

        val value = node.get("value").intValue()
        val editedTest = node.get("test").textValue().plus(" edited!")
        val userName = node.get("user").textValue()

        val party = cordaRPC.proxy.wellKnownPartyFromX500Name(CordaX500Name.parse(userName))!!    

        return DumpData(value, editedTest, party)
    }
}

Файл: CustomJsonConfig.kt:

@Configuration
class CustomJsonConfig {
    @Bean
    fun prova(): Module {
        return SimpleModule().addDeserializer(DumpData::class.java, DumpDataDeserializer())
    }
}

ДесериалПриведение в действие выполняется следующим образом:

val data = objMapper.treeToValue(body.get("prova"), DumpData::class.java)

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...