=localCacheData.getTimeoutTime()) {
+// cacheRepository.remove(key);
+// }
+// }
+// }
+// return true;
+// }
+//
+//}
diff --git a/src/main/java/com/xxl/tool/exception/BizException.java b/src/main/java/com/xxl/tool/exception/BizException.java
new file mode 100644
index 0000000..3739bb0
--- /dev/null
+++ b/src/main/java/com/xxl/tool/exception/BizException.java
@@ -0,0 +1,19 @@
+package com.xxl.tool.exception;
+
+/**
+ * @author xuxueli 2024-06-30
+ */
+public class BizException extends RuntimeException {
+
+ public BizException() {
+ }
+
+ public BizException(String message) {
+ super(message);
+ }
+
+ public BizException(Throwable cause) {
+ super(cause);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/xxl/tool/ftl/FtlTool.java b/src/main/java/com/xxl/tool/ftl/FtlTool.java
new file mode 100644
index 0000000..daa0d39
--- /dev/null
+++ b/src/main/java/com/xxl/tool/ftl/FtlTool.java
@@ -0,0 +1,41 @@
+package com.xxl.tool.ftl;
+
+import com.xxl.tool.exception.BizException;
+import freemarker.ext.beans.BeansWrapper;
+import freemarker.ext.beans.BeansWrapperBuilder;
+import freemarker.template.Configuration;
+import freemarker.template.TemplateHashModel;
+
+/**
+ * ftl tool
+ *
+ * @author xuxueli 2018-01-17 20:37:48
+ */
+public class FtlTool {
+
+ // 静态包装器
+ private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); //BeansWrapper.getDefaultInstance();
+
+ /**
+ * 生成 freemarker 自定义方法
+ *
+ *
+ * // 自定义方法包装;
+ * TemplateHashModel model = FtlTool.generateStaticModel(I18nUtil.class.getName())
+ * // 注入SpringMVC响应对象,逻辑运营在 “AsyncHandlerInterceptor.postHandle” 中;
+ * modelAndView.addObject("I18nUtil", model);
+ *
+ *
+ * @param packageName
+ * @return
+ */
+ public static TemplateHashModel generateStaticModel(String packageName) {
+ try {
+ TemplateHashModel staticModels = wrapper.getStaticModels();
+ TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName);
+ return fileStatics;
+ } catch (Exception e) {
+ throw new BizException(e);
+ }
+ }
+}
diff --git a/src/main/java/com/xxl/tool/net/CookieTool.java b/src/main/java/com/xxl/tool/net/CookieTool.java
new file mode 100644
index 0000000..9d077ae
--- /dev/null
+++ b/src/main/java/com/xxl/tool/net/CookieTool.java
@@ -0,0 +1,139 @@
+package com.xxl.tool.net;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+/**
+ * Cookie Tool
+ *
+ * @author xuxueli 2015-12-12 18:01:06
+ */
+public class CookieTool {
+
+ /**
+ * 默认缓存时间,单位/秒, 2H
+ */
+ private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE;
+ /**
+ * 保存路径,根路径
+ */
+ private static final String COOKIE_PATH = "/";
+
+ /**
+ * add cookie
+ *
+ * @param response
+ * @param key
+ * @param value
+ * @param domain
+ * @param path
+ * @param maxAge : >0 存活秒数,=0 删除, <0 浏览器推出则销毁;
+ * @param isHttpOnly
+ */
+ private static void set(HttpServletResponse response, String key, String value,
+ String domain, String path, int maxAge, boolean isHttpOnly) {
+
+ // encode value
+ try {
+ value = URLEncoder.encode(value, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException();
+ }
+
+ // add cookie
+ Cookie cookie = new Cookie(key, value);
+ if (domain != null) {
+ cookie.setDomain(domain);
+ }
+ cookie.setPath(path);
+ cookie.setMaxAge(maxAge);
+ cookie.setHttpOnly(isHttpOnly);
+ response.addCookie(cookie);
+ }
+
+ /**
+ * 新增 cookie
+ *
+ * @param response
+ * @param key
+ * @param value
+ * @param ifRemember : true - 永不过期,false - 浏览器推出则销毁;
+ */
+ public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) {
+ int age = ifRemember?COOKIE_MAX_AGE:-1;
+ set(response, key, value, null, COOKIE_PATH, age, true);
+ }
+
+ /**
+ * 新增 cookie
+ *
+ * @param response
+ * @param key
+ * @param value
+ * @param maxAge
+ */
+ public static void set(HttpServletResponse response, String key, String value, int maxAge) {
+ set(response, key, value, null, COOKIE_PATH, maxAge, true);
+ }
+
+ /**
+ * 删除 cookie
+ *
+ * @param request
+ * @param response
+ * @param key
+ */
+ public static void remove(HttpServletRequest request, HttpServletResponse response, String key) {
+ Cookie cookie = get(request, key);
+ if (cookie != null) {
+ set(response, key, "", null, COOKIE_PATH, 0, true);
+ }
+ }
+
+ /**
+ * get cookie
+ *
+ * @param request
+ * @param key
+ */
+ private static Cookie get(HttpServletRequest request, String key) {
+ Cookie[] arr_cookie = request.getCookies();
+ if (arr_cookie != null && arr_cookie.length > 0) {
+ for (Cookie cookie : arr_cookie) {
+ if (cookie.getName().equals(key)) {
+ return cookie;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 查询 cookie value
+ *
+ * @param request
+ * @param key
+ * @return
+ */
+ public static String getValue(HttpServletRequest request, String key) {
+ Cookie cookie = get(request, key);
+ if (cookie == null) {
+ return null;
+ }
+
+ // decode value
+ String value = cookie.getValue();
+ try {
+ value = URLDecoder.decode(value, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ return value;
+ }
+
+}
\ No newline at end of file