次のような構造を持つ Scala クラスをシリアライズ/デシリアライズする必要があります。
@JsonIgnoreProperties(ignoreUnknown = true, value = Array("body"))
case class Example(body: Array[Byte]) {
lazy val isNativeText = bodyIsNativeText
lazy val textEncodedBody = (if (isNativeText) new String(body, "UTF-8") else Base64.encode(body))
def this(isNativeText: Boolean, textEncodedBody: String) = this((if(isNativeText) str.getBytes("UTF-8") else Base64.decode(textEncodedBody)))
def bodyIsNativeText: Boolean = // determine if the body was natively a string or not
}
その主なメンバーはバイトの配列であり、UTF-8 でエンコードされたテキスト文字列を表すかもしれませんが、そうでないかもしれません。プライマリ コンストラクターはバイト配列を受け入れますが、この文字列が base64 でエンコードされたバイナリ データであるか、格納する実際のネイティブ テキストであるかを示すフラグ付きの文字列を受け入れる代替コンストラクターがあります。
JSON オブジェクトにシリアル化するために、本文がネイティブ テキストの場合、base64 でエンコードされた文字列ではなく、ネイティブ文字列として格納したいと考えています。そのため、私はプロパティを@JsonIgnoreProperties
含めず、代わりに JSON でエコーされる a を使用しています。body
textEncodedBody
問題は、次のように逆シリアル化しようとすると発生します。
val e = Json.parse[Example]("""{'isNativeText': true, 'textEncodedBody': 'hello'}""")
次のエラーが表示されます。
com.codahale.jerkson.ParsingException: 無効な JSON。[body] が必要でしたが、[isNativeText, textEncodedBody] が見つかりました。
明らかに、動作するコンストラクターがあります...それはデフォルトのものではありません。Jerkson にこのデフォルト以外のコンストラクターを使用させるにはどうすればよいですか?
@JsonProperty
編集:と注釈の両方を使用しようとしました@JsonCreator
が、ジャークソンはそれらの両方を無視しているようです。
EDIT2 :ジャークソン ケース クラス シリアライゼーション ソース コードを見ると、そのフィールドと同じ名前のケース クラス メソッド@JsonProperty
が機能する方法、つまり JSON ゲッターとして使用されるように見えます。それができれば、私の問題は解決するでしょう。Scala にあまり詳しくないので、その方法がわかりません。ケース クラスがそのフィールドの 1 つと同じ名前のユーザー定義メソッドを持つことは可能ですか?
参考までに、この結論に導く以下のコードを次に示します...
private val methods = klass.getDeclaredMethods
.filter { _.getParameterTypes.isEmpty }
.map { m => m.getName -> m }.toMap
def serialize(value: A, json: JsonGenerator, provider: SerializerProvider) {
json.writeStartObject()
for (field <- nonIgnoredFields) {
val methodOpt = methods.get(field.getName)
val fieldValue: Object = methodOpt.map { _.invoke(value) }.getOrElse(field.get(value))
if (fieldValue != None) {
val fieldName = methodOpt.map { _.getName }.getOrElse(field.getName)
provider.defaultSerializeField(if (isSnakeCase) snakeCase(fieldName) else fieldName, fieldValue, json)
}
}
json.writeEndObject()
}