[英]Rendering JSON with Play! and Scala
I have a simple question regarding rendering JSON object from a Scala class. 我有一个关于从Scala类渲染JSON对象的简单问题。 Why do I have to implemet deserializer ( read, write ). 为什么我必须实现反序列化器(读,写)。
I have the following case class: 我有以下案例类:
case class User(firstname:String, lastname:String, age:Int)
And in my controller: 在我的控制器中:
val milo:User = new User("Sam","Fisher",23);
Json.toJson(milo);
I get compilation error: No Json deserializer found for type models.User. 我得到编译错误:找不到类型models.User的Json反序列化器。 Try to implement an implicit Writes or Format for this type. 尝试为此类型实现隐式写入或格式。
In my previous project I had to implement a reader,writer object in the class for it to work and I find it very annoying. 在我以前的项目中,我必须在类中实现一个reader,writer对象才能工作,我发现它非常烦人。
object UserWebsite {
implicit object UserWebsiteReads extends Format[UserWebsite] {
def reads(json: JsValue) = UserWebsite(
(json \ "email").as[String],
(json \ "url").as[String],
(json \ "imageurl").as[String])
def writes(ts: UserWebsite) = JsObject(Seq(
"email" -> JsString(ts.email),
"url" -> JsString(ts.url),
"imageurl" -> JsString(ts.imageurl)))
}
}
I really recommend to upgrade to play 2.1-RC1 because here, JSON writers/readers are very simple to be defined (more details here ) 我真的建议升级到2.1-RC1,因为在这里,JSON编写器/阅读器很容易定义(更多细节在这里 )
But in order to help you to avoid some errors, I will give you a hint with imports: - use these imports only! 但是为了帮助你避免一些错误,我会给你一个进口提示: - 只使用这些进口! (notice that json.Reads is not included) (注意不包括json.Reads)
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Writes._
and you only have to write this code for write/read your class to/from Json (of course you will have User
instead of Address
: 你只需编写这段代码就可以在Json中写入/读取你的类(当然你会有User
而不是Address
:
implicit val addressWrites = Json.writes[Address]
implicit val addressReads = Json.reads[Address]
Now, they will be used automatically: 现在,它们将自动使用:
Example of write : 写的例子:
Ok(Json.toJson(entities.map(s => Json.toJson(s))))
Example of read (I put my example of doing POST for creating an entity by reading json from body) please notice addressReads
used here 阅读的例子(我把我的例子用于通过从身体读取json来创建实体)请注意addressReads
使用的addressReads
def create = Action(parse.json) { request =>
request.body.validate(addressReads).map { entity =>
Addresses.insert(entity)
Ok(RestResponses.toJson(RestResponse(OK, "Succesfully created a new entity.")))
}.recover { Result =>
BadRequest(RestResponses.toJson(RestResponse(BAD_REQUEST, "Unable to transform JSON body to entity.")))
}
}
In conclusion, they tried (and succeded) to make things very simple regarding JSON. 总之,他们尝试(并成功)使JSON的事情变得非常简单。
If you are using play 2.0.x you can do 如果你使用的是Play 2.0.x,你可以这样做
import com.codahale.jerkson.Json._
generate(milo)
generate uses reflection to do it. 生成使用反射来做到这一点。
In play 2.1 you can use Json.writes to create a macro for that implicit object you had to create. 在Play 2.1中,您可以使用Json.writes为您必须创建的隐式对象创建一个宏。 No runtime reflection needed! 无需运行时反射!
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val userWrites = Json.writes[User]
Json.toJson(milo)
I have been using jerkson (which basically is wrapper to jackson) in my project to convert objects to json string. 我一直在我的项目中使用jerkson(基本上是jackson的包装器)将对象转换为json字符串。
The simplest way to do that is: 最简单的方法是:
import com.codehale.jerkson.Json._
...
generate(milo)
...
If you need to configure the ObjectMapper (eg adding custom serializer/deserializer, configuring output format, etc.), you can do it by creating object which extends com.codehale.jerkson.Json
class. 如果需要配置ObjectMapper(例如添加自定义序列化器/解串器,配置输出格式等),可以通过创建扩展com.codehale.jerkson.Json
类的对象来com.codehale.jerkson.Json
。
package utils
import org.codehaus.jackson.map._
import org.codehaus.jackson.{Version, JsonGenerator, JsonParser}
import com.codahale.jerkson.Json
import org.codehaus.jackson.map.module.SimpleModule
import org.codehaus.jackson.map.annotate.JsonSerialize
object CustomJson extends Json {
val module = new SimpleModule("CustomSerializer", Version.unknownVersion())
// --- (SERIALIZERS) ---
// Example:
// module.addSerializer(classOf[Enumeration#Value], EnumerationSerializer)
// --- (DESERIALIZERS) ---
// Example:
// module.addDeserializer(classOf[MyEnumType], new EnumerationDeserializer[MyEnumType](MyEnumTypes))
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL)
mapper.setSerializationConfig(mapper.getSerializationConfig.without(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES))
mapper.registerModule(module)
}
To use it in your codes: 要在您的代码中使用它:
import utils.CustomJson._
...
generate(milo)
...
In fact, this is very simple. 实际上,这很简单。 Firstly import: 首先导入:
import play.api.libs.json._
Thanks to the fact, that User is a case class you can automatically create Json writes using Json.writes[]: 由于事实,User是一个案例类,您可以使用Json.writes []自动创建Json写入:
val milo:User = new User("Millad","Dagdoni",23)
implicit val userImplicitWrites = Json.writes[User]
Json.toJson(milo)
I haven't found it in the docs, but here is the link to the api: http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json.Json $ 我没有在文档中找到它,但这里是api的链接: http : //www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.libs.json杰森 $
In your case, I'd use the JSON.format macro. 在您的情况下,我将使用JSON.format宏。
import play.api.libs.json._
implicit val userFormat = Json.format[User]
val milo = new User("Sam", "Fisher", 23)
val json = Json.toJson(milo)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.