Json Circe解码器-如果失败,则返回到另一个解码器
我使用Circe进行json操作。我添加了自定义编码器和解码器来处理一些类型,比如Joda Time 在分析DateTime时,我想允许传递多种格式。 例如,Json Circe解码器-如果失败,则返回到另一个解码器,json,scala,circe,Json,Scala,Circe,我使用Circe进行json操作。我添加了自定义编码器和解码器来处理一些类型,比如Joda Time 在分析DateTime时,我想允许传递多种格式。 例如,dd-MM-yyyy'T'HH:MM:ss'Z'和dd-MM-yyyy'T'HH:MM:ss.SSS'Z' 我对解码器的定义如下: val dateTimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'") val dateTimeFormatWithMillis =
dd-MM-yyyy'T'HH:MM:ss'Z'
和dd-MM-yyyy'T'HH:MM:ss.SSS'Z'
我对解码器的定义如下:
val dateTimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
val dateTimeFormatWithMillis = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
implicit val jodaDateTimeFormat: Encoder[DateTime] with Decoder[DateTime] = new Encoder[DateTime] with Decoder[DateTime] {
override def apply(a: DateTime): Json = Encoder.encodeString(a.toString("yyyy-MM-dd'T'HH:mm:ss'Z'"))
override def apply(c: HCursor): Result[DateTime] = Decoder.decodeString.map { x =>
DateTime.parse(x, dateTimeFormat)
}.apply(c)
}
现在,如果我输入了一个与dateTimeFormat
匹配的datetime字符串,那么解码将起作用,但是如果我在datetimeformatwillis
中传递datetime,它将无法处理
我知道我可以使用DateTimeFormatterBuilder
添加多个解析器并对其进行处理,但是,我想知道在Circe中是否有一种方法可以链接多个解码器,一个接一个地尝试,直到成功或到达链的末端 您可以使用组合解码器,以便在第一个解码器失败时尝试第二个解码器
以下是一个工作示例:
import org.joda.time.DateTime
导入org.joda.time.format.{DateTimeFormat,DateTimeFormatter}
导入io.circe.{解码器,编码器}
导入io.circe.parser.decode
导入scala.util.Try
val dateTimeFormat=dateTimeFormat.forPattern(“yyyy-MM-dd'T'HH:MM:ss'Z'))
val datetimeformatwillis=DateTimeFormat.forPattern(“yyyy-MM-dd'T'HH:MM:ss.SSS'Z'))
/**创建使用提供的格式解码[[DateTime]]的解码器*/
def dateTimeFormatDecoder(格式:DateTimeFormatter):解码器[日期时间]=
解码器[String].emapTry(str=>Try(DateTime.parse(str,format)))
/**[[Decoder]]用于第一种格式(不含毫秒)*/
val DateTime不带毫秒编码器:解码器[日期时间]=
dateTimeFormatDecoder(dateTimeFormat)
/**[[Decoder]]用于第二种格式(毫秒)*/
val dateTimeWithMillisDecoder:解码器[日期时间]=
dateTimeFormatDecoder(dateTimeFormatWithMillis)
/**使用`Encoder[String].contramap(…)``对[[DateTime]]进行编码,这是
*也许是一个更为惯用的版本
*`Encoder.encodeString(a.toString(“yyyy-MM-dd'T'HH:MM:ss'Z'))`*/
隐式val-jodatetimeencoder:Encoder[DateTime]=
编码器[String].contramap(u.toString(“yyyy-MM-dd'T'HH:MM:ss'Z'))
隐式val jodaDateTimeDecoder:解码器[日期时间]=
不带毫秒编码器的日期时间或带毫秒编码器的日期时间
println(解码[日期时间](“”“2001-02-03T04:05:06Z”)
println(解码[日期时间](“”“2001-02-03T04:05:06.789Z”))
请注意,编码器
和解码器
是分开的,因为解码器#或
返回一个解码器
,它不能与组合类一起工作(即编码器[DateTime]和解码器[DateTime]
)
另外,DateTime.parse
调用已用包装,因为或
组合器(以及通常所有解码器
组合器)希望处理或
值,而不是异常