Ứng dụng của tôi hỗ trợ nối tiếp protobuf và JSON. Đối với serialization JSON tôi sử dụng com.trueaccord.scalapb.json.JsonFormat
, dtos của tôi được tạo từ các định nghĩa proto.Tôi làm cách nào để sử dụng tiêu đề yêu cầu http để đàm phán nội dung trong Mashaller?
Các loại tùy chọn kết thúc com.trueaccord
nối tiếp các đối tượng JSON gây ra sự cố cho một số khách hàng vì vậy tôi muốn có thể hỗ trợ org.json4s
mà không cần phanh máy khách hiện tại.
Tôi muốn có thể chọn trình nối tiếp dựa trên tiêu đề http tùy chỉnh được gọi là JFORMAT. Ý tưởng là nếu tiêu đề này được gửi, tôi sẽ sử dụng json4s nếu không tôi sẽ sử dụng serializer trueaccord.
tôi cố gắng tạo ra một Unmarshaller có thể chọn một serializer yêu cầu dựa trên một giá trị tiêu đề:
Unmarshaller.withMaterializer[HttpRequest, T](_ => implicit mat => {
case request: HttpRequest =>
val entity = request.entity
entity.dataBytes.runFold(ByteString.empty)(_ ++ _).map(data => {
entity.contentType match {
case `applicationJsonContentType` =>
val jsFormat = {
val header = request.headers.find(h => h.name() == jsonFormatHeaderName)
if (header.isEmpty) "1.0" else header.get.value()
}
val charBuffer = Unmarshaller.bestUnmarshallingCharsetFor(entity)
val jsonText = data.decodeString(charBuffer.nioCharset().name())
val dto = if(jsFormat == "2.0") {
write[T](value)(formats) // New Formatter
} else {
JsonFormat.fromJsonString[T](jsonText) // Old Formatter
}
dto
case `protobufContentType` =>
companion.parseFrom(CodedInputStream.newInstance(data.asByteBuffer)) // Proto Formatter
case _ =>
throw UnsupportedContentTypeException(applicationJsonContentType, protobufContentType)
}
})
Tôi muốn làm điều tương tự với marshaller của tôi mà tôi sử dụng với Marshaller.oneOf và xử lý một JSON trông giống như:
Marshaller.withFixedContentType(contentType) { value =>
val jsonText = JsonSerializer.toJsonString[T](value)
HttpEntity(contentType, jsonText)
}
Có cách nào để xây dựng Mashaller nhận thức được tiêu đề http yêu cầu không? Tài liệu HTTP Akka không có bất kỳ ví dụ nào và tôi không thể hiểu được PredefinedToRequestMarshallers.
Tôi có cần kết hợp nhiều trình khắc phục sự cố bằng cách nào đó hoặc tôi có thể thêm một số siêu dữ liệu vào ngữ cảnh trong quá trình tuần tự yêu cầu mà tôi có thể sử dụng sau trong Marshaller không? Tôi muốn tránh thêm meta vào dto của mình nếu có thể hoặc sử dụng loại nội dung tùy chỉnh như application/vnd.api+json
Có rất nhiều thông tin hữu ích khác mà tôi có thể sử dụng từ yêu cầu khi tôi định dạng phản hồi như Accept-Encoding, tiêu đề tùy chỉnh như duy nhất yêu cầu id để tạo ra một id tương quan, tôi có thể thêm hỗ trợ JSONP bằng cách đọc các parmeter callback
truy vấn vv
để làm rõ: tôi cần một giải pháp để sử dụng Mashaller, lớp con của nó hoặc một phiên bản tùy chỉnh được tạo ra bởi một phương pháp nhà máy hoặc có thể nhiều Marshallers xích lại với nhau. Marshaller.withFixedContentType
đã sử dụng tiêu đề Accept
do đó phải có cách. Tôi đã thêm tiền thưởng để thưởng cho một giải pháp cho một thử thách cụ thể. Tôi là kho của hacks và cách giải quyết và tôi hỏi câu hỏi bởi vì tôi cần một giải pháp sạch sẽ giải quyết một kịch bản cụ thể.
Tôi có thể thiếu điều gì đó ở đây: tại sao bạn không khởi tạo trình khắc phục sự cố sau khi nhận yêu cầu và khi bạn biết bạn cần yêu cầu nào? Nó có ý nghĩa khi unmarshalling để quản lý tất cả các loại nội dung, nhưng marshalling là khá nhiều bạn chuyển câu trả lời của bạn để bất cứ điều gì bạn muốn, vì vậy nếu bạn muốn nó phụ thuộc vào yêu cầu, làm cho nó một chức năng của yêu cầu? – C4stor