나는 스칼라 케이스 클래스를 라운드 트립하기 위해 일부 작동 잭슨 스칼라 모듈 코드를 가지고있다. 잭슨은 플랫 케이스 클래스에서 훌륭하게 작동했지만 다른 케이스 클래스 목록이 포함 된 클래스를 만들었을 때 필요한 코드의 양이 많았습니다. 고려 : 시리얼 라이저와구조화 된 스칼라 케이스 클래스의 사용자 정의 json 직렬화
object ScrumGameMashaller {
val mapper = new ObjectMapper()
val module = new SimpleModule("CustomSerializer")
module.addSerializer(classOf[CardSet], new CardSetSerializer)
module.addDeserializer(classOf[CardSet], new CardSetDeserializer)
val scalaModule = DefaultScalaModule
mapper.registerModule(scalaModule)
mapper.registerModule(module)
def jsonFrom(value: Any): String = {
import java.io.StringWriter
val writer = new StringWriter()
mapper.writeValue(writer, value)
writer.toString
}
private[this] def objectFrom[T: Manifest](value: String): T =
mapper.readValue(value, typeReference[T])
private[this] def typeReference[T: Manifest] = new TypeReference[T] {
override def getType = typeFromManifest(manifest[T])
}
private[this] def typeFromManifest(m: Manifest[_]): Type = {
if (m.typeArguments.isEmpty) { m.runtimeClass }
else new ParameterizedType {
def getRawType = m.runtimeClass
def getActualTypeArguments = m.typeArguments.map(typeFromManifest).toArray
def getOwnerType = null
}
}
:
public class CardSetSerializer extends JsonSerializer<CardSet> {
@Override
public void serialize(CardSet cardSet, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeArrayFieldStart("cards");
List<CardDrawn> cardsDrawn = cardSet.cards();
scala.collection.Iterator<CardDrawn> iter = cardsDrawn.iterator();
while(iter.hasNext()){
CardDrawn cd = iter.next();
cdSerialize(jgen,cd);
}
jgen.writeEndArray();
jgen.writeStringField("mType", "CardSet");
jgen.writeEndObject();
}
private void cdSerialize(JsonGenerator jgen, CardDrawn cd) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("player", cd.player());
jgen.writeNumberField("card", cd.card());
jgen.writeEndObject();
}
}
잭슨 스칼라 모듈과 JSON에서 내가/자바로 작성 디시리얼라이저 사용자 지정 serializer를 사용에/
abstract class Message
case class CardDrawn(player: Long, card: Int, mType: String = "CardDrawn") extends Message
case class CardSet(cards: List[CardDrawn], mType: String = "CardSet") extends Message
가 CardSet은 라운드 트립을 얻으려면
및 매칭 디시리얼라이저 :
public class CardSetDeserializer extends JsonDeserializer<CardSet> {
private static class CardDrawnTuple {
Long player;
Integer card;
}
@Override
public CardSet deserialize(JsonParser jsonParser, DeserializationContext cxt) throws IOException, JsonProcessingException {
ObjectCodec oc = jsonParser.getCodec();
JsonNode root = oc.readTree(jsonParser);
JsonNode cards = root.get("cards");
Iterator<JsonNode> i = cards.elements();
List<CardDrawn> cardObjects = new ArrayList<>();
while(i.hasNext()){
CardDrawnTuple t = new CardDrawnTuple();
ObjectNode c = (ObjectNode) i.next();
Iterator<Entry<String, JsonNode>> fields = c.fields();
while(fields.hasNext()){
Entry<String,JsonNode> f = fields.next();
if(f.getKey().equals("player")) {
t.player = f.getValue().asLong();
} else if(f.getKey().equals("card")){
t.card = f.getValue().asInt();
} else {
System.err.println(CardSetDeserializer.class.getCanonicalName()+ " : unknown field " + f.getKey());
}
}
CardDrawn cd = new CardDrawn(t.player, t.card, "CardDrawn");
cardObjects.add(cd);
}
return new CardSet(JavaConversions.asScalaBuffer(cardObjects).toList(), "CardSet");
}
}
이것은 스칼라에서 상당히 바닐라적인 것을 다루는 많은 코드처럼 보입니다. 이 코드를 개선 할 수 있습니까? 그렇지 않으면 구조화 된 사례 클래스를 자동으로 수행 할 라이브러리가 있습니까? 저크슨 예제는 쉽게 보였지만 버려진 것 같습니다.
내가 유망 보았다 잭을 시도했지만 내가 여기에보고 이러한 클래스에 문제가 있었다 https://github.com/ wg/jacks/issues/15 – simbo1905
Argonaut는''암시적인 lazy val CodecCardSet로 작업을 수행합니다 : CodecJson [CardSet] = casecodec2 (CardSet.apply, CardSet.unapply) ("cards", "mType")'''and '''암묵적인 lazy val CodecCardDrawn : CodecJson [Card Drawn] = casecodec3 (CardDrawn.apply, CardDrawn.unapply) ("player", "card", "mType")'''예 : https://github.com/argonaut-io/argonaut/issues/64 – simbo1905
스칼라 잭슨 모듈 사용을 고려해 보셨습니까? https://github.com/FasterXML/jackson-module-scala –