Micronaut http 客户端无法识别字段
Micronaut http client doesn't recognise fields
我从休息服务处收到以下 json。
{
"AccessControlRecords": {
"OccasionRecords": [
{
"Type": "",
"BookingNr": "91376",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "",
"PartOfObjectName": "",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "17.08.2019",
"BookToDate": "23.05.2020",
"OccasionDate": "2020-01-04 09:00",
"OccasionToDate": "2020-01-04 10:00",
"FomKlo": "09:00",
"TomKlo": "10:00",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 0,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "Svømmeklubben Frem",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
},
{
"Type": "",
"BookingNr": "90443",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "",
"PartOfObjectName": "",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "02.11.2019",
"BookToDate": "28.03.2020",
"OccasionDate": "2020-01-04 14:00",
"OccasionToDate": "2020-01-04 16:30",
"FomKlo": "14:00",
"TomKlo": "16:30",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 1,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "Odense Roklub",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
},
{
"Type": "",
"BookingNr": "91916",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "DELA",
"PartOfObjectName": "Delt styrketræning (A)",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "24.08.2019",
"BookToDate": "20.06.2020",
"OccasionDate": "2020-01-04 10:00",
"OccasionToDate": "2020-01-04 14:00",
"FomKlo": "10:00",
"TomKlo": "14:00",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 0,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "* Odense Håndbold talentcenter",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
}
]
},
"ResultCode": 0,
"ResultText": null
}
我的数据class定义如下
data class Bookings(val AccessControlRecords: AccessControlRecords, val resultCode: Int, val resultText: String?)
data class AccessControlRecords(val OccasionRecords: List<OccasionRecords>)
data class OccasionRecords(val type: String?,
val BookingNr: String,
val bookingRow: String,
val FacilityID: String,
val ObjectID: String,
val PartOfObjectId: String,
val PartOfObjectName: String,
val FacilityName: String,
val ObjectName: String,
val BookFromDate: String,
val BookToDate: String,
val OccasionDate: String,
val OccasionToDate: String,
val FomKlo: String,
val TomKlo: String,
val TimeBefore: String,
val TimeAfter: String,
val Weekday: Int,
val BookStatus: String,
val KortReg: String,
val CustomerID: String,
val CustomerName: String,
val TypeOfBooking: String,
val CreatedBy: String,
val Cards: String,
val FunctionCode1: Int,
val FunctionCode2: Int,
val FunctionCode3: Int,
val FunctionCode4: String,
val Text1: String,
val Text2: String,
val Text3: String,
val Text4: String,
val EndUser: String,
val Activity: String)
我的配置class定义如下
class BookingConfiguration {
companion object {
const val URL = "https://something.dk"
const val PATH = "/kmd_webapi/api/Monitor/GetFilteredAccessControlRecords?dateTimeFrom=2020-01-04&dateTimeTo=2020-01-04&facility=OIHAL&facilityObject=STYRK&partObject=&authenticationCode=xxx&type=json"
}
}
实际客户端定义如下
@Client(BookingConfiguration.URL)
interface BookingsClient {
@Get(BookingConfiguration.PATH)
fun fetchBookings(dateTimeFrom: String, dateTimeTo: String, authenticationCode: String): Flowable<Bookings>
}
我遇到的异常如下
01:31:59.199 [pool-1-thread-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error decoding JSON stream for type [T]: Instantiation of [simple type, class dk.fitfit.OccasionRecords] value failed for JSON property BookingNr due to missing (therefore NULL) value for creator parameter BookingNr which is a non-nullable type
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: dk.fitfit.Bookings["AccessControlRecords"]->java.lang.Object[0]->dk.fitfit.OccasionRecords["BookingNr"])
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [T]: Instantiation of [simple type, class dk.fitfit.OccasionRecords] value failed for JSON property BookingNr due to missing (therefore NULL) value for creator parameter BookingNr which is a non-nullable type
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: dk.fitfit.Bookings["AccessControlRecords"]->java.lang.Object[0]->dk.fitfit.OccasionRecords["BookingNr"])
at io.micronaut.jackson.codec.JsonMediaTypeCodec.decode(JsonMediaTypeCodec.java:123)
at io.micronaut.http.client.DefaultHttpClient.lambda$null(DefaultHttpClient.java:905)
at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:63)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext[=14=](InstrumentedSubscriber.java:80)
at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
...
我注意到 属性 Bookings.AccessControlRecords 必须是大写的。但是 Bookings.resultCode 和 Bookings.resultText 并没有,我觉得很奇怪。与 AccessControlRecords.OccasionRecords 相同。当然,我一直在为 BookingNr 属性 尝试不同的案例,但无济于事。
谁能告诉我我做错了什么?或者也许有人知道如何进一步调试它?
如下所示使用@JsonProperty 解决了问题。
data class Bookings(@JsonProperty("AccessControlRecords") val accessControlRecords: AccessControlRecords, val resultCode: Int, val resultText: String?)
我从休息服务处收到以下 json。
{
"AccessControlRecords": {
"OccasionRecords": [
{
"Type": "",
"BookingNr": "91376",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "",
"PartOfObjectName": "",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "17.08.2019",
"BookToDate": "23.05.2020",
"OccasionDate": "2020-01-04 09:00",
"OccasionToDate": "2020-01-04 10:00",
"FomKlo": "09:00",
"TomKlo": "10:00",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 0,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "Svømmeklubben Frem",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
},
{
"Type": "",
"BookingNr": "90443",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "",
"PartOfObjectName": "",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "02.11.2019",
"BookToDate": "28.03.2020",
"OccasionDate": "2020-01-04 14:00",
"OccasionToDate": "2020-01-04 16:30",
"FomKlo": "14:00",
"TomKlo": "16:30",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 1,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "Odense Roklub",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
},
{
"Type": "",
"BookingNr": "91916",
"BookingRow": "1",
"FacilityID": "OIHAL",
"ObjectID": "STYRK",
"PartOfObjectId": "DELA",
"PartOfObjectName": "Delt styrketræning (A)",
"FacilityName": "Odense Idrætshal",
"ObjectName": "Styrketræningslokale",
"BookFromDate": "24.08.2019",
"BookToDate": "20.06.2020",
"OccasionDate": "2020-01-04 10:00",
"OccasionToDate": "2020-01-04 14:00",
"FomKlo": "10:00",
"TomKlo": "14:00",
"TimeBefore": "0",
"TimeAfter": "0",
"Weekday": 0,
"BookStatus": "",
"KortReg": "",
"CustomerID": "",
"CustomerName": "* Odense Håndbold talentcenter",
"TypeOfBooking": "E",
"CreatedBy": "",
"Cards": null,
"FunctionCode1": 0,
"FunctionCode2": 0,
"FunctionCode3": 0,
"FunctionCode4": "",
"Text1": "",
"Text2": "",
"Text3": "",
"Text4": "",
"EndUser": "",
"Activity": "Styrketræning"
}
]
},
"ResultCode": 0,
"ResultText": null
}
我的数据class定义如下
data class Bookings(val AccessControlRecords: AccessControlRecords, val resultCode: Int, val resultText: String?)
data class AccessControlRecords(val OccasionRecords: List<OccasionRecords>)
data class OccasionRecords(val type: String?,
val BookingNr: String,
val bookingRow: String,
val FacilityID: String,
val ObjectID: String,
val PartOfObjectId: String,
val PartOfObjectName: String,
val FacilityName: String,
val ObjectName: String,
val BookFromDate: String,
val BookToDate: String,
val OccasionDate: String,
val OccasionToDate: String,
val FomKlo: String,
val TomKlo: String,
val TimeBefore: String,
val TimeAfter: String,
val Weekday: Int,
val BookStatus: String,
val KortReg: String,
val CustomerID: String,
val CustomerName: String,
val TypeOfBooking: String,
val CreatedBy: String,
val Cards: String,
val FunctionCode1: Int,
val FunctionCode2: Int,
val FunctionCode3: Int,
val FunctionCode4: String,
val Text1: String,
val Text2: String,
val Text3: String,
val Text4: String,
val EndUser: String,
val Activity: String)
我的配置class定义如下
class BookingConfiguration {
companion object {
const val URL = "https://something.dk"
const val PATH = "/kmd_webapi/api/Monitor/GetFilteredAccessControlRecords?dateTimeFrom=2020-01-04&dateTimeTo=2020-01-04&facility=OIHAL&facilityObject=STYRK&partObject=&authenticationCode=xxx&type=json"
}
}
实际客户端定义如下
@Client(BookingConfiguration.URL)
interface BookingsClient {
@Get(BookingConfiguration.PATH)
fun fetchBookings(dateTimeFrom: String, dateTimeTo: String, authenticationCode: String): Flowable<Bookings>
}
我遇到的异常如下
01:31:59.199 [pool-1-thread-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error decoding JSON stream for type [T]: Instantiation of [simple type, class dk.fitfit.OccasionRecords] value failed for JSON property BookingNr due to missing (therefore NULL) value for creator parameter BookingNr which is a non-nullable type
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: dk.fitfit.Bookings["AccessControlRecords"]->java.lang.Object[0]->dk.fitfit.OccasionRecords["BookingNr"])
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [T]: Instantiation of [simple type, class dk.fitfit.OccasionRecords] value failed for JSON property BookingNr due to missing (therefore NULL) value for creator parameter BookingNr which is a non-nullable type
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: dk.fitfit.Bookings["AccessControlRecords"]->java.lang.Object[0]->dk.fitfit.OccasionRecords["BookingNr"])
at io.micronaut.jackson.codec.JsonMediaTypeCodec.decode(JsonMediaTypeCodec.java:123)
at io.micronaut.http.client.DefaultHttpClient.lambda$null(DefaultHttpClient.java:905)
at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:63)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext[=14=](InstrumentedSubscriber.java:80)
at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
...
我注意到 属性 Bookings.AccessControlRecords 必须是大写的。但是 Bookings.resultCode 和 Bookings.resultText 并没有,我觉得很奇怪。与 AccessControlRecords.OccasionRecords 相同。当然,我一直在为 BookingNr 属性 尝试不同的案例,但无济于事。
谁能告诉我我做错了什么?或者也许有人知道如何进一步调试它?
如下所示使用@JsonProperty 解决了问题。
data class Bookings(@JsonProperty("AccessControlRecords") val accessControlRecords: AccessControlRecords, val resultCode: Int, val resultText: String?)