解析JFinalFilter--JFinal(initPathUtil,configJFinal,initActionMapping,initHandler,initRender,initOre)等

public void init(FilterConfig filterConfig) throws ServletException {
    this.createJFinalConfig(filterConfig.getInitParameter("configClass"));
    if (!jfinal.init(this.jfinalConfig, filterConfig.getServletContext())) {
        throw new RuntimeException("JFinal init error!");
    } else {
        this.handler = jfinal.getHandler();
        this.constants = Config.getConstants();
        this.encoding = this.constants.getEncoding();
        this.jfinalConfig.afterJFinalStart();
        String contextPath = filterConfig.getServletContext().getContextPath();
        this.contextPathLength = contextPath != null && !"/".equals(contextPath) ? contextPath.length() : 0;
    }
}
public void init(FilterConfig filterConfig) throws boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {

    this.servletContext = servletContext;
    this.contextPath = servletContext.getContextPath();
    this.initPathUtil();
    Config.configJFinal(jfinalConfig);
    this.constants = Config.getConstants();
    this.initActionMapping();
    this.initHandler();
    this.initRender();
    this.initOreillyCos();
    this.initTokenManager();
    return true;
}
在初始化时调用JFina里

第一、initPathUtil,初始化 Path工具类的 webRootPath(即项目根路径)。

private void initPathUtil() {
    String path = this.servletContext.getRealPath("/");
    PathKit.setWebRootPath(path);
}

init 方法中的参数正是 web.xml 中的 JFinalFilter 的初始化参数,即 com.fw.config.MppConfig,它继承于 JFinalConfig,在 createJFinalConfig 中利用该参数使用反射机制得到 JFinalConfig 的实例。

第二、Config.configJFinal 加载 JFinalConfig 实例,进行一些配置。

配置常量,初始化 Log 工具类,配置路由,配置插件,开启插件,配置拦截器,配置 handler。

 jfinalConfig.configConstant(constants);
static void configJFinal(JFinalConfig jfinalConfig) {
    jfinalConfig.configConstant(constants);
    initLogFactory();
    initEngine();
    jfinalConfig.configRoute(routes);
    jfinalConfig.configEngine(engine);
    jfinalConfig.configPlugin(plugins);
    startPlugins();
    jfinalConfig.configInterceptor(interceptors);
    jfinalConfig.configHandler(handlers);
}
 jfinalConfig.configConstant(constants);
static void configJFinal(JFinalConfig jfinalConfig) {
    jfinalConfig.configConstant(constants);
    initLogFactory();
    initEngine();
    jfinalConfig.configRoute(routes);
    jfinalConfig.configEngine(engine);
    jfinalConfig.configPlugin(plugins);
    startPlugins();
    jfinalConfig.configInterceptor(interceptors);
    jfinalConfig.configHandler(handlers);
}

第三、初始化 ActionMapping、Handler、Render

ActionMapping

private void initActionMapping() {
    this.actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());
    this.actionMapping.buildActionMapping();
    Config.getRoutes().clear();
}
第一、创建 ActionMapping,映射所有访问路径和其对应的Action,填充得到一个 HashMap。下面是创建 ActionMapping 代码和注释

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.core;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.InterceptorManager;
import com.jfinal.config.Interceptors;
import com.jfinal.config.Routes;
import com.jfinal.config.Routes.Route;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

final class ActionMapping {
    private static final String SLASH = "/";
    private Routes routes;
    private final Map<String, Action> mapping = new HashMap();// ActionMapping 映射

    ActionMapping(Routes routes, Interceptors interceptors) {//构造方法参数传递进入来fu
   this.routes = routes;
 }
private Set<String> buildExcludedMethodName() { Set<String> excludedMethodName = new HashSet(); Method[] methods = Controller.class.getMethods(); Method[] arr$ = methods; int len$ = methods.length; for(int i$ = 0; i$ < len$; ++i$) { Method m = arr$[i$]; if (m.getParameterTypes().length == 0) { excludedMethodName.add(m.getName()); } } return excludedMethodName; } private List<Routes> getRoutesList() { List<Routes> routesList = Routes.getRoutesList(); List<Routes> ret = new ArrayList(routesList.size() + 1); ret.add(this.routes); ret.addAll(routesList); return ret; } void buildActionMapping() {// 初始化,我将要向里面塞东西了,要清空一下 this.mapping.clear();
Set<String> excludedMethodName = this.buildExcludedMethodName();//返回的是 Controller接口的所有方法集合 InterceptorManager interMan = InterceptorManager.me();// 得到 InterceptorManager 的实例 Iterator i$ = this.getRoutesList().iterator(); while(i$.hasNext()) { // 遍历一个 Entry 集合。Entry 的 key 为访问路径,value 为其对应的 Controller。 Routes routes = (Routes)i$.next(); Iterator i$ = routes.getRouteItemList().iterator(); while(i$.hasNext()) { Route route = (Route)i$.next(); Class<? extends Controller> controllerClass = route.getControllerClass();// 得到访问路径对应的 Controller class Interceptor[] controllerInters = interMan.createControllerInterceptor(controllerClass); // 如果 Controller class没有拦截器注解,则返回一个空数组。反之返回这个类所有拦截器组成的数组 boolean sonOfController = controllerClass.getSuperclass() == Controller.class;// 这里必定为 true,获取class Method[] methods = sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods();//getDeclaredMethods 得到这个类的所有方法以及其接口的所有方法,不包括继承的方法 Method[] arr$ = methods; int len$ = methods.length; for(int i$ = 0; i$ < len$; ++i$) { Method method = arr$[i$]; String methodName = method.getName(); if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0 && (!sonOfController || Modifier.isPublic(method.getModifiers()))) {//若这个方法是继承自 Controller的方法 或 该方法有参数,过滤掉 Interceptor[] actionInters = interMan.buildControllerActionInterceptor(routes.getInterceptors(), controllerInters, controllerClass, method);// 得到包含所有拦截器的数组(包括全局的拦截器,类级别的拦截器、方法级别的拦截器) String controllerKey = route.getControllerKey();//获取controller的路径key值 ActionKey ak = (ActionKey)method.getAnnotation(ActionKey.class);  String actionKey; if (ak != null) {
// ActionKey 不为空的话为设置自定义的访问路径(说明有方法被注有 @ActionKey 注解)
actionKey = ak.value().trim(); if ("".equals(actionKey)) { throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank."); } if (!actionKey.startsWith("/")) { actionKey = "/" + actionKey; } } else if (methodName.equals("index")) {  // ActionKey为空,methodName 为 index的情况下:actionKey = controllerKey actionKey = controllerKey; } else // ActionKey为空,methodName 不为 index的情况下:actionKey = controllerKey +"/" + methodName actionKey = controllerKey.equals("/") ? "/" + methodName : controllerKey + "/" + methodName; } // 组合装配成一个 Action // 填充 HashMap(访问路径为 key,Action 为 value) Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, route.getFinalViewPath(routes.getBaseViewPath())); if (this.mapping.put(actionKey, action) != null) {
                       throw new RuntimeException(buildMsg(actionKey, controllerClass, method));
} } } } } this.routes.clear(); Action action = (Action)this.mapping.get("/"); if (action != null) { this.mapping.put("", action); } } private static final String buildMsg(String actionKey, Class<? extends Controller> controllerClass, Method method) { StringBuilder sb = (new StringBuilder("The action \"")).append(controllerClass.getName()).append(".").append(method.getName()).append("()\" can not be mapped, ").append("actionKey \"").append(actionKey).append("\" is already in use."); String msg = sb.toString(); System.err.println("\nException: " + msg); return msg; } Action getAction(String url, String[] urlPara) { Action action = (Action)this.mapping.get(url); if (action != null) { return action; } else { int i = url.lastIndexOf("/"); if (i != -1) { action = (Action)this.mapping.get(url.substring(0, i)); urlPara[0] = url.substring(i + 1); } return action; } } List<String> getAllActionKeys() { List<String> allActionKeys = new ArrayList(this.mapping.keySet()); Collections.sort(allActionKeys); return allActionKeys; }}

初始化Handler

第一、创建一个 ActionHandler 实例 actionHandler。

第二、HandlerFactory.getHandler 创建一个 Handler 链,链尾是 actionHandler,并且返回链首。



private void initHandler() {
    Handler actionHandler = new ActionHandler(this.actionMapping, this.constants);
    this.handler = HandlerFactory.getHandler(Config.getHandlers().getHandlerList(), actionHandler);
}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.core;

import com.jfinal.aop.Invocation;
import com.jfinal.config.Constants;
import com.jfinal.handler.Handler;
import com.jfinal.log.Log;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import com.jfinal.render.RenderManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionHandler extends Handler {
    private final boolean devMode;
    private final ActionMapping actionMapping;
    private static final RenderManager renderManager = RenderManager.me();
    private static final Log log = Log.getLog(ActionHandler.class);

    public ActionHandler(ActionMapping actionMapping, Constants constants) {
        this.actionMapping = actionMapping;
        this.devMode = constants.getDevMode();
    }

    public final void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        if (target.indexOf(46) == -1) {
            isHandled[0] = true;
            String[] urlPara = new String[]{null};
            Action action = this.actionMapping.getAction(target, urlPara);
            if (action == null) {
                if (log.isWarnEnabled()) {
                    String qs = request.getQueryString();
                    log.warn("404 Action Not Found: " + (qs == null ? target : target + "?" + qs));
                }

                renderManager.getRenderFactory().getErrorRender(404).setContext(request, response).render();
            } else {
                String qs;
                String msg;
                try {
                    Controller controller = (Controller)action.getControllerClass().newInstance();
                    controller.init(request, response, urlPara[0]);
                    if (this.devMode) {
                        if (ActionReporter.isReportAfterInvocation(request)) {
                            (new Invocation(action, controller)).invoke();
                            ActionReporter.report(target, controller, action);
                        } else {
                            ActionReporter.report(target, controller, action);
                            (new Invocation(action, controller)).invoke();
                        }
                    } else {
                        (new Invocation(action, controller)).invoke();
                    }

                    Render render = controller.getRender();
                    if (render instanceof ForwardActionRender) {
                        msg = ((ForwardActionRender)render).getActionUrl();
                        if (target.equals(msg)) {
                            throw new RuntimeException("The forward action url is the same as before.");
                        }

                        this.handle(msg, request, response, isHandled);
                        return;
                    }

                    if (render == null) {
                        render = renderManager.getRenderFactory().getDefaultRender(action.getViewPath() + action.getMethodName());
                    }

                    render.setContext(request, response, action.getViewPath()).render();
                } catch (RenderException var11) {
                    if (log.isErrorEnabled()) {
                        qs = request.getQueryString();
                        log.error(qs == null ? target : target + "?" + qs, var11);
                    }
                } catch (ActionException var12) {
                    int errorCode = var12.getErrorCode();
                    msg = null;
                    if (errorCode == 404) {
                        msg = "404 Not Found: ";
                    } else if (errorCode == 401) {
                        msg = "401 Unauthorized: ";
                    } else if (errorCode == 403) {
                        msg = "403 Forbidden: ";
                    }

                    String qs;
                    if (msg != null) {
                        if (log.isWarnEnabled()) {
                            qs = request.getQueryString();
                            log.warn(msg + (qs == null ? target : target + "?" + qs));
                        }
                    } else if (log.isErrorEnabled()) {
                        qs = request.getQueryString();
                        log.error(qs == null ? target : target + "?" + qs, var12);
                    }

                    var12.getErrorRender().setContext(request, response, action.getViewPath()).render();
                } catch (Exception var13) {
                    if (log.isErrorEnabled()) {
                        qs = request.getQueryString();
                        log.error(qs == null ? target : target + "?" + qs, var13);
                    }

                    renderManager.getRenderFactory().getErrorRender(500).setContext(request, response, action.getViewPath()).render();
                }

            }
        }
    }
}
//
创建一个 handler 链条,最后返回的 result 是 handler 链的头部,链尾是 ActionHandler
// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.jfinal.handler;import java.util.List;public class HandlerFactory { private HandlerFactory() { }
创建一个 handler 链条,最后返回的 result 是 handler 链的头部,链尾是 ActionHandler
public static Handler getHandler(List<Handler> handlerList, Handler actionHandler) { Handler result = actionHandler; for(int i = handlerList.size() - 1; i >= 0; --i) { Handler temp = (Handler)handlerList.get(i); temp.next = result; temp.nextHandler = result; result = temp; } return result; }}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.config;

import com.jfinal.handler.Handler;
import java.util.ArrayList;
import java.util.List;

public final class Handlers {
    private final List<Handler> handlerList = new ArrayList();

    public Handlers() {
    }

    public Handlers add(Handler handler) {
        if (handler == null) {
            throw new IllegalArgumentException("handler can not be null");
        } else {
            this.handlerList.add(handler);
            return this;
        }
    }

    public List<Handler> getHandlerList() {
        return this.handlerList;
    }
}

初始化Render

private void initRender() {
    RenderManager.me().init(Config.getEngine(), this.constants, this.servletContext);
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.render;

import com.jfinal.config.Constants;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ModelRecordElResolver;
import com.jfinal.template.Engine;
import java.io.File;
import java.util.Locale;
import javax.servlet.ServletContext;

public class RenderManager {
    private Engine engine;
    private Constants constants;
    private ServletContext servletContext;
    private IRenderFactory renderFactory = null;
    private static final RenderManager me = new RenderManager();

    private RenderManager() {
    }

    public static RenderManager me() {
        return me;
    }

    public IRenderFactory getRenderFactory() {
        return this.renderFactory;
    }

    public void setRenderFactory(IRenderFactory renderFactory) {
        if (renderFactory == null) {
            throw new IllegalArgumentException("renderFactory can not be null");
        } else {
            this.renderFactory = renderFactory;
        }
    }

    public void init(Engine engine, Constants constants, ServletContext servletContext) {
        this.engine = engine;
        this.constants = constants;
        this.servletContext = servletContext;
        Render.init(constants.getEncoding(), constants.getDevMode());
         this.initTemplateRender();
        this.initFreeMarkerRender(servletContext);
        this.initVelocityRender(servletContext);
        this.initJspRender(servletContext);
        this.initFileRender(servletContext);
        if (this.renderFactory == null) {
            this.renderFactory = new RenderFactory();
        }

        this.renderFactory.init(engine, constants, servletContext);
    }

    private void initTemplateRender() {
        TemplateRender.init(this.engine);
    }

    private void initFreeMarkerRender(ServletContext servletContext) {
        try {
            Class.forName("freemarker.template.Template");
            FreeMarkerRender.init(servletContext, Locale.getDefault(), this.constants.getFreeMarkerTemplateUpdateDelay());
        } catch (ClassNotFoundException var3) {
            LogKit.logNothing(var3);
        }

    }

    private void initVelocityRender(ServletContext servletContext) {
        try {
            Class.forName("org.apache.velocity.VelocityContext");
            VelocityRender.init(servletContext);
        } catch (ClassNotFoundException var3) {
            LogKit.logNothing(var3);
        }

    }

    private void initJspRender(ServletContext servletContext) {
        try {
            Class.forName("javax.el.ELResolver");
            Class.forName("javax.servlet.jsp.JspFactory");
            ModelRecordElResolver.init(servletContext);
        } catch (ClassNotFoundException var3) {
            LogKit.logNothing(var3);
        } catch (IllegalStateException var4) {
            throw var4;
        } catch (Exception var5) {
            LogKit.logNothing(var5);
        }

    }

    private void initFileRender(ServletContext servletContext) {
        String downloadPath = this.constants.getBaseDownloadPath();
        downloadPath = downloadPath.trim();
        downloadPath = downloadPath.replaceAll("\\\\", "/");
        String baseDownloadPath;
        if (PathKit.isAbsolutelyPath(downloadPath)) {
            baseDownloadPath = downloadPath;
        } else {
            baseDownloadPath = PathKit.getWebRootPath() + File.separator + downloadPath;
        }

        if (!baseDownloadPath.equals("/") && baseDownloadPath.endsWith("/")) {
            baseDownloadPath = baseDownloadPath.substring(0, baseDownloadPath.length() - 1);
        }

        FileRender.init(baseDownloadPath, servletContext);
    }

    public Engine getEngine() {
        return this.engine;
    }

    public Constants getConstants() {
        return this.constants;
    }

    public ServletContext getServletContext() {
        return this.servletContext;
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.render;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class Render {
    protected String view;
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    private static String encoding = "UTF-8";
    private static boolean devMode = false;

    public Render() {
    }

    static void init(String encoding, boolean devMode) {
        encoding = encoding;
        devMode = devMode;
    }

    public static String getEncoding() {
        return encoding;
    }

    public static boolean getDevMode() {
        return devMode;
    }

    public Render setContext(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        return this;
    }

    public Render setContext(HttpServletRequest request, HttpServletResponse response, String viewPath) {
        this.request = request;
        this.response = response;
        if (this.view != null && this.view.length() > 0 && this.view.charAt(0) != '/') {
            this.view = viewPath + this.view;
        }

        return this;
    }

    public String getView() {
        return this.view;
    }

    public void setView(String view) {
        this.view = view;
    }

    public abstract void render();
}

TemplateRender.init(this.engine); 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.render;

import com.jfinal.template.Engine;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class TemplateRender extends Render {
    private static Engine engine;
    private static final String contentType = "text/html; charset=" + getEncoding();

    static void init(Engine engine) {
        if (engine == null) {
            throw new IllegalArgumentException("engine can not be null");
        } else {
            engine = engine;
        }
    }

    public TemplateRender(String view) {
        this.view = view;
    }

    public String getContentType() {
        return contentType;
    }

    public void render() {
        this.response.setContentType(this.getContentType());
        Map<Object, Object> data = new HashMap();
        Enumeration attrs = this.request.getAttributeNames();

        while(attrs.hasMoreElements()) {
            String attrName = (String)attrs.nextElement();
            data.put(attrName, this.request.getAttribute(attrName));
        }

        PrintWriter writer = null;

        try {
            writer = this.response.getWriter();
            engine.getTemplate(this.view).render(data, writer);
        } catch (Exception var7) {
            throw new RenderException(var7);
        } finally {
            if (writer != null) {
                writer.close();
            }

        }

    }

    public String toString() {
        return this.view;
    }
}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.render;

import com.jfinal.core.JFinal;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;

public class FreeMarkerRender extends Render {
    private static final String contentType = "text/html; charset=" + getEncoding();
    private static final Configuration config = new Configuration();

    public FreeMarkerRender(String view) {
        this.view = view;
    }

    public static Configuration getConfiguration() {
        return config;
    }

    public static void setProperty(String propertyName, String propertyValue) {
        try {
            getConfiguration().setSetting(propertyName, propertyValue);
        } catch (TemplateException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static void setSharedVariable(String name, Object object) {
        try {
            getConfiguration().setSharedVariable(name, object);
        } catch (TemplateException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static void setProperties(Properties properties) {
        try {
            getConfiguration().setSettings(properties);
        } catch (TemplateException var2) {
            throw new RuntimeException(var2);
        }
    }

    public static void setTemplateLoadingPath(String path) {
        config.setServletContextForTemplateLoading(JFinal.me().getServletContext(), path);
    }
//
// 初始化 freemarker 配置:config = new Configuration();
// 设置 freemarker 页面的存放位置为项目根路径
static void init(ServletContext servletContext, Locale locale, int template_update_delay) { config.setServletContextForTemplateLoading(servletContext, "/"); if (getDevMode()) {//
// 设置开发模式下更新延迟时间
config.setTemplateUpdateDelay(0); } else { config.setTemplateUpdateDelay(template_update_delay); } config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); config.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER); config.setDefaultEncoding(getEncoding());
   // 设置默认编码// 设置输出编// 设置时区
// 去掉int型输出时的逗号, 例如: 123,456  
setNumberFormat
config.setOutputEncoding(getEncoding()); config.setLocale(locale); config.setLocalizedLookup(false); config.setNumberFormat("#0.#####"); config.setDateFormat("yyyy-MM-dd"); config.setTimeFormat("HH:mm:ss"); config.setDateTimeFormat("yyyy-MM-dd HH:mm:ss"); } public String getContentType() { return contentType; } public void render() { this.response.setContentType(this.getContentType()); Map data = new HashMap(); Enumeration attrs = this.request.getAttributeNames(); while(attrs.hasMoreElements()) { String attrName = (String)attrs.nextElement(); data.put(attrName, this.request.getAttribute(attrName)); } PrintWriter writer = null; try { Template template = config.getTemplate(this.view); writer = this.response.getWriter(); template.process(data, writer); } catch (Exception var7) { throw new RenderException(var7); } finally { if (writer != null) { writer.close(); } } }

Init 上传组件

private void initOreillyCos() {
    OreillyCos.init(this.constants.getBaseUploadPath(), this.constants.getMaxPostSize(), this.constants.getEncoding());
}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.upload;

import com.jfinal.kit.LogKit;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;
import com.oreilly.servlet.multipart.FileRenamePolicy;
import java.io.File;

public class OreillyCos {
    public OreillyCos() {
    }
//加载上传组件
    public static void init(String uploadPath, int maxPostSize, String encoding) {
        if (StrKit.isBlank(uploadPath)) {
            throw new IllegalArgumentException("uploadPath can not be blank.");
        } else {
            try {
                Class.forName("com.oreilly.servlet.MultipartRequest");
                doInit(uploadPath, maxPostSize, encoding);
            } catch (ClassNotFoundException var4) {
                LogKit.logNothing(var4);
            }

        }
    }

    public static void setFileRenamePolicy(FileRenamePolicy fileRenamePolicy) {
        if (fileRenamePolicy == null) {
            throw new IllegalArgumentException("fileRenamePolicy can not be null.");
        } else {
            MultipartRequest.fileRenamePolicy = fileRenamePolicy;
        }
    }

    private static void doInit(String uploadPath, int maxPostSize, String encoding) {
        uploadPath = uploadPath.trim();
        uploadPath = uploadPath.replaceAll("\\\\", "/");
        String baseUploadPath;
// 判断上传路径是否是绝对路径,如果不是把它加工成绝对路径
if (PathKit.isAbsolutelyPath(uploadPath)) { baseUploadPath = uploadPath; } else { baseUploadPath = PathKit.getWebRootPath() + File.separator + uploadPath; } if (!baseUploadPath.equals("/") && baseUploadPath.endsWith("/")) { baseUploadPath = baseUploadPath.substring(0, baseUploadPath.length() - 1); } MultipartRequest.init(baseUploadPath, maxPostSize, encoding); }}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.upload;

import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.oreilly.servlet.multipart.FileRenamePolicy;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MultipartRequest extends HttpServletRequestWrapper {
    private static String baseUploadPath;
    private static int maxPostSize;
    private static String encoding;
    static FileRenamePolicy fileRenamePolicy = new DefaultFileRenamePolicy();
    private List<UploadFile> uploadFiles;
    private com.oreilly.servlet.MultipartRequest multipartRequest;

    static void init(String baseUploadPath, int maxPostSize, String encoding) {
        baseUploadPath = baseUploadPath;
        maxPostSize = maxPostSize;
        encoding = encoding;
    }

    public MultipartRequest(HttpServletRequest request, String uploadPath, int maxPostSize, String encoding) {
        super(request);
        this.wrapMultipartRequest(request, this.getFinalPath(uploadPath), maxPostSize, encoding);
    }

    public MultipartRequest(HttpServletRequest request, String uploadPath, int maxPostSize) {
        super(request);
        this.wrapMultipartRequest(request, this.getFinalPath(uploadPath), maxPostSize, encoding);
    }

    public MultipartRequest(HttpServletRequest request, String uploadPath) {
        super(request);
        this.wrapMultipartRequest(request, this.getFinalPath(uploadPath), maxPostSize, encoding);
    }

    public MultipartRequest(HttpServletRequest request) {
        super(request);
        this.wrapMultipartRequest(request, baseUploadPath, maxPostSize, encoding);
    }

    private String getFinalPath(String uploadPath) {
        if (uploadPath == null) {
            throw new IllegalArgumentException("uploadPath can not be null.");
        } else {
            uploadPath = uploadPath.trim();
            if (!uploadPath.startsWith("/") && !uploadPath.startsWith("\\")) {
                return baseUploadPath + File.separator + uploadPath;
            } else {
                return baseUploadPath.equals("/") ? uploadPath : baseUploadPath + uploadPath;
            }
        }
    }

    private void wrapMultipartRequest(HttpServletRequest request, String uploadPath, int maxPostSize, String encoding) {
        File dir = new File(uploadPath);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new RuntimeException("Directory " + uploadPath + " not exists and can not create directory.");
        } else {
            this.uploadFiles = new ArrayList();

            try {
                this.multipartRequest = new com.oreilly.servlet.MultipartRequest(request, uploadPath, maxPostSize, encoding, fileRenamePolicy);
                Enumeration files = this.multipartRequest.getFileNames();

                while(files.hasMoreElements()) {
                    String name = (String)files.nextElement();
                    String filesystemName = this.multipartRequest.getFilesystemName(name);
                    if (filesystemName != null) {
                        String originalFileName = this.multipartRequest.getOriginalFileName(name);
                        String contentType = this.multipartRequest.getContentType(name);
                        UploadFile uploadFile = new UploadFile(name, uploadPath, filesystemName, originalFileName, contentType);
                        if (this.isSafeFile(uploadFile)) {
                            this.uploadFiles.add(uploadFile);
                        }
                    }
                }

            } catch (IOException var12) {
                throw new RuntimeException(var12);
            }
        }
    }

    private boolean isSafeFile(UploadFile uploadFile) {
        String fileName = uploadFile.getFileName().trim().toLowerCase();
        if (!fileName.endsWith(".jsp") && !fileName.endsWith(".jspx")) {
            return true;
        } else {
            uploadFile.getFile().delete();
            return false;
        }
    }

    public List<UploadFile> getFiles() {
        return this.uploadFiles;
    }

    public Enumeration getParameterNames() {
        return this.multipartRequest.getParameterNames();
    }

    public String getParameter(String name) {
        return this.multipartRequest.getParameter(name);
    }

    public String[] getParameterValues(String name) {
        return this.multipartRequest.getParameterValues(name);
    }

    public Map getParameterMap() {
        Map map = new HashMap();
        Enumeration enumm = this.getParameterNames();

        while(enumm.hasMoreElements()) {
            String name = (String)enumm.nextElement();
            map.put(name, this.multipartRequest.getParameterValues(name));
        }

        return map;
    }
}

加载initTokenManager

private void initTokenManager() {
    ITokenCache tokenCache = this.constants.getTokenCache();
    if (tokenCache != null) {
        TokenManager.init(tokenCache);
    }

}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.token;

import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class TokenManager {
    private static ITokenCache tokenCache;
    private static Random random = new Random();

    private TokenManager() {
    }

    public static void init(ITokenCache tokenCache) {
        if (tokenCache != null) {
            tokenCache = tokenCache;
            long halfTimeOut = 150000L;
// Token最小过期时间的一半时间作为任务运行的间隔时间
(new Timer("TokenManager", true)).schedule(new TimerTask() { public void run() { TokenManager.removeTimeOutToken(); } }, halfTimeOut, halfTimeOut); } } public static void createToken(Controller controller, String tokenName, int secondsOfTimeOut) { if (tokenCache == null) { String tokenId = String.valueOf(random.nextLong()); controller.setAttr(tokenName, tokenId); controller.setSessionAttr(tokenName, tokenId); createTokenHiddenField(controller, tokenName, tokenId); } else { createTokenUseTokenIdGenerator(controller, tokenName, secondsOfTimeOut); } } private static void createTokenHiddenField(Controller controller, String tokenName, String tokenId) { StringBuilder sb = new StringBuilder(); sb.append("<input type='hidden' name='").append(tokenName).append("' value='" + tokenId).append("' />"); controller.setAttr("token", sb.toString()); } private static void createTokenUseTokenIdGenerator(Controller controller, String tokenName, int secondsOfTimeOut) { if (secondsOfTimeOut < 300) { secondsOfTimeOut = 300; } String tokenId = null; Token token = null; int var5 = 8; do { if (var5-- == 0) { throw new RuntimeException("Can not create tokenId."); } tokenId = String.valueOf(random.nextLong()); token = new Token(tokenId, System.currentTimeMillis() + (long)(secondsOfTimeOut * 1000)); } while(tokenId == null || tokenCache.contains(token)); controller.setAttr(tokenName, tokenId); tokenCache.put(token); createTokenHiddenField(controller, tokenName, tokenId); } public static synchronized boolean validateToken(Controller controller, String tokenName) { String clientTokenId = controller.getPara(tokenName); if (tokenCache != null) { Token token = new Token(clientTokenId); boolean result = tokenCache.contains(token); tokenCache.remove(token); return result; } else { String serverTokenId = (String)controller.getSessionAttr(tokenName); controller.removeSessionAttr(tokenName); return StrKit.notBlank(clientTokenId) && clientTokenId.equals(serverTokenId); } } private static void removeTimeOutToken() { List<Token> tokenInCache = tokenCache.getAll(); if (tokenInCache != null) { List<Token> timeOutTokens = new ArrayList(); long currentTime = System.currentTimeMillis(); Iterator i$ = tokenInCache.iterator(); Token token; while(i$.hasNext()) { token = (Token)i$.next(); if (token.getExpirationTime() <= currentTime) { timeOutTokens.add(token); } } i$ = timeOutTokens.iterator(); while(i$.hasNext()) { token = (Token)i$.next(); tokenCache.remove(token); } } }}


总结:

解析JFinalFilter文件的解读加载顺序

开始是默认加载Filter的init方法

然后调用JFinal的init方法,

初始化加载initPathUtil,constants ,configJFinalinitActionMapping,initHandler,initRender,initOreillyCos,initOreillyCos,initTokenManager。

if (!jfinal.init(this.jfinalConfig, filterConfig.getServletContext())) {

其中所有类加载时都会有各自的init方法和实现或者集成的类,工厂等。

 boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {

        this.servletContext = servletContext;
        this.contextPath = servletContext.getContextPath();
        this.initPathUtil();
        Config.configJFinal(jfinalConfig);
        this.constants = Config.getConstants();
        this.initActionMapping();
        this.initHandler();
        this.initRender();
        this.initOreillyCos();
        this.initTokenManager();

        return true;

    }

configJFinal下默认加载的东西,同理,也有各自需要加载的文件。

 static void configJFinal(JFinalConfig jfinalConfig) {
        jfinalConfig.configConstant(constants);
        initLogFactory();
        initEngine();
        jfinalConfig.configRoute(routes);
        jfinalConfig.configEngine(engine);
        jfinalConfig.configPlugin(plugins);
        startPlugins();
        jfinalConfig.configInterceptor(interceptors);
        jfinalConfig.configHandler(handlers);
    }

然后加载Filter默认的doFilter方法,

运行最后会调用来实现后台和前台的交互。

chain.doFilter(request, response);

//配置过滤器2
<filter>
   <filter-name>jfinal</filter-name>
   <filter-class>com.jfinal.core.JFinalFilter</filter-class>
   <init-param>
      <param-name>configClass</param-name>
      <param-value>com.tspace.common.TspaceConfig</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>jfinal</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值