com.v5analytics.webster.Router Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webster Show documentation
Show all versions of webster Show documentation
Minimalist web framework, that has an express.js like API.
The newest version!
package com.v5analytics.webster;
import com.v5analytics.webster.handlers.StaticFileHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Router {
private static final Logger LOGGER = LoggerFactory.getLogger(Router.class);
private ServletContext servletContext;
private Map> routes = new HashMap>();
private HandlerChain missingRouteHandlerChain = new HandlerChain(new RequestResponseHandler[0]);
private RequestResponseHandler missingRouteHandler;
Map, RequestResponseHandler[]> exceptionHandlers = new HashMap<>();
public Router(ServletContext servletContext) {
this.servletContext = servletContext;
this.missingRouteHandler = new StaticFileHandler(servletContext);
routes.put(Route.Method.GET, new ArrayList());
routes.put(Route.Method.POST, new ArrayList());
routes.put(Route.Method.PUT, new ArrayList());
routes.put(Route.Method.DELETE, new ArrayList());
routes.put(Route.Method.HEAD, new ArrayList());
routes.put(Route.Method.OPTIONS, new ArrayList());
routes.put(Route.Method.TRACE, new ArrayList());
routes.put(Route.Method.CONNECT, new ArrayList());
}
public Route addRoute(Route.Method method, String path, RequestResponseHandler... handlers) {
List methodRoutes = routes.get(method);
Route route = new Route(method, path, handlers);
int existingRouteIndex = methodRoutes.indexOf(route);
if (existingRouteIndex > -1) {
methodRoutes.set(existingRouteIndex, route);
} else {
methodRoutes.add(route);
}
return route;
}
public void addExceptionHandler(Class extends Exception> exceptionClass, RequestResponseHandler[] handlers) {
exceptionHandlers.put(exceptionClass, handlers);
}
public void route(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
routeWithExceptionHandling(request, response);
} catch (Exception ex) {
RequestResponseHandler[] handlers = exceptionHandlers.get(ex.getClass());
if (handlers != null && handlers.length > 0) {
LOGGER.error("Caught exception in route: " + request.getRequestURI(), ex);
dispatch(handlers, request, response);
} else {
throw ex;
}
}
}
private void routeWithExceptionHandling(HttpServletRequest request, HttpServletResponse response) throws Exception {
Route.Method method = Route.Method.valueOf(request.getMethod().toUpperCase());
if (method == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String requestURI = request.getRequestURI();
String contextPath = request.getContextPath();
if (contextPath == null) {
contextPath = "";
}
String relativeUri = requestURI.substring(contextPath.length());
if (relativeUri.length() == 0) {
response.sendRedirect(contextPath + '/');
return;
}
Route route = findRoute(method, request, relativeUri);
if (route == null) {
missingRouteHandler.handle(request, response, missingRouteHandlerChain);
} else {
RequestResponseHandler[] handlers = route.getHandlers();
dispatch(handlers, request, response);
}
}
private void dispatch(
RequestResponseHandler[] handlers,
HttpServletRequest request,
HttpServletResponse response
) throws Exception {
HandlerChain chain = new HandlerChain(handlers);
chain.next(request, response);
}
private Route findRoute(Route.Method method, HttpServletRequest request, String relativeUri) {
List potentialRoutes = routes.get(method);
for (Route route : potentialRoutes) {
if (route.isMatch(request, relativeUri)) {
return route;
}
}
return null;
}
public Map> getRoutes() {
return routes;
}
public void setMissingRouteHandler(RequestResponseHandler missingRouteHandler) {
this.missingRouteHandler = missingRouteHandler;
}
public RequestResponseHandler getMissingRouteHandler() {
return missingRouteHandler;
}
}