【问题标题】:Akka HTTP API service with file upload extractRequestContext and case class at a time?一次带有文件上传extractRequestContext和案例类的Akka HTTP API服务?
【发布时间】:2018-02-20 07:21:21
【问题描述】:

如何编写带有文件上传和案例类的 Akka HTTP 服务来接受来自前端的输入请求?我有两个服务,比如

     val upload1 = path("api" / "upload1") {
    extractClientIP {
      ip =>
        optionalHeaderValueByName(Constants.AUTH) {
          auths =>
            (post & extractRequestContext) { request =>
              // functionality
            }
        }
    }
  }

  val upload2= path("api" / "upload2") {
    extractClientIP {
      ip =>
        optionalHeaderValueByName(Constants.AUTH) {
          auths =>
            (post & entity(as[Create])) { create =>
              // functionality
            }
        }
    }
  }

我需要将以上两个 API 合并到一个请求调用中,而不是两个请求调用,我该如何实现这一点,我已经尝试如下但它不起作用

 val upload1 = path("api" / "upload1") {
    extractClientIP {
      ip =>
        optionalHeaderValueByName(Constants.AUTH) {
          auths =>
            (post & extractRequestContext & entity(as[Create]) { request =>
              // functionality
            }
        }
    }
  }

我遇到了缺少参数类型问题

我在使用时遇到了问题

(post & extractRequestContext & entity(as[String])) { (requestContext, create) =>
              // do stuff
              complete("ok")
            }

    ERROR akka.actor.ActorSystemImpl - Error during processing of request: 'Substream Source cannot be materialized more than once'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.
java.lang.IllegalStateException: Substream Source cannot be materialized more than once
    at akka.stream.impl.fusing.SubSource$$anon$4.setCB(StreamOfStreams.scala:725) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.SubSource$$anon$4.preStart(StreamOfStreams.scala:735) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.GraphInterpreter.init(GraphInterpreter.scala:520) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.GraphInterpreterShell.init(ActorGraphInterpreter.scala:380) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.ActorGraphInterpreter.tryInit(ActorGraphInterpreter.scala:538) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.ActorGraphInterpreter.preStart(ActorGraphInterpreter.scala:586) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.actor.Actor$class.aroundPreStart(Actor.scala:510) ~[akka-actor_2.11-2.4.19.jar:na]
    at akka.stream.impl.fusing.ActorGraphInterpreter.aroundPreStart(ActorGraphInterpreter.scala:529) ~[akka-stream_2.11-2.4.19.jar:na]
    at akka.actor.ActorCell.create(ActorCell.scala:590) ~[akka-actor_2.11-2.4.19.jar:na]
    at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:461) ~[akka-actor_2.11-2.4.19.jar:na]
    at akka.actor.ActorCell.systemInvoke(ActorCell.scala:483) ~[akka-actor_2.11-2.4.19.jar:na]
    at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282) [akka-actor_2.11-2.4.19.jar:na]
    at akka.dispatch.Mailbox.run(Mailbox.scala:223) [akka-actor_2.11-2.4.19.jar:na]
    at akka.dispatch.Mailbox.exec(Mailbox.scala:234) [akka-actor_2.11-2.4.19.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.11.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.11.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.11.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.11.jar:na]

【问题讨论】:

    标签: scala file-upload akka akka-http


    【解决方案1】:

    如果您使用 & 运算符组合两个指令,您将获得一个包含 所有提取 值的元组,这些值来自 所有您的指令,以完成您的路线。

    在您的情况下,您将连接 2 个指令,每个指令提取 1 个值(extractRequestContextentity(as[Create])),以及一个不提取参数的指令(post)。因此,您需要从 2 个参数(RequestContextCreate)为您的路线提供一个函数。

      val upload1 = path("api" / "upload1") {
        extractClientIP {
          ip =>
            optionalHeaderValueByName("tmp") {
              auths =>
                (post & extractRequestContext & entity(as[String])) { (requestContext, create) =>
                  // do stuff
                  complete("ok")
                }
            }
        }
      }
    

    【讨论】:

    • 当我尝试使用您的解决方案时,我得到了Error during processing of request: 'Substream Source cannot be materialized more than once'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler. java.lang.IllegalStateException: Substream Source cannot be materialized more than once。我已经更新了我的问题,请再次参考
    猜你喜欢
    • 2016-11-14
    • 2015-12-31
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多