@ Override protected void handleRequest ( RequestContext context ) throws ServletException , IOException { // for exceptions generated before response commit uses HttpServletResponse.sendError // on send error, servlet container prepares error response using container internal HTML for response body // if <error-page> is configured into deployment descriptor servlet container uses that HTML for response body final HttpServletRequest httpRequest = context . getRequest ( ) ; final HttpServletResponse httpResponse = context . getResponse ( ) ; ArgumentsReader argumentsReader = null ; Resource resource = null ; try { ManagedMethodSPI method = resourceMethods . get ( key ( context . getRequestPath ( ) ) ) ; if ( method == null ) { throw new NoSuchMethodException ( httpRequest . getRequestURI ( ) ) ; } final Type [ ] formalParameters = method . getParameterTypes ( ) ; argumentsReader = argumentsReaderFactory . getArgumentsReader ( httpRequest , formalParameters ) ; Object [ ] arguments = argumentsReader . read ( httpRequest , formalParameters ) ; Object controller = container . getInstance ( method . getDeclaringClass ( ) ) ; resource = method . invoke ( controller , arguments ) ; if ( resource == null ) { throw new BugError ( "Null resource |%s|." , httpRequest . getRequestURI ( ) ) ; } } catch ( AuthorizationException e ) { // at this point, resource is private and need to redirect to a login page // if application provides one, tiny container is configured with, and use it // otherwise servlet container should have one // if no login page found send back servlet container error - that could be custom error page, if declared String loginPage = container . getLoginPage ( ) ; if ( loginPage != null ) { httpResponse . sendRedirect ( loginPage ) ; } else { // expected servlet container behavior: // if <login-config> section exist into web.xml do what is configured there // else send back internal page with message about SC_UNAUTHORIZED // authenticate can throw ServletException if fails, perhaps because is not configured // let servlet container handle this error, that could be custom error page is configured httpRequest . authenticate ( httpResponse ) ; } return ; } catch ( NoSuchMethodException | IllegalArgumentException e ) { // do not use AppServlet#sendError since it is encoded JSON and for resources need HTML dumpError ( context , e ) ; httpResponse . sendError ( HttpServletResponse . SC_NOT_FOUND , httpRequest . getRequestURI ( ) ) ; return ; } catch ( InvocationException e ) { // do not use AppServlet#sendError since it is encoded JSON and for resources need HTML dumpError ( context , e ) ; if ( e . getCause ( ) instanceof NoSuchResourceException ) { httpResponse . sendError ( HttpServletResponse . SC_NOT_FOUND , httpRequest . getRequestURI ( ) ) ; } else { httpResponse . sendError ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR , e . getCause ( ) . getMessage ( ) ) ; } return ; } finally { if ( argumentsReader != null ) { argumentsReader . clean ( ) ; } } // once serialization process started response becomes committed // and is not longer possible to use HttpServletResponse#sendError // let servlet container handle IO exceptions but since client already start rendering // there is no so much to do beside closing or reseting connection httpResponse . setStatus ( HttpServletResponse . SC_OK ) ; resource . serialize ( httpResponse ) ; }
Handle request for a resource . Locate resource method based on request path from request context execute method and serialize back to client returned resource . See class description for general behavior .