package foundation.server; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import foundation.handler.DataPool; import foundation.handler.DataPoolType; import foundation.log.LogConfig; import foundation.route.ClientAcceptType; import foundation.route.ControllerNavigator; import foundation.route.Route; import foundation.route.RouteNavigator; import foundation.route.RouteTable; import foundation.route.RouteType; import foundation.route.ServerErrorNavigator; import foundation.server.config.Configer; import foundation.token.IOnlineUser; import foundation.token.IUserManager; import foundation.translator.Translator; public class Dispatcher implements Filter { public static boolean AuthorizeActive; private static Dispatcher instance; private static Logger logger; static { logger = LogManager.getLogger(Dispatcher.class); } public Dispatcher() { instance = this; } public synchronized static Dispatcher getInstance() { if (instance == null) { instance = new Dispatcher(); } return instance; } public void init(FilterConfig filterConfig) throws ServletException { AuthorizeActive = Translator.toBoolean(Configer.getString("AuthorizeActive"), true); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { DataPool dataPool = null; request.setCharacterEncoding("utf-8"); //1. route and get navigator RouteNavigator navigator = RouteTable.matchRoute(request); //2. log if (LogConfig.IsActive_Dispatcher_Trace) { logger.debug("filter request URI:" + navigator); } //3. authorize if (navigator.isAuthorizeSensitive() && AuthorizeActive) { Route route = navigator.getRoute(); //3.1 user token dataPool = new DataPool(request); if (DataPoolType.Options == dataPool.getType()) { ControllerNavigator.replyOptions(request, response); return; } String token = dataPool.getToken(); IOnlineUser onlineUser = IUserManager.registerUser(token); dataPool.setUser(onlineUser); //3.2 go to login if (onlineUser.isAnymous()) { if (route == null) { logger.info("redirct to time out for request: {}", navigator); navigator.redirectToTimeOut(response, ClientAcceptType.Html); return; } RouteType routeType = route.getRouteType(); if (RouteType.Controller == routeType) { logger.info("redirct to time out for request: {}", navigator); navigator.redirectToTimeOut(response, ClientAcceptType.Ajax); return; } navigator.redirectToTimeOut(response, ClientAcceptType.Html); return; } } //4. send to navigator.sendTo(response, dataPool); } catch (Exception e) { String error = printStackToString(e); logger.error("dispatch error:" + e.getMessage()); logger.error(error); RouteNavigator navigator = new ServerErrorNavigator(request); navigator.sendTo(response, null, e); } } public void destroy() { } private String printStackToString(Exception e) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outStream); e.printStackTrace(printStream); return outStream.toString(); } }