Reputation: 467
We were Scalatra users. Everytime we would create a servlet , we would extend our BaseServlet which extend ScalatraBase :
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 ))
}
}
EDIT: I want to abstract it out. I mean I want to add all the error and rejection handling functionalities in my BaseServlet and then extend it ( in say AnyServlet) . So if AnyServlet has an unfound path or has an exception thrown somewhere it is automatically handled by the BaseServlet. Is there something similar in Spray which can handle my paths not found and errors in a similar fashion? Thanks in advance!
Upvotes: 2
Views: 375
Reputation: 17431
You don't need to "abstract it out" because in spray you don't have distinct "servlets" - you just have a route, which may call other routes:
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
}
}
}
You can put the handler in TopLevelRoute and it will apply to anything in UserRoute or DepartmentRoute. A spray HttpServiceActor
only handles a single route, not a bunch of different "controllers" - it's up to you how you combine all your routes into a single route.
Upvotes: 1
Reputation: 4382
You have to define a custom RejectionHandler.
In your application define this RejectionHandler as an implicit val.
import spray.routing.RejectionHandler
private implicit val notFoundRejectionHandler = RejectionHandler {
case Nil => {
// If no route matches, then try to render a Scaml template...
}
}
I figured it out from the spray github spec
Upvotes: 1