没有 play.api.libs.json.Format 的实例可用于 akka.actor.typed.ActorRef[org.knoldus.eventSourcing.UserState.Confirmation]
No instance of play.api.libs.json.Format is available for akka.actor.typed.ActorRef[org.knoldus.eventSourcing.UserState.Confirmation]
No instance of play.api.libs.json.Format is available for akka.actor.typed.ActorRef[org.knoldus.eventSourcing.UserState.Confirmation] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
[error] implicit val userCommand: Format[AddUserCommand] = Json.format
即使我为 AddUserCommand
.
创建了 Json Format
的隐式实例,我仍然收到此错误
这是我的代码:
trait UserCommand extends CommandSerializable
object AddUserCommand{
implicit val format: Format[AddUserCommand] = Json.format[AddUserCommand]
}
final case class AddUserCommand(user:User, reply: ActorRef[Confirmation]) extends UserCommand
谁能帮我解决这个错误以及如何解决它?
错误说它无法为 AddUserCommand
构造一个 Format
因为 ActorRef[Confirmation]
没有 Format
。
使用 Json.format[X]
时,案例 class X
的所有成员都必须定义 Format
。
在您的情况下,您可能不想为这种情况定义格式化程序 class(序列化 ActorRef
没有多大意义)而是构建另一种情况 class 只有数据。
编辑:如果您真的想向那里发送演员参考,请参阅 Levi 关于如何为 ActorRef
提供格式化程序的回答。
正如 Gael 指出的那样,您需要为 ActorRef[Confirmation]
提供 Format
。复杂的是,使用 the ActorRefResolver 的自然序列化要求存在 ExtendedActorSystem
,这意味着在伴随对象中定义 Format
的通常方法将无法正常工作.
请注意,由于 Lagom 进行依赖注入的方式,this approach doesn't really work in Lagom: commands in Lagom basically can't use Play JSON。
import akka.actor.typed.scaladsl.adapter.ClassicActorSystemOps
import play.api.libs.json._
class PlayJsonActorRefFormat(system: ExtendedActorSystem) {
def reads[A] = new Reads[ActorRef[A]] {
def reads(jsv: JsValue): JsResult[ActorRef[A]] =
jsv match {
case JsString(s) => JsSuccess(ActorRefResolver(system.toTyped).resolveActorRef(s))
case _ => JsError(Seq(JsPath() -> Seq(JsonValidationError(Seq("ActorRefs are strings"))))) // hopefully parenthesized that right...
}
}
def writes[A] = new Writes[ActorRef[A]] {
def writes(a: ActorRef[A]): JsValue = JsString(ActorRefResolver(system.toTyped).toSerializationFormat(a))
}
def format[A] = Format[ActorRef[A]](reads, writes)
}
然后您可以将 AddUserCommand
的格式定义为
object AddUserCommand {
def format(arf: PlayJsonActorRefFormat): Format[AddUserCommand] = {
implicit def arfmt[A]: Format[ActorRef[A]] = arf.format
Json.format[AddUserCommand]
}
}
因为你可能使用 JSON 来序列化围绕集群发送的消息(否则,ActorRef
不应该像这样泄漏),你将构造一个实例Akka Serializer 实现中的格式。
(注意:我只用 Circe 做过这个,没有用 Play JSON,但基本方法很常见)
No instance of play.api.libs.json.Format is available for akka.actor.typed.ActorRef[org.knoldus.eventSourcing.UserState.Confirmation] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
[error] implicit val userCommand: Format[AddUserCommand] = Json.format
即使我为 AddUserCommand
.
Format
的隐式实例,我仍然收到此错误
这是我的代码:
trait UserCommand extends CommandSerializable
object AddUserCommand{
implicit val format: Format[AddUserCommand] = Json.format[AddUserCommand]
}
final case class AddUserCommand(user:User, reply: ActorRef[Confirmation]) extends UserCommand
谁能帮我解决这个错误以及如何解决它?
错误说它无法为 AddUserCommand
构造一个 Format
因为 ActorRef[Confirmation]
没有 Format
。
使用 Json.format[X]
时,案例 class X
的所有成员都必须定义 Format
。
在您的情况下,您可能不想为这种情况定义格式化程序 class(序列化 ActorRef
没有多大意义)而是构建另一种情况 class 只有数据。
编辑:如果您真的想向那里发送演员参考,请参阅 Levi 关于如何为 ActorRef
提供格式化程序的回答。
正如 Gael 指出的那样,您需要为 ActorRef[Confirmation]
提供 Format
。复杂的是,使用 the ActorRefResolver 的自然序列化要求存在 ExtendedActorSystem
,这意味着在伴随对象中定义 Format
的通常方法将无法正常工作.
请注意,由于 Lagom 进行依赖注入的方式,this approach doesn't really work in Lagom: commands in Lagom basically can't use Play JSON。
import akka.actor.typed.scaladsl.adapter.ClassicActorSystemOps
import play.api.libs.json._
class PlayJsonActorRefFormat(system: ExtendedActorSystem) {
def reads[A] = new Reads[ActorRef[A]] {
def reads(jsv: JsValue): JsResult[ActorRef[A]] =
jsv match {
case JsString(s) => JsSuccess(ActorRefResolver(system.toTyped).resolveActorRef(s))
case _ => JsError(Seq(JsPath() -> Seq(JsonValidationError(Seq("ActorRefs are strings"))))) // hopefully parenthesized that right...
}
}
def writes[A] = new Writes[ActorRef[A]] {
def writes(a: ActorRef[A]): JsValue = JsString(ActorRefResolver(system.toTyped).toSerializationFormat(a))
}
def format[A] = Format[ActorRef[A]](reads, writes)
}
然后您可以将 AddUserCommand
的格式定义为
object AddUserCommand {
def format(arf: PlayJsonActorRefFormat): Format[AddUserCommand] = {
implicit def arfmt[A]: Format[ActorRef[A]] = arf.format
Json.format[AddUserCommand]
}
}
因为你可能使用 JSON 来序列化围绕集群发送的消息(否则,ActorRef
不应该像这样泄漏),你将构造一个实例Akka Serializer 实现中的格式。
(注意:我只用 Circe 做过这个,没有用 Play JSON,但基本方法很常见)