2017-01-24 7 views
0

ScalaのOptionBlobの型を処理するために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) 
} 
+0

'オプション[Any]'のシリアライザを削除すると、 'Option [Blob]'はうまく動作することに気づきました。それらは "スタック"なので、おそらく 'Option [Blob以外のもの] 'とオプション[Blob]のためのものです。 – JulienD

答えて

0
class OptionSerializer extends JsonSerializer[Option[Any]] { 
    def serialize(src: Option[Any], typeOfSrc: Type, context: JsonSerializationContext): JsonElement = { 
    src match { 
     case None => JsonNull.INSTANCE 
     case Some(b: java.sql.Blob) => context.serialize(utils.Sql.blob2String(b)) 
     case Some(v) => context.serialize(v) 
    } 
    } 
} 
関連する問題