Spring (kotlin) контроллер получает ненулевые параметры класса данных как ноль - PullRequest
0 голосов
/ 06 ноября 2018

Я столкнулся с неожиданной ошибкой, с которой я не уверен, как справиться.

У меня есть такой класс данных:

data class Payload (
  @SerializedName("id")
  var id: String
  @SerializedName("type")
  var type: String,
  @SerializedName("data")
  var data: String
)

И простой Spring-контроллер, подобный этому:

@PostMapping("/some-endpoint")
fun dataHandler(@RequestBody payload: Payload): String{
    when (payload.type){
        "someType" -> {
            val result = try {
                gson.fromJson(payload.data, payloadData::class.java)
            } catch (e: Exception){
                throw BadDataException("Bad Data")
            }
            payloadProcessor.process(result, payload.id) // NPE here
        }
        "otherType" -> {
            doSomethingElseHere()
        }
    }
}

Когда выполнение достигает payloadProcessor.process, возникает исключение нулевого указателя, так как id является, по-видимому, нулевым. С другой стороны, объект создан, и два оставшихся значения кажутся правильно заполненными. Если я добавляю оператор if, проверяющий наличие нулевых значений, ide жалуется, что свойства полезной нагрузки никогда не бывают нулевыми, отмечая оператор if как избыточный, но на самом деле это не так. У меня сложилось впечатление, что нуль-безопасные свойства ... ну ... нуль-безопасные. По крайней мере, я ожидаю, что исключение нулевого указателя произойдет после того, как объект сконструирован.

Мой вопрос:

  • Как Spring может создать такой объект
  • Почему это не обнаружено при строительстве объекта
  • Каким был бы способ "Kotlin" справиться с этим, поскольку я не хотел бы проверять нулевые параметры в предположительно нулевом безопасном объекте.

1 Ответ

0 голосов
/ 06 ноября 2018

Проблема в Gson, а не в Spring. Gson разработан для использования с Java, в котором нет * различия между обнуляемыми и не обнуляемыми типами, поэтому Gson в любом случае с радостью присвоит нулевое значение.

К сожалению, здесь нет волшебного решения. Вы можете написать свой собственный TypeAdapter , который явно проверяет наличие нулевых значений перед созданием ваших классов данных, но если у вас много классов, это будет очень повторяющимся. В качестве альтернативы, вы можете создать свой собственный TypeAdapterFactory и использовать библиотеку отражений Kotlin, чтобы проверить, какие типы являются обнуляемыми, а какие нет, но это будет иметь различные последствия в отношении производительности и зависимостей.

* Есть аннотации обнуления (@Nonnull, @Nullable), но Гсон их не проверяет.

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