How can I programmatically execute Route of rejection handler and get resulting HttpEntity?

僤鯓⒐⒋嵵緔 提交于 2019-12-11 11:58:50

问题


How can I programmatically execute Route of rejection handler and get resulting HttpEntity ?

For example assuming that I have RequestContext object and Rejection object I'd like to execute RejectionHandler.default on it and get HttpEntity.

Here is example of what I'd like to do:

implicit def myRejectionHandler =
  RejectionHandler.newBuilder()
    .handleAll[Rejection] { rejections ⇒

    def prefixEntity(entity: ResponseEntity): ResponseEntity = entity match {
      case HttpEntity.Strict(contentType, data) => {
        import spray.json._
        val text = ErrorResponse(0, "Rejection", data.utf8String).toJson.prettyPrint
        HttpEntity(ContentTypes.`application/json`, text)
      }
      case _ =>
        throw new IllegalStateException("Unexpected entity type")
    }

    val route: Route = extractRequestContext { ctx =>
      mapResponseEntity(prefixEntity) {
        // Here I want result of `complete` route from RejectionHandler.default
      }
    }
    route
  }
    .handleNotFound {
      complete((NotFound, "Not here!"))
    }
    .result()

回答1:


I think I get the gist of what you want. You can just apply the default rejection handler in there where your comment is. The only thing is that the apply there returns an Option that will be None if the rejections encountered don't hit on anything in that rejection handler. This is unlikely given that you are using the default handler and it pretty much handles everything, but you still need to account for it in the code (hence my getOrElse that results in a generic InternalServerError). The modified code would look like this:

val defaultRejectionHandler = RejectionHandler.default

implicit def myRejectionHandler =
  RejectionHandler.newBuilder()
    .handleAll[Rejection] { rejections ⇒

    def prefixEntity(entity: ResponseEntity): ResponseEntity = entity match {
      case HttpEntity.Strict(contentType, data) => {
        import spray.json._
        val text = ErrorResponse(0, "Rejection", data.utf8String).toJson.prettyPrint
        HttpEntity(ContentTypes.`application/json`, text)
      }
      case _ =>
        throw new IllegalStateException("Unexpected entity type")
    }

    val route: Route = extractRequestContext { ctx =>
      mapResponseEntity(prefixEntity) {
        defaultRejectionHandler.apply(rejections).getOrElse{
          complete(StatusCodes.InternalServerError)
        }
      }
    }
    route
  }
  .handleNotFound {
    complete((NotFound, "Not here!"))
  }
  .result()

This compiles, but I did not actually test it to see if we get the desired effect. Also, I didn't need the RequestContext value ctx, so you might be able to remove that extractRequestContext layer in there.



来源:https://stackoverflow.com/questions/34924463/how-can-i-programmatically-execute-route-of-rejection-handler-and-get-resulting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!