spray-json을 사용한 Scala 케이스 객체의 JSON 역 직렬화

msilb

다음 도메인 모델을 JsonReader사용하여 사용자 지정을 작성하려고합니다 spray-json.

sealed trait OrderType
object OrderType {
  case object MARKET extends OrderType
  case object LIMIT extends OrderType
  case object STOP extends OrderType
  case object MARKET_IF_TOUCHED extends OrderType
  case object TAKE_PROFIT extends OrderType
  case object STOP_LOSS extends OrderType
  case object TRAILING_STOP_LOSS extends OrderType
}

JsonReader이 목적을 위해 만든 사용자 지정은 다음과 같습니다 .

implicit object OrderTypeJsonReader extends JsonReader[OrderType] {
  def read(value: JsValue): OrderType = value match {
    case JsString("MARKET") => MARKET
    case JsString("LIMIT") => LIMIT
    case JsString("STOP") => STOP
    case JsString("MARKET_IF_TOUCHED") => MARKET_IF_TOUCHED
    case JsString("TAKE_PROFIT") => TAKE_PROFIT
    case JsString("STOP_LOSS") => STOP_LOSS
    case JsString("TRAILING_STOP_LOSS") => TRAILING_STOP_LOSS
    case _ => deserializationError("OrderType expected")
  }
}

json 문자열과 이름이 case object동일 하다는 점을 감안할 때 여기에서 코드 중복을 피할 수있는 방법이 있습니까?

Zelezoglo

패턴 일치를 부분 함수 (또는 맵)로 바꾸려고 시도 할 수 있습니다.

val orderTypes = List(MARKET, LIMIT, STOP, MARKET_IF_TOUCHED, TAKE_PROFIT, STOP_LOSS, TRAILING_STOP_LOSS)

val string2orderType: Map[JsValue, OrderType] = 
  orderTypes.map(ot => (JsString(ot.toString), ot)).toMap

implicit object OrderTypeJsonReader extends JsonReader[OrderType] {
  def read(value: JsValue): OrderType = 
    string2orderType.getOrElse(value, deserializationError("OrderType expected"))
}

단점은 모든 케이스 오브젝트의 목록을 수동으로 지정해야한다는 것입니다. 리플렉션을 사용하여 생성 할 수 있습니다. 아마도이 질문은 봉인 된 특성의 서브 클래스 얻기에 도움이 될 것입니다 . 그러면 다음을 가질 수 있습니다.

import scala.reflect.runtime.universe

private val tpe = universe.typeOf[OrderType]
private val clazz = tpe.typeSymbol.asClass

private def objectBy[T](name: String): T = Class.forName(OrderType.getClass.getName + name + "$").newInstance().asInstanceOf[T]

val string2orderType: Map[JsValue, OrderType] = clazz.knownDirectSubclasses.map { sc =>
  val objectName = sc.toString.stripPrefix("object ")
  (JsString(objectName), objectBy[OrderType](objectName))
}.toMap

implicit object OrderTypeJsonReader extends JsonReader[OrderType] {
  def read(value: JsValue): OrderType = string2orderType.getOrElse(value, deserializationError("OrderType expected"))
}

스프레이에 기본 케이스 클래스 형식을 추가하는 방법에 대한이 토론도 참조하십시오 : https://github.com/spray/spray-json/issues/186

의견을 해결하기 위해 업데이트

모든 유형 T에 대해 '생성'할 수 있습니까? 봉인 된 트레이 트 / 케이스 객체 열거가 꽤 많고 보일러 플레이트를 최소로 유지하는 것을 선호합니다.

나는 이것을 생각 해냈다 :

import spray.json._
import Utils._

sealed trait OrderStatus
object OrderStatus {
  case object Cancelled extends OrderStatus
  case object Delivered extends OrderStatus
  // More objects...

  implicit object OrderStatusJsonReader extends ObjectJsonReader[OrderStatus]
}

sealed trait OrderType
object OrderType {
  case object MARKET extends OrderType
  case object LIMIT extends OrderType
  // More objects...

  implicit object OrderTypeJsonReader extends ObjectJsonReader[OrderType]
}

object Utils {
  import scala.reflect.ClassTag
  import scala.reflect.runtime.universe._

  def objectBy[T: ClassTag](name: String): T = {
    val c = implicitly[ClassTag[T]]
    Class.forName(c + "$" + name + "$").newInstance().asInstanceOf[T]
  }

  def string2trait[T: TypeTag : ClassTag]: Map[JsValue, T] = {
    val clazz = typeOf[T].typeSymbol.asClass
    clazz.knownDirectSubclasses.map { sc =>
      val objectName = sc.toString.stripPrefix("object ")
      (JsString(objectName), objectBy[T](objectName))
    }.toMap
  }

  class ObjectJsonReader[T: TypeTag : ClassTag] extends JsonReader[T] {
    val string2T: Map[JsValue, T] = string2trait[T]
    def defaultValue: T = deserializationError(s"${ implicitly[ClassTag[T]].runtimeClass.getCanonicalName } expected")
    override def read(json: JsValue): T = string2T.getOrElse(json, defaultValue)
  }
}

그런 다음 다음과 같이 사용할 수 있습니다.

import OrderType._
import OrderStatus._
JsString("MARKET").convertTo[OrderType]
JsString(OrderStatus.Cancelled.toString).convertTo[OrderStatus]

또한 spray-json github 문제의 코드를 시도했으며 다음과 같이 사용할 수 있습니다.

implicit val orderTypeJsonFormat: RootJsonFormat[OrderType] = 
  caseObjectJsonFormat(MARKET, LIMIT, STOP, MARKET_IF_TOUCHED, TAKE_PROFIT, STOP_LOSS, TRAILING_STOP_LOSS)

안타깝게도 모든 객체를 명시 적으로 지정해야합니다. 당신이 그렇게하고 싶다면, 내 첫 번째 제안 (반성없이)이 더 낫다고 생각합니다. (반사가 없기 때문에 :-))

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

GSON을 사용하여 객체의 JSON 배열 역 직렬화

분류에서Dev

복잡한 Json 객체 역 직렬화

분류에서Dev

자바 객체에 datetime을 사용하여 JSON 역 직렬화

분류에서Dev

JSON 역 직렬화에 Scala Jackson을 사용하십니까?

분류에서Dev

Jackson을 사용한 JSON 파일의 다형성 역 직렬화

분류에서Dev

JSON을 .net 객체로 역 직렬화

분류에서Dev

JSON.net을 사용하여 대량의 json 데이터 역 직렬화

분류에서Dev

JSON.net을 사용하여 대량의 json 데이터 역 직렬화

분류에서Dev

Play의 json을 사용하여 동적 필드 이름을 직렬화 / 역 직렬화하는 방법

분류에서Dev

복잡한 JSON 개체 역 직렬화

분류에서Dev

컨테이너없이 JSON.NET을 사용하여 개체 역 직렬화

분류에서Dev

JSON.NET으로 이상한 구조의 JSON 역 직렬화

분류에서Dev

목록 속성을 사용하여 JSON을 객체로 역 직렬화

분류에서Dev

이상한 JSON 역 직렬화

분류에서Dev

JSON 개체 역 직렬화

분류에서Dev

Collection + JSON 객체로 역 직렬화

분류에서Dev

다양한 유형의 객체를 포함하는 JSON 배열 역 직렬화

분류에서Dev

JSON Newtonsoft C # 다양한 유형의 객체 목록 역 직렬화

분류에서Dev

System.Text.Json을 사용하여 이상한 모양의 데이터 역 직렬화

분류에서Dev

Jackson을 사용하여 임의의 JSON 역 직렬화

분류에서Dev

Rust : JSON 배열을 매우 간단한 사용자 정의 테이블로 역 직렬화

분류에서Dev

C #을 사용하여 클래스로 JSON 역 직렬화

분류에서Dev

Jackson API-간단한 동적 객체로 JSON 역 직렬화

분류에서Dev

NSJSONSerialization을 사용하여 json에서 이미지 역 직렬화

분류에서Dev

구조와 이름이 다른 json 객체 역 직렬화

분류에서Dev

객체를 사전으로 역 직렬화하는 JSON

분류에서Dev

Jackson을 사용한 사용자 지정 JSON 직렬화 / 역 직렬화

분류에서Dev

잘못된 JSON을 사용한 Spring MVC JSON 역 직렬화 (Jackson)

분류에서Dev

JSON을 C # 개체로 역 직렬화

Related 관련 기사

  1. 1

    GSON을 사용하여 객체의 JSON 배열 역 직렬화

  2. 2

    복잡한 Json 객체 역 직렬화

  3. 3

    자바 객체에 datetime을 사용하여 JSON 역 직렬화

  4. 4

    JSON 역 직렬화에 Scala Jackson을 사용하십니까?

  5. 5

    Jackson을 사용한 JSON 파일의 다형성 역 직렬화

  6. 6

    JSON을 .net 객체로 역 직렬화

  7. 7

    JSON.net을 사용하여 대량의 json 데이터 역 직렬화

  8. 8

    JSON.net을 사용하여 대량의 json 데이터 역 직렬화

  9. 9

    Play의 json을 사용하여 동적 필드 이름을 직렬화 / 역 직렬화하는 방법

  10. 10

    복잡한 JSON 개체 역 직렬화

  11. 11

    컨테이너없이 JSON.NET을 사용하여 개체 역 직렬화

  12. 12

    JSON.NET으로 이상한 구조의 JSON 역 직렬화

  13. 13

    목록 속성을 사용하여 JSON을 객체로 역 직렬화

  14. 14

    이상한 JSON 역 직렬화

  15. 15

    JSON 개체 역 직렬화

  16. 16

    Collection + JSON 객체로 역 직렬화

  17. 17

    다양한 유형의 객체를 포함하는 JSON 배열 역 직렬화

  18. 18

    JSON Newtonsoft C # 다양한 유형의 객체 목록 역 직렬화

  19. 19

    System.Text.Json을 사용하여 이상한 모양의 데이터 역 직렬화

  20. 20

    Jackson을 사용하여 임의의 JSON 역 직렬화

  21. 21

    Rust : JSON 배열을 매우 간단한 사용자 정의 테이블로 역 직렬화

  22. 22

    C #을 사용하여 클래스로 JSON 역 직렬화

  23. 23

    Jackson API-간단한 동적 객체로 JSON 역 직렬화

  24. 24

    NSJSONSerialization을 사용하여 json에서 이미지 역 직렬화

  25. 25

    구조와 이름이 다른 json 객체 역 직렬화

  26. 26

    객체를 사전으로 역 직렬화하는 JSON

  27. 27

    Jackson을 사용한 사용자 지정 JSON 직렬화 / 역 직렬화

  28. 28

    잘못된 JSON을 사용한 Spring MVC JSON 역 직렬화 (Jackson)

  29. 29

    JSON을 C # 개체로 역 직렬화

뜨겁다태그

보관