2017-06-16 9 views
0

私は2つのケースクラスを持っています。主なもの、Requestは、2つのマップを含んでいます。 最初のマップには、キーと値の両方の文字列があります。 2番目のマップには文字列キーがあり、2番目のケースクラスのインスタンスである値KVMapListがあります。ScalaのケースクラスをJSONに変換

RequestをJSON表現に変換する必要があります。 次のコードは、これを実行しようとしている:

import com.fasterxml.jackson.annotation.PropertyAccessor 
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper 
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility 
import com.fasterxml.jackson.databind.ObjectMapper 

def test(req:Request):String { 
    val mapper = new ObjectMapper() with ScalaObjectMapper 
    mapper.setVisibility(PropertyAccessor.ALL, Visibility.ANY) 
    var jsonInString: String = null 
    try { 
    jsonInString = mapper.writeValueAsString(request) 
    } 
    catch { 
    =case e: IOException => { 
     e.printStackTrace 
    } 
    jsonString 
} 

しかし、これは動作しません。 Requestクラスが移入された場合でも、出力は次のとおりです。

{"parameters":{"underlying":{"some-value":""},"empty":false,"traversableAgain":true},"deps":{"sizeMapDefined":false,"empty":false,"traversableAgain":true}} 

対応するJavaクラスを持つJSONオブジェクトマッパーを使用することは簡単ですが、まだそれはScalaで働いて持っていません。どんな援助も非常に感謝しています。

答えて

5

ジャクソンは、ある程度Scalaの悪い古い記憶の多くです。 JSON処理のためにネイティブのScalaライブラリ、特にcirceのようなJSONシリアライザのコンパイル時の導出に本当に良いものを使用する必要があります。

私はこれがあなたの質問に直接答えないことを知っていますが、circeを使用した後は決して他のものに戻ることはありません。それはにつれてケースクラス内の変更可能なマップを使用して別のノートで

import io.circe.generic.auto._ 
import io.circe.parser._ 
import io.circe.syntax._ 

val req = new Request(...) 
val json = req.asJson.noSpaces 
val reparsed = decode[Request](json) 

は、非慣用的であり、自動生成さ copy法を使用して、マップの不変オプスを実装するのは非常に些細でなければなりません。

case class Request(parameters: Map[String, String] { 
    def +(key: String, value: String): Request = { 
    this.copy(parameters = parameters + (key -> value)) 
    } 
} 

可能であればどこでも変更可能性を避けてください。ここで回避すると、あまり効果がないようです。

+0

req.asJson.noSpaces:error:scala.MatchError:true(クラスscala.reflect.internal.Trees $ Literal)のコンパイル時に、ビルドに失敗しました。 jar circe-parse_sjs0.6_2.11とcirce-generic_2.11を使用しています(両方ともグループio.circeから)。ありがとう! – user1052610

1

私はこのScalaObjectMapperが何をするのか分かりませんが、それは有用であるとは思われません。 最初にmapper.registerModule(DefaultScalaModule)を追加すると、それはうまくいくはずです... MutableMapとするとmutable.Mapを意味し、何らかの種類の自家製のクラスではありません(そうした場合、シリアライザを自分で提供する必要があるからです)。

DefaultScalaModulejackson-module-scalaライブラリです。まだビルドしていない場合は追加してください)。

+0

この例外は、registerModuleが呼び出されたときにスローされます。スレッド "main"内の例外java.lang.VerifyError:クラスcom.fasterxml.jackson.module.scala.ser.ScalaIteratorSerializerは、finalメソッドwithResolvedをオーバーライドします(Lcom/fasterxml/jackson/databind/Lcom/fasterxml/jackson/databind/jsontype/TypeSerializer; Lcom/fasterxml/jackson/databind/JsonSerializer;)Lcom/fasterxml/jackson/databind/ser/std/AsArraySerializerBase; – user1052610

+0

間違ったバージョンを使用している必要があります。 jacksonコアとscalaモジュールライブラリのバージョンは同じでなければなりません。 – Dima

+0

ディマに感謝します。別の問題が修正されました。これはエラーです:Scalaモジュール2.9.0では、Jackson Databindバージョン> = 2.9.0と<2.10.0が必要です。しかし、2.9.0.pr3より高いバージョンのJackson-databindを見つけることができません。 – user1052610

関連する問題