Scala - case class 的自定义编组器
Scala - custom Marshaller for case class
我正在为 Spray 框架实施 REST api 并尝试以良好的 json 格式实施响应
这里有一点如果代码:
case class Response(msg: String, APIv: String = "", requestNr: String = "")
case class Error(msg: String, errNo: String, exception: String = "")
case class ErrorResponse(error: Error, APIv: String = "", requestNr: String = "")
object Marshallers extends DefaultJsonProtocol with SprayJsonSupport {
implicit val response = jsonFormat3(Response)
implicit val error = jsonFormat3(Error)
implicit val errorResponse = jsonFormat3(ErrorResponse)
}
然后对于 get 方法,我是这样使用它的:
def getRoute = get {
path("schema" / Segment) { schemaClassShortId : String =>
respondWithMediaType(`application/json`) {
complete(
FakeStorage.service.getSchema(schemaClassShortId) match {
case None => new ErrorResponse(new Error("SchemaClass with ID: ["+schemaClassShortId + "] not found", EC.SchemaClassNotFound))
case Some(schema) => new Response(schema.toString, "APIv-test", "RequestNr-test")
}
)
}
}
}
请注意,class 的情况在构造函数中可能有缺失值,例如 "Response" class "APIv" 或 "RequestNr" 可能不会被传递和设置清空 - ("")
这样的 class 会产生休闲的 JSON 响应:
{
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000",
"exception": ""
},
"APIv": "",
"requestNr": ""
}
但是我想改变两件事:
1) 订单
{
"APIv": "",
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000",
"exception": ""
},
"requestNr": ""
}
2) 完全不将空对象包含在响应中
{
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000"
}
}
据我所知,我需要编写自定义 Marshaller - 但是我不确定如何去做,因为我对 Spray 尤其是 Scala 还很陌生
你能举例说明我的案例吗?
如果您想更改 json 中字段的顺序,只需更改 class 中的顺序即可。
如果您不想显示为空或 null 的字段,只需使用带有默认值 None 的选项,spray-json 默认情况下不会序列化 None 的字段所以他们不会出现在 json 中。
case class ErrorResponse(APIv: Option[String] = None, error: Error, requestNr: Option[String] = None)
我正在为 Spray 框架实施 REST api 并尝试以良好的 json 格式实施响应
这里有一点如果代码:
case class Response(msg: String, APIv: String = "", requestNr: String = "")
case class Error(msg: String, errNo: String, exception: String = "")
case class ErrorResponse(error: Error, APIv: String = "", requestNr: String = "")
object Marshallers extends DefaultJsonProtocol with SprayJsonSupport {
implicit val response = jsonFormat3(Response)
implicit val error = jsonFormat3(Error)
implicit val errorResponse = jsonFormat3(ErrorResponse)
}
然后对于 get 方法,我是这样使用它的:
def getRoute = get {
path("schema" / Segment) { schemaClassShortId : String =>
respondWithMediaType(`application/json`) {
complete(
FakeStorage.service.getSchema(schemaClassShortId) match {
case None => new ErrorResponse(new Error("SchemaClass with ID: ["+schemaClassShortId + "] not found", EC.SchemaClassNotFound))
case Some(schema) => new Response(schema.toString, "APIv-test", "RequestNr-test")
}
)
}
}
}
请注意,class 的情况在构造函数中可能有缺失值,例如 "Response" class "APIv" 或 "RequestNr" 可能不会被传递和设置清空 - ("")
这样的 class 会产生休闲的 JSON 响应:
{
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000",
"exception": ""
},
"APIv": "",
"requestNr": ""
}
但是我想改变两件事:
1) 订单
{
"APIv": "",
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000",
"exception": ""
},
"requestNr": ""
}
2) 完全不将空对象包含在响应中
{
"error": {
"msg": "SchemaClass with ID: [wrongId] not found",
"errNo": "1000"
}
}
据我所知,我需要编写自定义 Marshaller - 但是我不确定如何去做,因为我对 Spray 尤其是 Scala 还很陌生
你能举例说明我的案例吗?
如果您想更改 json 中字段的顺序,只需更改 class 中的顺序即可。
如果您不想显示为空或 null 的字段,只需使用带有默认值 None 的选项,spray-json 默认情况下不会序列化 None 的字段所以他们不会出现在 json 中。
case class ErrorResponse(APIv: Option[String] = None, error: Error, requestNr: Option[String] = None)