복붙노트

[SCALA] 스칼라는 케이스 (22 개) 필드를 가지고 있지만 스칼라 2.11.5에서 플레이 JSON과 문제가 발생

SCALA

스칼라는 케이스 (22 개) 필드를 가지고 있지만 스칼라 2.11.5에서 플레이 JSON과 문제가 발생

스칼라 2.11, 우리는 경우 클래스의 권리를 더 다음 22 개 필드를 가질 수있다?

case class SomeResponse(
                                     var compositeKey: String,
                                     var id1: String,
                                     var id2: String,
                                     var firstName: String,
                                     var lastName: String,
                                     var email: String,
                                     var email2: String,
                                     var birth: Long,
                                     var gender: String,
                                     var phone: Phone,
                                     var city: String,
                                     var zip: String,
                                     var carriage: Boolean,
                                     var carriage2: Boolean,
                                     var fooLong: Long,
                                     var fooLong2: Long,
                                     var suspended: Boolean,
                                     var foo: Foo,
                                     var address: String,
                                     var suite: String,
                                     var state: String,
                                     var instructions: String)

implicit val formatSomeResponse = Json.format[SomeResponse]

그럼 위의 플레이 JSON 형식으로 정확히 22 필드가있는 경우 클래스는, 지금은 컴파일 할 때,이 오류가 발생합니다 :

SomeFile.scala:126: value apply is not a member of play.api.libs.functional.FunctionalBuilder[play.api.libs.json.OFormat]#CanBuild22[String,String,String,String,String,String,String,Long,String,com.Phone,String,String,Boolean,Boolean,Long,Long,Boolean,com.Foo,String,String,String,String]

그리고 케이스 클래스 전화 및 푸 각 두 개의 필드를 각각 가지고있다.

실제로 문제를 직면하고있는 이유 그래서, 그것은 22 개 필드 제한 교차하지 않거나 다른 뭔가 내가 잘못했다이며, 나는 스칼라 2.11.5 / 2.11.1에서 그것을 시도 - 플레이 JSON 2.3

최신 정보: 제임스와 Phadej에 의해 답변을 바탕으로

  val someResponseFirstFormat: OFormat[(String, String, String, String, String, String, String, Long, String, Phone, String)] =
    ((__ \ "compositeKey").format[String] and
      (__ \ "id1").format[String] and
      (__ \ "id2").format[String] and
      (__ \ "firstName").format[String] and
      (__ \ "lastName").format[String] and
      (__ \ "email").format[String] and
      (__ \ "email2").format[String] and
      (__ \ "birth").format[Long] and
      (__ \ "gender").format[String] and
      (__ \ "phone").format[Phone] and
      (__ \ "city").format[String]).tupled

  val someResponseSecondFormat: OFormat[(String, Boolean, Boolean, Long, Long, Boolean, Foo, String, String, String, String)] =
    ((__ \ "zip").format[String] and
      (__ \ "carriage").format[Boolean] and
      (__ \ "carriage2").format[Boolean] and
      (__ \ "fooLong").format[Long] and
      (__ \ "fooLong2").format[Long] and
      (__ \ "suspended").format[Boolean] and
      (__ \ "foo").format[Foo] and
      (__ \ "address").format[String] and
      (__ \ "suite").format[String] and
      (__ \ "country").format[String] and
      (__ \ "instructions").format[String]).tupled

  implicit val formatSome: Format[SomeResponse] = (
    someResponseFirstFormat and someResponseSecondFormat
    ).apply({
    case ((compositeKey, id1, id2, firstName, lastName, email, email2, birth, gender, phone, city),
    (zip, carriage, carriage2, created, updated, suspended, foo, address, suite, country, instructions)) =>
      SomeResponse(compositeKey, id1, id2, firstName, lastName, email, email2, birth, gender, phone, city, zip, carriage, carriage2, created, updated, suspended, location, address, suite, country, instructions)
  }, huge => ((huge.compositeKey, huge.id1, huge.id2, huge.firstName, huge.lastName, huge.email, huge.email2, huge.birth, huge.gender, huge.phone, huge.city),
    (huge.zip, huge.carriage, huge.carriage2, huge.created, huge.updated, huge.suspended, huge.foo, huge.address, huge.suite, huge.country, huge.instructions)))

해결법

  1. ==============================

    1.당신은 당신이 정의를 읽어 분할 할 수 있습니다 :

    당신은 당신이 정의를 읽어 분할 할 수 있습니다 :

    val fields1to10: Reads[(A,B,C,D,E,F,G,H,I,J)] = ???
    val fields11to20 = ???
    val fields21to30 = ???
    
    implicit val hugeCaseClassReads: Reads[HugeCaseClass] = (
      fields1to10 and fields11to20 and fields21to30
    ) { a, b, c => createHugeCaseClassFromThreeTuples(a, b, c) }
    

    22 만까지 정의 된 중간 클래스가 있기 때문에 "기능 구문은"22 개 이상의 필드에 대한 작업을하지 않는 이유는 다음과 같습니다 FunctionalBuilder

    완전히의 모습 작은 예를 들어 기입 :

    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    
    // Let's pretend this is huge:
    case class Huge(a: Int, b: String, c: Boolean, d: List[Int])
    
    val fields1to2: Reads[(Int, String)] = (
      (__ \ "a").read[Int] and
      (__ \ "b").read[String]
    ).tupled
    
    val fields3to4: Reads[(Boolean, List[Int])] = (
      (__ \ "c").read[Boolean] and
      (__ \ "d").read[List[Int]]
    ).tupled
    
    implicit val hugeCaseClassReads: Reads[Huge] = (
      fields1to2 and fields3to4
    ) {
      case ((a, b), (c, d)) =>  
        Huge(a, b, c, d)
    }
    

    그리고 유효성 검사 null로 노력의 결과 :

    scala> JsNull.validate[Huge]
    res6: play.api.libs.json.JsResult[Huge] = JsError(
      List(
        (/b,List(ValidationError(error.path.missing,WrappedArray()))),
        (/d,List(ValidationError(error.path.missing,WrappedArray()))),
        (/c,List(ValidationError(error.path.missing,WrappedArray()))),
        (/a,List(ValidationError(error.path.missing,WrappedArray())))))
    

    당신이 볼 수 있듯이, 모든 필드가 시도됩니다.

    아니면 더 CanBuildNN 클래스와 플레이를 확장 할 수 : https://github.com/playframework/playframework/blob/2.3.6/framework/src/play-functional/src/main/scala/play/api/libs/functional /Products.scala

    그러나 나는 예를 들어 주소 관련 등을 들어, SomeResponse 클래스의 그룹 필드에 당신을 조언 것 그리고 JSON 구조가 평평하고 변경할 수없는 경우, 쓰기, 읽기, 손으로 인스턴스를 작성합니다.

  2. ==============================

    2.컴파일 위의 예를하기 위해, 나는 종류가 명시했습니다 :

    컴파일 위의 예를하기 위해, 나는 종류가 명시했습니다 :

    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    
    // Let's pretend this is huge:
    case class Huge(a: Int, b: String, c: Boolean, d: List[Int])
    
    object Huge {
      val fields1to2: Reads[(Int, String)] = (
        (__ \ "a").read[Int] and
        (__ \ "b").read[String]
      ).tupled
    
      val fields3to4: Reads[(Boolean, List[Int])] = (
        (__ \ "c").read[Boolean] and
        (__ \ "d").read[List[Int]]
      ).tupled
    
      val f: ((Int, String), (Boolean, List[Int])) => Huge = {
        case ((a, b), (c, d)) => Huge(a, b, c, d)
      }
    
      implicit val hugeCaseClassReads: Reads[Huge] = (
        fields1to2 and fields3to4
      ) { f }
    
    }
    
  3. from https://stackoverflow.com/questions/28167971/scala-case-having-22-fields-but-having-issue-with-play-json-in-scala-2-11-5 by cc-by-sa and MIT license