首页 > 解决方案 > Java 可选:映射到子类或超类

问题描述

我正在尝试从 Manning 在 Java 中的“Akka in Action”中重写一个 POC 项目的 scala 示例。该项目是一个用于创建活动和购买门票的小型 Http 服务器。

我正处于演员可以向Optional<Event>我的RestApi. 根据该值是否存在,我应该使用OK, else来完成调用NOT_FOUND

在 Scala 中,代码片段如下所示:

      get {
          // GET /events/:event
          onSuccess(getEvent(event)) {
            _.fold(complete(NotFound))(e => complete(OK, e))
          }
        }

... wheregetEvent返回一个Option[Event](相当于 java 的Optional<Event>)。这就是我用Java重写它的方式:

   get(() -> onSuccess(() -> getEvent(event), eventGetRoute()))

   ...
    //and eventGetRoute() is a function:
    private Function<Optional<Event>, Route> eventGetRoute() {
        return maybeEvent -> maybeEvent.map(event -> complete(OK, event, Jackson.marshaller())).orElseGet(() -> complete(NOT_FOUND));
    }

这不编译:Bad return type in lambda expression: Route cannot be converted to RouteAdapter。较长的(和第一个)complete返回 a RouteAdapter,第二个返回 a Route。如果我像这样重写上面的函数:

private Function<Optional<Event>, Route> eventGetRoute() {
    return maybeEvent -> {
        if(maybeEvent.isPresent()) {
            return complete(OK, maybeEvent.get(), Jackson.marshaller());
        }
        return complete(NOT_FOUND);
    };
}

...然后编译器不会抱怨,但是映射 Optional 不是正确的方法。

Java 没有foldOptional 的方法(至少在 SE8 中没有),它允许首先传递 fallback-to 值。

我很好奇是否可以在尊重功能风格的情况下编写此功能。

更新

正如评论中所问的,这些是javadsl 库中complete方法的签名:akka-http

  def complete(status: StatusCode): Route = RouteAdapter(
    D.complete(status.asScala))

  def complete[T](status: StatusCode, value: T, marshaller: Marshaller[T, RequestEntity]) = RouteAdapter {
    D.complete(ToResponseMarshallable(value)(fromToEntityMarshaller(status.asScala)(marshaller)))
  }

标签: javascalaakkaoptionalakka-http

解决方案


什么是返回类型complete(OK, maybeEvent.get(), Jackson.marshaller())

我假设RouteAdapter。如果是这样,将其转换为Route这样的链将被绑定到RouteRouteAdaper,并且最终不会遇到从超类到子类的转换问题。


推荐阅读