public class ActionBean {

    private Class<?> actionClass;
    private Method actionMethod;

    public ActionBean(Class<?> actionClass, Method actionMethod) {
        this.actionClass = actionClass;
        this.actionMethod = actionMethod;
    }

    public Class<?> getActionClass() {
        return actionClass;
    }

    public void setActionClass(Class<?> actionClass) {
        this.actionClass = actionClass;
    }

    public Method getActionMethod() {
        return actionMethod;
    }

    public void setActionMethod(Method actionMethod) {
        this.actionMethod = actionMethod;
    }
} public class Page extends BaseBean {

    private String path;              // 页面路径
    private Map<String, Object> data; // 相关数据

    public Page(String path) {
        this.path = path;
        data = new HashMap<String, Object>();
    }

    public Page data(String key, Object value) {
        data.put(key, value);
        return this;
    }

    public boolean isRedirect() {
        return path.startsWith("/");
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }
} public class RequestBean {

    private String requestMethod;
    private String requestPath;

    public RequestBean(String requestMethod, String requestPath) {
        this.requestMethod = requestMethod;
        this.requestPath = requestPath;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestPath() {
        return requestPath;
    }

    public void setRequestPath(String requestPath) {
        this.requestPath = requestPath;
    }
} public class Result extends BaseBean {

    private boolean success; // 成功标志
    private int error;       // 错误代码
    private Object data;     // 相关数据

    public Result(boolean success) {
        this.success = success;
    }

    public Result error(int error) {
        this.error = error;
        return this;
    }

    public Result data(Object data) {
        this.data = data;
        return this;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public int getError() {
        return error;
    }

    public void setError(int error) {
        this.error = error;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
} public class ActionHelper {

    private static final Map<RequestBean, ActionBean> actionMap = new HashMap<RequestBean, ActionBean>();

    static {
        // 获取并遍历所有 Action 类
        List<Class<?>> actionClassList = ClassHelper.getClassListBySuper(BaseAction.class);
        for (Class<?> actionClass : actionClassList) {
            // 获取并遍历该 Action 类中所有的方法（不包括父类中的方法）
            Method[] actionMethods = actionClass.getDeclaredMethods();
            if (ArrayUtil.isNotEmpty(actionMethods)) {
                for (Method actionMethod : actionMethods) {
                    // 判断当前 Action 方法是否带有 @Request 注解
                    if (actionMethod.isAnnotationPresent(Request.class)) {
                        // 获取 @Requet 注解中的 URL 字符串
                        String[] urlArray = StringUtil.splitString(actionMethod.getAnnotation(Request.class).value(), ":");
                        if (ArrayUtil.isNotEmpty(urlArray)) {
                            // 获取请求方法与请求路径
                            String requestMethod = urlArray[0];
                            String requestPath = urlArray[1]; // 带有占位符
                            // 将请求路径中的占位符 {\w+} 转换为正则表达式 (\\w+)
                            requestPath = StringUtil.replaceAll(requestPath, "\\{\\w+\\}", "(\\\\w+)");
                            // 将 RequestBean 与 ActionBean 放入 Action Map 中
                            actionMap.put(new RequestBean(requestMethod, requestPath), new ActionBean(actionClass, actionMethod));
                        }
                    }
                }
            }
        }
    }

    public static Map<RequestBean, ActionBean> getActionMap() {
        return actionMap;
    }
} public class BeanHelper {

    private static final Logger logger = Logger.getLogger(BeanHelper.class);

    private static final Map<Class<?>, Object> beanMap = new HashMap<Class<?>, Object>(); // Bean 类 => Bean 实例

    static {
        try {
            // 获取并遍历所有的 Bean（带有 @Bean 注解的类）
            List<Class<?>> beanClassList = ClassHelper.getClassListByAnnotation(Bean.class);
            for (Class<?> beanClass : beanClassList) {
                // 创建 Bean 实例
                Object beanInstance = beanClass.newInstance();
                // 将 Bean 实例放入 Bean Map 中（键为 Bean 类，值为 Bean 实例）
                beanMap.put(beanClass, beanInstance);
            }
        } catch (Exception e) {
            logger.error("初始化 BeanHelper 出错！", e);
        }
    }

    public static Map<Class<?>, Object> getBeanMap() {
        return beanMap;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> cls) {
        if (!beanMap.containsKey(cls)) {
            throw new RuntimeException("无法根据类名获取实例！" + cls);
        }
        return (T) beanMap.get(cls);
    }
} public class ConfigHelper {

    private static final Properties configProperties = FileUtil.loadPropFile("config.properties");

    public static String getStringProperty(String key) {
        String value = "";
        if (configProperties.containsKey(key)) {
            value = configProperties.getProperty(key);
        }
        return value;
    }

    public static int getNumberProperty(String key) {
        int value = 0;
        String sValue = getStringProperty(key);
        if (StringUtil.isNumber(sValue)) {
            value = Integer.parseInt(sValue);
        }
        return value;
    }
} public class CastUtil {

    // 转为 String 型
    public static String castString(Object obj) {
        return CastUtil.castString(obj, "");
    }

    // 转为 String 型（提供默认值）
    public static String castString(Object obj, String defaultValue) {
        return obj != null ? String.valueOf(obj) : defaultValue;
    }

    // 转为 double 型
    public static double castDouble(Object obj) {
        return CastUtil.castDouble(obj, 0);
    }

    // 转为 double 型（提供默认值）
    public static double castDouble(Object obj, double defaultValue) {
        double doubleValue = defaultValue;
        if (obj != null) {
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)) {
                try {
                    doubleValue = Double.parseDouble(strValue);
                } catch (NumberFormatException e) {
                    doubleValue = defaultValue;
                }
            }
        }
        return doubleValue;
    }

    // 转为 float 型
    public static float castFloat(Object obj) {
        return CastUtil.castFloat(obj, 0);
    }

    // 转为 float 型（提供默认值）
    public static float castFloat(Object obj, float defaultValue) {
        float floatValue = defaultValue;
        if (obj != null) {
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)) {
                try {
                    floatValue = Float.parseFloat(strValue);
                } catch (NumberFormatException e) {
                    floatValue = defaultValue;
                }
            }
        }
        return floatValue;
    }

    // 转为 long 型
    public static long castLong(Object obj) {
        return CastUtil.castLong(obj, 0);
    }

    // 转为 long 型（提供默认值）
    public static long castLong(Object obj, long defaultValue) {
        long longValue = defaultValue;
        if (obj != null) {
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)) {
                try {
                    longValue = Long.parseLong(strValue);
                } catch (NumberFormatException e) {
                    longValue = defaultValue;
                }
            }
        }
        return longValue;
    }

    // 转为 int 型
    public static int castInt(Object obj) {
        return CastUtil.castInt(obj, 0);
    }

    // 转为 int 型（提供默认值）
    public static int castInt(Object obj, int defaultValue) {
        int intValue = defaultValue;
        if (obj != null) {
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)) {
                try {
                    intValue = Integer.parseInt(strValue);
                } catch (NumberFormatException e) {
                    intValue = defaultValue;
                }
            }
        }
        return intValue;
    }

    // 转为 boolean 型
    public static boolean castBoolean(Object obj) {
        return CastUtil.castBoolean(obj, false);
    }

    // 转为 boolean 型（提供默认值）
    public static boolean castBoolean(Object obj, boolean defaultValue) {
        boolean booleanValue = defaultValue;
        if (obj != null) {
            booleanValue = Boolean.parseBoolean(castString(obj));
        }
        return booleanValue;
    }

    // 转为 String[] 型
    public static String[] castStringArray(Object[] objArray) {
        if (objArray == null) {
            objArray = new Object[0];
        }
        String[] strArray = new String[objArray.length];
        if (ArrayUtil.isNotEmpty(objArray)) {
            for (int i = 0; i < objArray.length; i++) {
                strArray[i] = castString(objArray[i]);
            }
        }
        return strArray;
    }

    // 转为 double[] 型
    public static double[] castDoubleArray(Object[] objArray) {
        if (objArray == null) {
            objArray = new Object[0];
        }
        double[] doubleArray = new double[objArray.length];
        if (!ArrayUtil.isEmpty(objArray)) {
            for (int i = 0; i < objArray.length; i++) {
                doubleArray[i] = castDouble(objArray[i]);
            }
        }
        return doubleArray;
    }

    // 转为 long[] 型
    public static long[] castLongArray(Object[] objArray) {
        if (objArray == null) {
            objArray = new Object[0];
        }
        long[] longArray = new long[objArray.length];
        if (!ArrayUtil.isEmpty(objArray)) {
            for (int i = 0; i < objArray.length; i++) {
                longArray[i] = castLong(objArray[i]);
            }
        }
        return longArray;
    }

    // 转为 int[] 型
    public static int[] castIntArray(Object[] objArray) {
        if (objArray == null) {
            objArray = new Object[0];
        }
        int[] intArray = new int[objArray.length];
        if (!ArrayUtil.isEmpty(objArray)) {
            for (int i = 0; i < objArray.length; i++) {
                intArray[i] = castInt(objArray[i]);
            }
        }
        return intArray;
    }

    // 转为 boolean[] 型
    public static boolean[] castBooleanArray(Object[] objArray) {
        if (objArray == null) {
            objArray = new Object[0];
        }
        boolean[] booleanArray = new boolean[objArray.length];
        if (!ArrayUtil.isEmpty(objArray)) {
            for (int i = 0; i < objArray.length; i++) {
                booleanArray[i] = castBoolean(objArray[i]);
            }
        }
        return booleanArray;
    }
} public class MapUtil {

    // 判断 Map 是否非空
    public static boolean isNotEmpty(Map<?, ?> map) {
        return MapUtils.isNotEmpty(map);
    }

    // 判断 Map 是否为空
    public static boolean isEmpty(Map<?, ?> map) {
        return MapUtils.isEmpty(map);
    }
} public class StringUtil {

    // 字符串分隔符
    public static final String SEPARATOR = String.valueOf((char) 29);

    // 判断字符串是否非空
    public static boolean isNotEmpty(String str) {
        return StringUtils.isNotEmpty(str);
    }

    // 判断字符串是否为空
    public static boolean isEmpty(String str) {
        return StringUtils.isEmpty(str);
    }

    // 若字符串为空，则取默认值
    public static String defaultIfEmpty(String str, String defaultValue) {
        return StringUtils.defaultIfEmpty(str, defaultValue);
    }

    // 替换固定格式的字符串（支持正则表达式）
    public static String replaceAll(String str, String regex, String replacement) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(sb, replacement);
        }
        m.appendTail(sb);
        return sb.toString();
    }

    // 是否为数字（整数或小数）
    public static boolean isNumber(String str) {
        return NumberUtils.isNumber(str);
    }

    // 是否为十进制数（整数）
    public static boolean isDigits(String str) {
        return NumberUtils.isDigits(str);
    }

    // 将驼峰风格替换为下划线风格
    public static String camelhumpToUnderline(String str) {
        Matcher matcher = Pattern.compile("[A-Z]").matcher(str);
        StringBuilder builder = new StringBuilder(str);
        for (int i = 0; matcher.find(); i++) {
            builder.replace(matcher.start() + i, matcher.end() + i, "_" + matcher.group().toLowerCase());
        }
        if (builder.charAt(0) == '_') {
            builder.deleteCharAt(0);
        }
        return builder.toString();
    }

    // 将下划线风格替换为驼峰风格
    public static String underlineToCamelhump(String str) {
        Matcher matcher = Pattern.compile("_[a-z]").matcher(str);
        StringBuilder builder = new StringBuilder(str);
        for (int i = 0; matcher.find(); i++) {
            builder.replace(matcher.start() - i, matcher.end() - i, matcher.group().substring(1).toUpperCase());
        }
        if (Character.isUpperCase(builder.charAt(0))) {
            builder.replace(0, 1, String.valueOf(Character.toLowerCase(builder.charAt(0))));
        }
        return builder.toString();
    }

    // 分割固定格式的字符串
    public static String[] splitString(String str, String separator) {
        return StringUtils.splitByWholeSeparator(str, separator);
    }

    // 将字符串首字母大写
    public static String firstToUpper(String str) {
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }

    // 将字符串首字母小写
    public static String firstToLower(String str) {
        return Character.toLowerCase(str.charAt(0)) + str.substring(1);
    }

    // 转为帕斯卡命名方式（如：FooBar）
    public static String toPascalStyle(String str, String seperator) {
        return StringUtil.firstToUpper(toCamelhumpStyle(str, seperator));
    }

    // 转为驼峰命令方式（如：fooBar）
    public static String toCamelhumpStyle(String str, String seperator) {
        return StringUtil.underlineToCamelhump(toUnderlineStyle(str, seperator));
    }

    // 转为下划线命名方式（如：foo_bar）
    public static String toUnderlineStyle(String str, String seperator) {
        str = str.trim().toLowerCase();
        if (str.contains(seperator)) {
            str = str.replace(seperator, "_");
        }
        return str;
    }

    // 转为显示命名方式（如：Foo Bar）
    public static String toDisplayStyle(String str, String seperator) {
        String displayName = "";
        str = str.trim().toLowerCase();
        if (str.contains(seperator)) {
            String[] words = StringUtil.splitString(str, seperator);
            for (String word : words) {
                displayName += StringUtil.firstToUpper(word) + " ";
            }
            displayName = displayName.trim();
        } else {
            displayName = StringUtil.firstToUpper(str);
        }
        return displayName;
    }
} public class WebUtil {

    private static final Logger logger = Logger.getLogger(WebUtil.class);

    // 将数据以纯文本格式写入响应中
    public static void writeText(HttpServletResponse response, Object data) {
        try {
            // 设置响应头
            response.setContentType("text/plain"); // 指定内容类型为纯文本格式
            response.setCharacterEncoding(Constant.DEFAULT_CHARSET); // 防止中文乱码

            // 向响应中写入数据
            PrintWriter writer = response.getWriter();
            writer.write(data + ""); // 转为字符串
        } catch (Exception e) {
            logger.error("在响应中写数据出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 将数据以 JSON 格式写入响应中
    public static void writeJSON(HttpServletResponse response, Object data) {
        try {
            // 设置响应头
            response.setContentType("application/json"); // 指定内容类型为 JSON 格式
            response.setCharacterEncoding(Constant.DEFAULT_CHARSET); // 防止中文乱码

            // 向响应中写入数据
            PrintWriter writer = response.getWriter();
            writer.write(JSONUtil.toJSON(data)); // 转为 JSON 字符串
        } catch (Exception e) {
            logger.error("在响应中写数据出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 将数据以 HTML 格式写入响应中（在 JS 中获取的是 JSON 字符串，而不是 JSON 对象）
    public static void writeHTML(HttpServletResponse response, Object data) {
        try {
            // 设置响应头
            response.setContentType("text/html"); // 指定内容类型为 HTML 格式
            response.setCharacterEncoding(Constant.DEFAULT_CHARSET); // 防止中文乱码

            // 向响应中写入数据
            PrintWriter writer = response.getWriter();
            writer.write(JSONUtil.toJSON(data)); // 转为 JSON 字符串
        } catch (Exception e) {
            logger.error("在响应中写数据出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 获取上传文件路径
    public static String getUploadFilePath(HttpServletRequest request, String relativePath) {
        // 返回绝对路径
        return request.getServletContext().getRealPath("") + relativePath;
    }

    // 获取上传文件名
    public static String getUploadFileName(HttpServletRequest request, Part part) {
        // 防止中文乱码（可放在 EncodingFilter 中处理）
//        request.setCharacterEncoding(Constant.DEFAULT_CHARSET);

        // 从请求头中获取文件名
        String cd = part.getHeader("Content-Disposition");
        String fileName = cd.substring(cd.lastIndexOf("=") + 2, cd.length() - 1);

        // 解决 IE 浏览器文件名问题
        if (fileName.contains("\\")) {
            fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
        }

        return fileName;
    }

    // 从请求中获取所有参数（当参数名重复时，用后者覆盖前者）
    public static Map<String, String> getRequestParamMap(HttpServletRequest request) {
        Map<String, String> paramMap = new LinkedHashMap<String, String>();
        try {
            String method = request.getMethod();
            if (method.equalsIgnoreCase("put") || method.equalsIgnoreCase("delete")) {
                String queryString = CodecUtil.decodeUTF8(StreamUtil.toString(request.getInputStream()));
                if (StringUtil.isNotEmpty(queryString)) {
                    String[] qsArray = StringUtil.splitString(queryString, "&");
                    if (ArrayUtil.isNotEmpty(qsArray)) {
                        for (String qs : qsArray) {
                            String[] array = StringUtil.splitString(qs, "=");
                            if (ArrayUtil.isNotEmpty(array) && array.length == 2) {
                                String paramName = array[0];
                                String paramValue = array[1];
                                if (checkParamName(paramName)) {
                                    paramMap.put(paramName, paramValue);
                                }
                            }
                        }
                    }
                }
            } else {
                Enumeration<String> paramNames = request.getParameterNames();
                while (paramNames.hasMoreElements()) {
                    String paramName = paramNames.nextElement();
                    if (checkParamName(paramName)) {
                        String[] paramValues = request.getParameterValues(paramName);
                        if (ArrayUtil.isNotEmpty(paramValues)) {
                            if (paramValues.length == 1) {
                                paramMap.put(paramName, paramValues[0]);
                            } else {
                                StringBuilder paramValue = new StringBuilder("");
                                for (int i = 0; i < paramValues.length; i++) {
                                    paramValue.append(paramValues[i]);
                                    if (i != paramValues.length - 1) {
                                        paramValue.append(StringUtil.SEPARATOR);
                                    }
                                }
                                paramMap.put(paramName, paramValue.toString());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("获取请求参数出错！", e);
            throw new RuntimeException(e);
        }
        return paramMap;
    }

    private static boolean checkParamName(String paramName) {
        return !paramName.equals("_"); // 忽略 jQuery 缓存参数
    }

    // 创建查询映射（查询字符串格式：a:1;b:2）
    public static Map<String, String> createQueryMap(String queryString) {
        Map<String, String> queryMap = new HashMap<String, String>();
        if (StringUtil.isNotEmpty(queryString)) {
            String[] queryArray = queryString.split(";");
            if (ArrayUtil.isNotEmpty(queryArray)) {
                for (String query : queryArray) {
                    String[] fieldArray = query.split(":");
                    if (ArrayUtil.isNotEmpty(fieldArray) && fieldArray.length == 2) {
                        queryMap.put(fieldArray[0], fieldArray[1]);
                    }
                }
            }
        }
        return queryMap;
    }

    // 转发请求
    public static void forwardRequest(String path, HttpServletRequest request, HttpServletResponse response) {
        try {
            request.getRequestDispatcher(path).forward(request, response);
        } catch (Exception e) {
            logger.error("转发请求出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 重定向请求
    public static void redirectRequest(String path, HttpServletRequest request, HttpServletResponse response) {
        try {
            response.sendRedirect(request.getContextPath() + path);
        } catch (Exception e) {
            logger.error("重定向请求出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 发送错误代码
    public static void sendError(int code, HttpServletResponse response) {
        try {
            response.sendError(code);
        } catch (Exception e) {
            logger.error("发送错误代码出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 判断是否为 AJAX 请求
    public static boolean isAJAX(HttpServletRequest request) {
        return request.getHeader("X-Requested-With") != null;
    }

    // 获取请求路径
    public static String getRequestPath(HttpServletRequest request) {
        String servletPath = request.getServletPath();
        String pathInfo = StringUtil.defaultIfEmpty(request.getPathInfo(), "");
        return servletPath + pathInfo;
    }

    // 将数据放入 Cookie 中
    public static void addCookie(HttpServletResponse response, String name, String value, String domain, int expires) {
        try {
            if (StringUtil.isNotEmpty(name)) {
                value = CodecUtil.encodeUTF8(value);
                Cookie cookie = new Cookie(name, value);
                cookie.setDomain(domain);
                cookie.setMaxAge(expires);
                response.addCookie(cookie);
            }
        } catch (Exception e) {
            logger.error("添加 Cookie 出错！", e);
            throw new RuntimeException(e);
        }
    }

    // 从 Cookie 中获取数据
    public static String getCookie(HttpServletRequest request, String name) {
        String value = "";
        try {
            Cookie[] cookieArray = request.getCookies();
            if (cookieArray != null) {
                for (Cookie cookie : cookieArray) {
                    if (StringUtil.isNotEmpty(name) && name.equals(cookie.getName())) {
                        value = CodecUtil.decodeUTF8(cookie.getValue());
                        break;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("获取 Cookie 出错！", e);
            throw new RuntimeException(e);
        }
        return value;
    }
}
import com.tkhoon.framework.bean.ActionBean;
import com.tkhoon.framework.bean.Page;
import com.tkhoon.framework.bean.RequestBean;
import com.tkhoon.framework.bean.Result;
import com.tkhoon.framework.helper.ActionHelper;
import com.tkhoon.framework.helper.BeanHelper;
import com.tkhoon.framework.helper.ConfigHelper;
import com.tkhoon.framework.util.CastUtil;
import com.tkhoon.framework.util.MapUtil;
import com.tkhoon.framework.util.StringUtil;
import com.tkhoon.framework.util.WebUtil;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
package com.tkhoon.framework;



@WebServlet("/*")
public class DispatcherServlet extends HttpServlet {

    private static final Logger logger = Logger.getLogger(DispatcherServlet.class);

    // 获取相关配置项
    private final String homePage = ConfigHelper.getStringProperty(Constant.APP_HOME_PAGE);
    private final String jspPath = ConfigHelper.getStringProperty(Constant.APP_JSP_PATH);

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取当前请求相关数据
        String currentRequestMethod = request.getMethod();
        String currentRequestPath = WebUtil.getRequestPath(request);
        if (logger.isDebugEnabled()) {
            logger.debug(currentRequestMethod + ":" + currentRequestPath);
        }
        // 将“/”请求重定向到首页
        if (currentRequestPath.equals("/")) {
            WebUtil.redirectRequest(homePage, request, response);
            return;
        }
        // 去掉当前请求路径末尾的“/”
        if (currentRequestPath.endsWith("/")) {
            currentRequestPath = currentRequestPath.substring(0, currentRequestPath.length() - 1);
        }
        // 定义一个 JSP 映射标志（默认为映射失败）
        boolean jspMapped = false;
        // 初始化 DataContext
        DataContext.init(request, response);
        // 获取请求参数映射（包括：Query String 与 Form Data）
        Map<String, String> requestParamMap = WebUtil.getRequestParamMap(request);
        try {
            // 获取并遍历 Action 映射
            Map<RequestBean, ActionBean> actionMap = ActionHelper.getActionMap();
            for (Map.Entry<RequestBean, ActionBean> actionEntry : actionMap.entrySet()) {
                // 从 RequestBean 中获取 Request 相关属性
                RequestBean requestBean = actionEntry.getKey();
                String requestMethod = requestBean.getRequestMethod();
                String requestPath = requestBean.getRequestPath(); // 正则表达式
                // 获取正则表达式匹配器（用于匹配请求路径并从中获取相应的请求参数）
                Matcher matcher = Pattern.compile(requestPath).matcher(currentRequestPath);
                // 判断请求方法与请求路径是否同时匹配
                if (requestMethod.equalsIgnoreCase(currentRequestMethod) && matcher.matches()) {
                    // 获取 Action 对象
                    ActionBean actionBean = actionEntry.getValue();
                    // 获取 Action 方法参数类型
                    Class<?>[] requestParamTypes = actionBean.getActionMethod().getParameterTypes();
                    // 创建 Action 方法参数列表
                    List<Object> paramList = createParamList(matcher, requestParamMap, requestParamTypes);
                    // 处理 Action 方法
                    handleActionMethod(request, response, actionBean, paramList);
                    // 设置为映射成功
                    jspMapped = true;
                    // 若成功匹配，则终止循环
                    break;
                }
            }
        } finally {
            // 销毁 DataContext
            DataContext.destroy();
        }
        // 若 JSP 映射失败，则根据默认路由规则转发请求
        if (!jspMapped && StringUtil.isNotEmpty(jspPath)) {
            // 获取路径（默认路由规则：/{1}/{2} => /xxx/{1}_{2}.jsp）
            String path = jspPath + currentRequestPath.substring(1).replace("/", "_") + ".jsp";
            // 转发请求
            request.setAttribute("path", path);
            WebUtil.forwardRequest(path, request, response);
        }
    }

    private List<Object> createParamList(Matcher matcher, Map<String, String> requestParamMap, Class<?>[] requestParamTypes) {
        List<Object> paramList = new ArrayList<Object>();
        // 遍历正则表达式中所匹配的组
        for (int i = 1; i <= matcher.groupCount(); i++) {
            // 获取请求参数
            String param = matcher.group(i);
            // 获取参数类型（支持四种类型：int/Integer、long/Long、double/Double、String）
            Class<?> paramType = requestParamTypes[i - 1];
            if (paramType.equals(int.class) || paramType.equals(Integer.class)) {
                paramList.add(CastUtil.castInt(param));
            } else if (paramType.equals(long.class) || paramType.equals(Long.class)) {
                paramList.add(CastUtil.castLong(param));
            } else if (paramType.equals(double.class) || paramType.equals(Double.class)) {
                paramList.add(CastUtil.castDouble(param));
            } else if (paramType.equals(String.class)) {
                paramList.add(param);
            }
        }
        // 向参数列表中添加请求参数映射
        if (MapUtil.isNotEmpty(requestParamMap)) {
            paramList.add(requestParamMap);
        }
        return paramList;
    }

    private void handleActionMethod(HttpServletRequest request, HttpServletResponse response, ActionBean actionBean, List<Object> paramList) {
        // 从 ActionBean 中获取 Action 相关属性
        Class<?> actionClass = actionBean.getActionClass();
        Method actionMethod = actionBean.getActionMethod();
        // 从 BeanHelper 中创建 Action 实例
        Object actionInstance = BeanHelper.getBean(actionClass);