ScalaのOption
とBlob
の型を処理するためにGsonを拡張できましたが、Option[java.sql.Blob]
の組み合わせで問題があります。Scala Gson、シリアライズできませんオプション[Blob]
私のテストは
言う[情報] - オプションをシリアル化する必要がある - OK
[情報] - ブロブをシリアル化する必要がある - OK
[情報] - オプションをシリアル化する必要があります[ブロブ] * FAILED
[INFO] { "X":{ "BUF":[97115100102]、 "LEN":4、 "origLen":4}} { "X" に等しくありませんでした。 "asdf"}
あなたはこの{"buf": [...]}
オブジェクトが何であるのか教えてください.Gsonがそれをやっているのかもしれませんか?私のシリアライザ(下記)間違いなくそれから文字列を作るために彼に告げる、まだこのオブジェクトはさらに引用符で囲まれていないです。
FWIW、本当のブロブとオプション[ブロブ]フィールドを持っている現実のオブジェクト(データベースの行)を直列化しようと、私もStackOverflowのエラーを取得します。
case class B(x: Option[Int], y: String)
case class C(x: java.sql.Blob)
case class D(x: Option[java.sql.Blob])
"serialize options" in {
val b = B(Some(1), "asdf")
gson.toJson(b) must be ("{\"x\":1,\"y\":\"asdf\"}")
}
"serialize a Blob" in {
val c = C(utils.string2Blob("asdf"))
gson.toJson(c) must be ("{\"x\":\"asdf\"}")
}
"serialize an Option[Blob]" in {
val d = D(Some(utils.string2Blob("asdf")))
gson.toJson(d) must be ("{\"x\":\"asdf\"}")
}
そして、念のBlobからとの私の変換方法、::
上記の結果を生成class OptionSerializer extends JsonSerializer[Option[Any]] {
def serialize(src: Option[Any], typeOfSrc: Type, context: JsonSerializationContext): JsonElement = {
src match {
case None => JsonNull.INSTANCE
case Some(v) => context.serialize(v)
}
}
}
class BlobSerializer extends JsonSerializer[java.sql.Blob] {
override def serialize(src: java.sql.Blob, typeOfSrc: Type, context: JsonSerializationContext): JsonElement = {
val s: String = utils.blob2String(v)
context.serialize(s)
}
}
class BlobOptionSerializer extends JsonSerializer[Option[java.sql.Blob]] {
override def serialize(src: Option[java.sql.Blob], typeOfSrc: Type, context: JsonSerializationContext): JsonElement = {
src match {
case None => JsonNull.INSTANCE
case Some(v: java.sql.Blob) =>
val s: String = utils.blob2String(v)
context.serialize(s)
}
}
}
private val builder = new GsonBuilder()
builder.registerTypeAdapter(classOf[java.sql.Blob], new BlobSerializer)
builder.registerTypeAdapter(classOf[Option[java.sql.Blob]], new BlobOptionSerializer)
builder.registerTypeAdapter(classOf[Option[Any]], new OptionSerializer)
val gson = builder.create()
テスト:ここ
は、私がシリアライザを書いた方法です:溶液は、Optionのシリアライザ内部BLOB型[任意]を特殊ケース実測
def string2Blob(s: String) = {
new SerialBlob(s.getBytes)
}
def blob2String(blob: java.sql.Blob): String = {
if (blob.length == 0)
return "" // Array[Byte]()
val b: Array[Byte] = blob.getBytes(1, blob.length.toInt)
blob.free
new String(b)
}
'オプション[Any]'のシリアライザを削除すると、 'Option [Blob]'はうまく動作することに気づきました。それらは "スタック"なので、おそらく 'Option [Blob以外のもの] 'とオプション[Blob]のためのものです。 – JulienD