从Scalatra切换到Spray:处理notFound和喷涂中的错误?

时间:2015-02-24 08:22:02

标签: scala servlets spray scalatra

我们是Scalatra用户。每次我们创建一个servlet时,我们都会扩展扩展ScalatraBase的BaseServlet:

    trait BaseServlet extends ScalatraFilter with ScalateSupport with FlashMapSupport  {

      /**
       * Returns the request parameter value for the given argument.
       */
      def getParam(key:String)(implicit request: HttpServletRequest): Option[String] = Option(request.getParameter(key))

      notFound {
        // If no route matches, then try to render a Scaml template
        val templateBase = requestPath match {
          case s if s.endsWith("/") => s + "index"
          case s => s
        }
        val templatePath = "/WEB-INF/templates/" + templateBase + ".scaml"
        servletContext.getResource(templatePath) match {
          case url: URL =>
            contentType = "text/html"
            templateEngine.layout(templatePath)
          case _ =>
            filterChain.doFilter(request, response)
        }
      }

      error {
        case e:ControlThrowable => throw e
        case e:Throwable =>
          val errorUID:String =  UUID.randomUUID.getLeastSignificantBits.abs.toString
          Log.logger(Log.FILE.ALL_EXCEPTIONS).error("#"+ errorUID + " -- " + e.getMessage + e.getStackTraceString)
          contentType = "application/json"
          response.setStatus(500)
          JsonUtility.toJSONString( Map("message" ->  ("Server Error # "+ errorUID  ) ,  "reason" -> e.getMessage ))
      }
}

修改 我想抽象出来。我的意思是我想在我的BaseServlet中添加所有错误和拒绝处理功能,然后扩展它(比如说AnyServlet)。因此,如果AnyServlet具有不合理的路径或在某处抛出异常,它将由BaseServlet自动处理。 Spray中是否有类似的东西能够以类似的方式处理未找到的路径和错误? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

您必须定义自定义的RejectionHandler。

在您的应用程序中,将此RejectionHandler定义为隐式val。

import spray.routing.RejectionHandler

private implicit val notFoundRejectionHandler = RejectionHandler {
  case Nil => {
     // If no route matches, then try to render a Scaml template...
  }
}

我从喷雾github spec

中找到了它

答案 1 :(得分:1)

你不需要"抽象出来"因为在喷涂中你不会有不同的" servlets" - 你只有一条路线,可以拨打其他路线:

class UserRoute {
  val route: Route = ...
}
class DepartmentRoute {
  val route: Route = ...
}
class TopLevelRoute(userRoute: UserRoute, departmentRoute: DepartmentRoute) {
  val route: Route =
    (handleRejections(MyRejHandler) & handleExceptions(MyExHandler)) {
      path("users") {
        userRoute.route
      } ~
      path("departments") {
        departmentRoute.route
      }
    }
}

您可以将处理程序放在TopLevelRoute中,它将应用于UserRoute或DepartmentRoute中的任何内容。喷雾HttpServiceActor仅处理单一路线,而不是一堆不同的控制器" - 由您决定如何将所有路线合并为一条路线。