2014-02-16 4 views
2

그래서 최근에 스칼라를 배우기 시작했습니다. 내 무능력에 미리 죄송합니다.Play2.2.1 프레임 워크에서 Json 스칼라 객체 직렬화

나는 stackoverflow에서 내 대답을 찾으려고했습니다. 몇 가지 관련 주제를 찾을 수 있었지만 문제는 발견하지 못했습니다.

Scala 개체를 기반으로 json 응답을 보내려고합니다. 나는 작업을하고 난하고있어 다음

def oneCredential = Action { 
    val cred = Credential("John", "Temp", "5437437") 
    Ok(Json.toJson(cred)) 
} 

나는 이것을 실행하기 위해 노력하고있어 그

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
import play.api.libs.json.util._ 

case class Credential(name: String, account: String, password: String) 

object Credential{ 
    implicit val credentialWrites = (
    (__ \ "name").write[String] and 
    (__ \ "account").write[String] and 
    (__ \ "password").write[String] 
)(Credential) 
} 

의 경우 클래스와 적절한 암시 글을 T]를 만들었습니다 , 다음과 같은 오류가 발생했습니다 : "오버로드 된 메서드 값 [적용]을 (models.Credential.type)에 적용 할 수 없습니다". 또한 시도했습니다.

implicit val credentialWrites = (
     (__ \ "name").write[String] and 
     (__ \ "account").write[String] and 
     (__ \ "password").write[String] 
)(Credential.apply _) 

실패합니다. 오류가 : 매개 변수 라이닝을위한 암시 적 가치를 찾을 수 없습니다 : play.api.libs.functional.Functor는 [play.api.libs.json.OWrites]

는이 :

implicit val credentialWrites = (
    (__ \ "name").writes[String] and 
    (__ \ "account").writes[String] and 
    (__ \ "password").writes[String] 
)(Credential) 

또 다른 실패 " 값 쓰기는 play.api.libs.json.JsPath의 구성원이 아닙니다. 주 : 암시 적 값인 credentialWrites는 응용 프로그램 포인트 이후에 있으며 명시적인 결과 유형이 없기 때문에 여기에 적용 할 수 없습니다. " 맞습니다. 오류의 첫 부분은 이해했지만 두 번째 부분은 이해하지 못했습니다. 나는 오류가있어 및 코드가 마침내 일이와

implicit val credentialWrites = Json.writes[Credential] 

:

마지막으로 나는 속기 솔루션을 발견했다. 이 해결책은이 blog에 있습니다. 속기 양식은 위의 "쓰기"가있는 것과 정확히 동일하다고합니다. 그러나이 "긴"형태는 나를 위해 작동하지 않았습니다.

긴 형식이 아닌 이유는 속기 버전이 작동하는 이유는 무엇입니까? 누군가가 이것을 설명 할 수 있습니까?

감사합니다.

PS 스칼라 버전 : 2.10.2는

답변

2

당신이 Reads을 위해 일하는 것이 준 정의는하지만, Writes은 마지막 인수의 다른 종류를 필요로한다. 다음 예를 보자

case class Baz(foo: Int, bar: String) 

val r = (__ \ 'foo).read[Int] and (__ \ 'bar).read[String] 
val w = (__ \ 'foo).write[Int] and (__ \ 'bar).write[String] 

rReads[A]를 얻을 수있는 기능 (Int, String) => A에 적용 할 수있는, 다음과 같이 우리가 (이 모두 해당)를 사용할 수 있습니다 의미 : 우리가 '무엇

val bazReader1 = r((foo: Int, bar: String) => Baz(foo, bar)) 
val bazReader2 = r(Baz.apply _) 
val bazReader3 = r(Baz) 

우리가 Reads[Int]Reads[String]에 적용 할 수 있도록이 기능을 응용 프로그램 작성자 Reads으로 옮기고 있습니다.하지만 원하지 않는 경우에는 신경 쓰지 않아도됩니다.

w

이 인수의 다른 종류의 소요 ( Writes이 contravariant 펑 - 그것이이없는 실용적 펑이 있기 때문에 다시를, 당신이 상관 할 필요가 없습니다, 그러나 이것은이다) :

val bazWriter1 = w((b: Baz) => (b.foo, b.bar)) 

우리 다음과 같은 동등이를 작성할 수

val bazWriter2 = w(unlift(Baz.unapply)) 

을 여기에 우리가 Option[(Int, String)] 반환하는 경우 클래스의 자동 생성 추출기, unapply를 사용하고 있습니다. 이 경우 항상 Some을 반환하므로 을 필수 Baz => (Int, String)으로 바꾸려면 unlift (기능적 구문 패키지에서 제공되며 표준 라이브러리의 Function.unlift을 호출)을 사용할 수 있습니다.

마지막 줄을 )(unlift(Credential.unapply))으로 변경하면 가야합니다.

+0

대단히 감사합니다. – Semuserable

관련 문제