1

암시 기록 기능 컨버터와 JSON으로 중첩 된 객체를 직렬화 :프레임 워크 2.3 스칼라 재생 - 나는 프론트 엔드 JQuery와 구성 요소에 대한이 (아약스 응답)과 같은 특정 JSON 객체가 필요

[ 
    {"division":"IT", "contacts":[ 
     {“firstname”:”Carl”, “surname”:”Smith”, “empID”:1}, 
     {“firstname”:”Henry”, “surname”:”Miller”, “empID”:2} 
]}, 
    {"division":"Sales", "contacts":[ 
     {“firstname”:”Nancy”, “surname”:”McDonald”, “empID”:3}, 
     {“firstname”:”Susan”, “surname”:”McBright”, “empID”:4} 
]} 
] 

백엔드에서 데이터를 통해 읽기를 anorm (MySQL의) 및 다음 개체의 변형은 :

List(Map("division" -> "IT", "contacts" -> List(c3,c4)), Map("division" -> "Sales",   "contacts" -> List(c3,c4))) 

는 그럼 난 (암시 적 기록 기능 컨버터 포함) JSON으로하지만 성공하지 개체를 직렬화하려고합니다. 나는 같은 방식으로 단순화 된 테스트 케이스 아이디어 - 워크 시트를 만들어 아래 : 스크립트의 끝에서

import play.api.libs.json.{JsValue, Json, Writes} 

case class Contact(firstname: String, surname: String, empID: Option[Int]) 

case class ContactDivisionList(division: String, contacts: Seq[Contact]) 

implicit val ctWrites = new Writes[Contact] { 
    def writes(ct: Contact) = Json.obj(
    "firstname" -> ct.firstname, 
    "surname" -> ct.surname, 
    "empid" -> ct.empID 
) 
} 

implicit val sdlWrites = new Writes[ContactDivisionList] { 
    def writes(dlist: ContactDivisionList) = Json.obj(
    "division" -> dlist.division, 
    "contacts" -> Json.toJson(dlist.contacts) 
) 
} 


/* 
Example 
*/ 
val c1 = Contact("Carl","Smith",Option(1)) 
val c2 = Contact("Henry","Miller",Option(2)) 
val c3 = Contact("Nancy","McDonald",Option(3)) 
val c4 = Contact("Susan","McBright",Option(4)) 

//Test case 1 ->OK 
Json.toJson(List(c1,c2,c3,c4)) 

//Test case 2 ->OK 
val c_comp1=List(Map("contacts" -> List(c1,c2)),Map("contacts" -> List(c3,c4))) 
//RESULT --> c_comp1: List[scala.collection.immutable.Map[String,List[Contact]]] =  List(Map(contacts -> List(Contact(Carl,Smith,Some(1)), Contact(Henry,Miller,Some(2)))), Map(contacts -> List(Contact(Nancy,McDonald,Some(3)), Contact(Susan,McBright,Some(4))))) 
Json.toJson(c_comp1) 
//res1: play.api.libs.json.JsValue = [{"contacts": [{"firstname":"Carl","surname":"Smith","empid":1},{"firstname":"Henry","surname":"Miller","empid":2}]},{"contacts":[{"firstname":"Nancy","surname":"McDonald","empid":3},{"firstname":"Susan","surname":"McBright","empid":4}]}] 


//Test case 3 ->Fail!!! 
val c_comp2 = List(Map("division" -> "IT", "contacts" -> List(c1,c2)),Map("division" -> "Sales", "contacts" -> List(c3,c4))) 
//sdlWrites: play.api.libs.json.Writes[ContactDivisionList]{def writes(dlist: ContactDivisionList): play.api.libs.json.JsObject} = [email protected] 

Json.toJson(c_comp2) 
//!!!!!Error messages 
/*Error:(39, 13) No Json serializer found for type  List[scala.collection.immutable.Map[String,java.io.Serializable]]. Try to implement an implicit Writes or Format for this type. 
Json.toJson(c_comp2) 
^ 

Error:(39, 13) not enough arguments for method toJson: (implicit tjs: play.api.libs.json.Writes[List[scala.collection.immutable.Map[String,java.io.Serializable]] ])play.api.libs.json.JsValue. 
Unspecified value parameter tjs. 
Json.toJson(c_comp2) 
^ 
*/ 

당신은 내가 Json.toJson (c_comp2)을 실행 오류가있어 "테스트 케이스 (3)"을 볼 수 있습니다 - -> "No Json serializer가 유형에 대해 발견되었습니다." 나는 많은 것을 시도하지만 나는 올바르게하지 않습니다. 성공적인 "테스트 케이스 2"의 유일한 차이점은 String-Tuppel을 사용하여 Map을 확장한다는 것입니다. 내가 sombody 그 문제를 도와 줄 수 있기를 바랍니다

, 들으

안부 카르 스텐

+0

감사합니다.하지만 제안 된 사례 클래스 ContactGroup과 스크립트 "ContactDivisionList"의 사례 클래스간에 차이가 있습니까? – smith

답변

1

귀하의 문제이다 Map 당신은 매핑 StringString 최소한의 상한에있다가 (당신의 부서 이름이)이고 List[Contact]인데, 이는 java.io.Serializable입니다.

scala> case class Contact(firstname: String, surname: String, empID: Option[Int]) 
defined class Contact 

scala> case class ContactDivisionList(division: String, contacts: Seq[Contact]) 
defined class ContactDivisionList 

scala> val c1 = Contact("Carl","Smith",Option(1)) 
c1: Contact = Contact(Carl,Smith,Some(1)) 

scala> val c2 = Contact("Henry","Miller",Option(2)) 
c2: Contact = Contact(Henry,Miller,Some(2)) 

scala> val c3 = Contact("Nancy","McDonald",Option(3)) 
c3: Contact = Contact(Nancy,McDonald,Some(3)) 

scala> val c4 = Contact("Susan","McBright",Option(4)) 
c4: Contact = Contact(Susan,McBright,Some(4)) 

scala> Map("division" -> "IT", "contacts" -> List(c1,c2)) 
res10: scala.collection.immutable.Map[String,java.io.Serializable] = Map(division -> IT, contacts -> List(Contact(Carl,Smith,Some(1)), Contact(Henry,Miller,Some(2)))) 

나는 문제의 본질 완전히 확실하지 않다,하지만 당신은 이미 List[ContactDivisionList]이있는 경우, 그것은 JSON에 그 직렬화 매우 간단합니다 :

scala> implicit val contactWrites = Json.writes[Contact] 
contactWrites: play.api.libs.json.OWrites[Contact] = [email protected] 

scala> implicit val contactDivisionListWrites = Json.writes[ContactDivisionList] 
contactDivisionListWrites: play.api.libs.json.OWrites[ContactDivisionList] = [email protected] 

scala> Json.toJson(List(ContactDivisionList("IT", List(c1,c2)), ContactDivisionList("Sales", List(c3, c4)))) 
res2: play.api.libs.json.JsValue = [{"division":"IT","contacts":[{"firstname":"Carl","surname":"Smith","empID":1},{"firstname":"Henry","surname":"Miller","empID":2}]},{"division":"Sales","contacts":[{"firstname":"Nancy","surname":"McDonald","empID":3},{"firstname":"Susan","surname":"McBright","empID":4}]}] 

당신이 피해야 나에게 보인다 처음에는 Map입니다. 나는 이전에 아무렇지도 않게 작업 해본 적이 없지만, 내가 바라는 부분은 데이터 구조의 코드입니다. 그 시점에서 유형 안전성을 잃어 버렸기 때문입니다. 이상적으로는 ContactDivisionList으로 작업하거나 JsValue 사례를 직접 사용하여 개체를 구성해야합니다.