Как динамически добавлять пары ключ-значение в объект Kotlin?

У меня есть Spring Boot REST api, который возвращает такой объект JSON:

{
  "id": "1"
  "timestamp": "2020-08-03T08:49:02.679+00:00"
  "message": "hello"
}

Это прямо получено из @Entity как это -

fun getMessage(id: Long) = messageRepository.findById(id)

Здесь Spring boot автоматически преобразует ответ в JSON. Однако я хочу добавить еще одну пару "ключ-значение" вgetMessage()функция. Подобно этому - Как я могу добавить пару ключ / значение к объекту JavaScript? но на Java/ Kotlin.

Как я могу это сделать?

2 ответа

Решение

Возможно, вы могли бы создать для этого другую модель и создать расширение для преобразования в новую модель.

data class Message(
    val id: Int,
    val timestamp: String, 
    val message: String   
)

data class MessageWithMoreInfo(
    val id: Int,
    val timestamp: String, 
    val message: String,
    val info: String   
)

fun Message.toMessageWithMoreInfo(val info: String) = MessageWithMoreInfo(
    id,
    timestamp,
    message,
    info
)

Вы не сможете воспроизвести способ вставки ключей и значений в объекты с помощью javascript, поскольку Java (и Kotlin) является языком со статической типизацией.

Преобразование Spring в Json не волшебство. Скорее всего, он сериализует вашу сущность с помощью Object Mapper (Jackson или Gson).

Теперь вы можете обойти это ограничение разными способами (одни лучше, чем другие), и ответ Лучано является одним из лучших.

Но, в зависимости от того, что вы вводите в свою сущность и от того, как определяется дизайн вашего проекта, вы можете сделать именно то, что делает javascript, используя Object Mapper, предоставляемый контекстом spring, и преобразовать вашу Entity в Map:

@Service
class AServiceImpl(
        private val repository: ARepository,
        // autowires the objectMapper
        private val objectMapper: ObjectMapper
) : AService {

    override fun getMessage(id: Long): Map<String, Any>{
        val entity = repository.findById(id)
        // here you have something more like a javascript Object 
        val map: MutableMap<String, Any> = objectMapper.convertValue(entity)
        // so you can add key/value pairs to it
        map["something"] = "some_value"
        // but you will need to change the method signature 
        return map
    }
}

Помните: прохождение карт довольно опасно, вы теряете многие преимущества Java/Kotlin:)

Другие вопросы по тегам