#java #spring #spring-boot #avro
#java #spring #spring-boot #avro
Вопрос:
У нас есть следующий простой веб-сервер:
package spring;
import avro.BatteryEvent;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Date;
@RestController
public class EnergyResourcesController {
private final Date date = new Date();
@PostMapping("/event/{uuid}")
BatteryEvent postBatteryEvent(
@PathVariable("uuid") String uuid,
@RequestBody BatteryEvent batteryEvent) throws IOException {
batteryEvent.setTime(date.getTime());
return batteryEvent;
}
}
Он использует a BatteryEvent
, который является сгенерированным Avro классом, который построен на основе следующей схемы Avro:
{
"namespace": "avro",
"type": "record",
"name": "BatteryEvent",
"fields": [
{
"name": "charging_source",
"type": [
"string",
"null"
]
},
{
"name": "processor4_temp",
"type": [
"int",
"null"
]
},
{
"name": "device_id",
"type": [
"string",
"null"
]
},
{
"name": "processor2_temp",
"type": [
"int",
"null"
]
},
{
"name": "processor1_temp",
"type": [
"int",
"null"
]
},
{
"name": "charging",
"type": [
"int",
"null"
]
},
{
"name": "current_capacity",
"type": [
"int",
"null"
]
},
{
"name": "inverter_state",
"type": [
"int",
"null"
]
},
{
"name": "moduleL_temp",
"type": [
"int",
"null"
]
},
{
"name": "moduleR_temp",
"type": [
"int",
"null"
]
},
{
"name": "processor3_temp",
"type": [
"int",
"null"
]
},
{
"name": "soC_regulator",
"type": [
"float",
"null"
]
},
{
"name": "time",
"type": [
"long",
"null"
],
"logicalType": "local-timestamp-millis"
}
]
}
Мы отправляем веб-серверу следующий JSON,
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085
}
Проблема BatteryEvent
в том, что мы получаем все null
значения, кроме charging
поля, например:
{"charging_source": null, "processor4_temp": null, "device_id": null, "processor2_temp": null, "processor1_temp": null, "charging": -261, "current_capacity": null, "inverter_state": null, "moduleL_temp": null, "moduleR_temp": null, "processor3_temp": null, "soC_regulator": null, "time": null}
Мой вопрос в том, почему это так? Все отправленные данные являются допустимыми JSON, и наш класс Avro также является допустимым. Наш сервер Spring Boot — это простой и корректный код, который был взят из собственной документации Spring Boot. Я хочу, чтобы данные, которые Spring Boot передает BatteryEvent
объекту, содержали значения из отправленного JSON события батареи.
Ответ №1:
Я не уверен, в чем основная причина вашей проблемы, но, похоже, есть некоторые проблемы с сериализацией / десериализацией JSON.
Когда я попытался воспроизвести вашу проблему, согласно вашей информации, я получал некоторое исключение, которое я разрешил, используя решение, упомянутое здесь здесь
После этого, когда я запускаю POST API, я получил ожидаемый результат со всеми заполненными значениями.
Вы можете проверить мой код здесь здесь
Не могли бы вы предоставить дополнительную информацию о своем коде, например, изменили ли вы процесс сериализации / десериализации по умолчанию? Это поможет получить больше представления о том, почему в вашем коде свойства устанавливаются как null
Ниже приведены запрос и ответ из моего примера
Запрос
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085
}
Ответ
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085,
"time": 1609404352570,
"moduleRTemp": 91,
"moduleLTemp": 199,
"inverterState": 1,
"soCRegulator": 26.598085,
"deviceId": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor1Temp": 60,
"currentCapacity": 10948,
"processor3Temp": 152,
"processor4Temp": 160,
"chargingSource": "utility",
"processor2Temp": 96
}
Комментарии:
1. Спасибо за вашу помощь! Когда мы переместили каталог сгенерированных источников Avro из
src/main/resources/avro
в${project.build.directory}/generated-sources
, мы смогли исправить проблемы с сериализацией / десериализацией. Мы бы не смогли этого сделать без вашегоpom
файла примера в созданном вами репозитории. Большое спасибо за вашу помощь!
Ответ №2:
Имя поля в entity должно совпадать с именем ключа в json
Комментарии:
1. Все имена полей в схеме Avro точно соответствуют именам ключей в полученном JSON.