[英]How do I exclude values when doing json Reads and Writes in my Play2 scala application
I'm browsing through: http://www.playframework.com/documentation/2.1.1/ScalaJsonCombinators and searching for how to exclude values when doing reads and writes. 我正在浏览: http : //www.playframework.com/documentation/2.1.1/ScalaJsonCombinators并搜索在执行读写操作时如何排除值。 Its probably there but I can't find it.
它可能在那里,但我找不到它。
So let say I have a case class Booking that have bunch of params, a creationTime and bookingId . 所以,假设我有一个案例类预订,有一堆参数,一个creationTime和bookingId 。 When writing from the object to Json I would like to write all the params But when reading the object from Json eg when a POST is made to creatingBooking in my controller:
当从对象写入Json时,我想编写所有参数但是当从Json读取对象时,例如当在我的控制器中创建POST时:
def createBooking = Action(parse.json) {
implicit request => {
request.body.validate[Booking].map {
case (booking) => {
Logger.info("" + booking)
Ok("ONLY TEST")
}
}.recoverTotal {
e => BadRequest("Detected error:" + JsError.toFlatJson(e))
}
}
}
I do not want to provide the values creationTime and bookingId in the Json POST and I do not want to read the values with my Reads impl: 我不想在Json POST中提供值creationTime和bookingId ,我不想用我的Reads impl读取值:
package models.booking
import java.util.UUID
import org.joda.time.{DateTime}
import play.api.libs.functional.syntax._
import play.api.libs.json._
case class Booking (bookingId: UUID,
rId: Long,
creationTime: DateTime,
user: User,
dateTime: BookingTime,
numOfGuest: Int,
status: BookingState.BookingState) {
def accepted(): Booking = {
this.copy(status = BookingState.ACCEPTED)
}
def sent(): Booking = {
this.copy(status = BookingState.SENT)
}
def denied(): Booking = {
this.copy(status = BookingState.DENIED)
}
def denyWithNewTimeSuggestion(): Booking = {
this.copy(status = BookingState.DENIED_NEW_TIME_SUGGESTED)
}
def timeout(): Booking = {
this.copy(status = BookingState.TIMED_OUT)
}
def sendOnOpening(): Booking = {
this.copy(status = BookingState.ON_HOLD)
}
}
object Booking {
implicit object UUIDFormat extends Format[UUID] {
def writes(uuid: UUID): JsValue = JsString(uuid.toString())
def reads(json: JsValue): JsResult[UUID] = json match {
case JsString(x) => JsSuccess(UUID.fromString(x))
case _ => JsError("Expected UUID as JsString")
}
}
val pattern = "yyyy-M-dd"
implicit val dateFormat =
Format[DateTime](Reads.jodaDateReads(pattern), Writes.jodaDateWrites(pattern))
import utils.EnumUtils.enumReads
implicit val bookingStateReads = enumReads(BookingState)
import play.api.libs.json.Reads._
implicit val bookingReads: Reads[Booking] = (
(__ \ "bookingId").read[UUID] and
(__ \ "rId").read[Long] and
(__ \ "creationTime").read[DateTime] and
(__ \ "user").read[User] and
(__ \ "dateTime").read[BookingTime] and
(__ \ "numOfGuest").read[Int] and
(__ \ "status").read[BookingState.BookingState]
)(Booking.apply _)
import utils.EnumUtils.enumWrites
import play.api.libs.json.Writes._
implicit val bookingWrites: Writes[Booking] = (
(__ \ "bookingId").write[UUID] and
(__ \ "rId").write[Long] and
(__ \ "creationTime").write[DateTime] and
(__ \ "user").write[User] and
(__ \ "dateTime").write[BookingTime] and
(__ \ "numOfGuest").write[Int] and
(__ \ "status").write[BookingState.BookingState]
)(unlift(Booking.unapply))
}
object BookingState extends Enumeration {
type BookingState = Value
val NEW = Value("NEW")
val SENT = Value("SENT")
val ACCEPTED = Value("ACCEPTED")
val DENIED = Value("DENIED")
val DENIED_NEW_TIME_SUGGESTED = Value("DENIED_NEW_TIME_SUGGESTED")
val TIMED_OUT = Value("TIMED_OUT")
val ON_HOLD = Value("ON_HOLD")
}
How do I specify a customBookingReads
that excludes the values bookingId and creationTime . 如何指定
customBookingReads
排除值bookingId和创建时间 。 I also want to keep the original 'bookingReads' so that I can use that for other things. 我还想保留原来的'bookingReads',以便我可以将其用于其他事情。
After some soul searching I realised that in this case the Booking and the Request is actually two different things, therefore I shouldn't try mixing those two. 经过一番深思熟虑,我意识到在这种情况下,预订和请求实际上是两个不同的东西,因此我不应该尝试将这两个混合起来。
I created a BookingRequest from which a Booking could be created. 我创建了一个BookingRequest,可以从中创建预订。
BookingRequest: 预约申请:
case class BookingRequest(rId: Long,
user: User,
bookingTime: BookingTime,
numOfGuest: Int) {
def createBooking(): Booking = {
Booking(UUID.randomUUID(), this.rId, new DateTime(), this.user, this.bookingTime, this.numOfGuest, BookingState.NEW)
}
}
object BookingRequest {
import play.api.libs.json.Reads._
implicit val bookingRequestReads: Reads[BookingRequest] = (
(__ \ "rId").read[Long] and
(__ \ "user").read[User] and
(__ \ "bookingTime").read[BookingTime] and
(__ \ "numOfGuest").read[Int]
)(BookingRequest.apply _)
import play.api.libs.json.Writes._
implicit val bookingRequestWrites: Writes[BookingRequest] = (
(__ \ "rId").write[Long] and
(__ \ "user").write[User] and
(__ \ "bookingTime").write[BookingTime] and
(__ \ "numOfGuest").write[Int]
)(unlift(BookingRequest.unapply))
}
Controller: 控制器:
def createBooking = Action(parse.json) {
implicit request => {
request.body.validate[BookingRequest].map {
case (bookingRequest) => {
Logger.info("Booking" + bookingRequest)
Logger.info("BookingRequest" + bookingRequest.createBooking())
// SAVE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Ok(Json.obj("status" -> "OK"))
}
}.recoverTotal {
e => BadRequest(Json.obj("status" ->"KO", "message" -> JsError.toFlatJson(e)))
}
}
}
But I'm still curious how to exclude values when doing Reads and Writes 但我仍然很好奇如何在执行读取和写入时排除值
I think the most straightforward way of getting what you want is to make the bookingId
and creationTime
fields Option
s. 我认为获得所需内容的最简单方法是制作
bookingId
和creationTime
字段Option
。
case class Booking (bookingId: Option[UUID],
rId: Long,
creationTime: Option[DateTime],
user: User,
dateTime: BookingTime,
numOfGuest: Int,
status: BookingState.BookingState)
This way your reads
can still try to read those fields, but if they're missing they'll just be None
. 这样你的
reads
仍然可以尝试读取这些字段,但如果它们丢失,它们将只是None
。 I do this exact thing and it works well, even with a standard Json.format[Booking]
-- no custom code required. 即使使用标准的
Json.format[Booking]
,我也可以做到这一点并且效果很好 - 不需要自定义代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.