This commit is contained in:
Looly 2023-04-24 11:35:14 +08:00
parent 9e49100f03
commit e67bbdec19
29 changed files with 361 additions and 203 deletions

View File

@ -1,83 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.aop;
import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.core.spi.SpiUtil;
import java.io.Serializable;
/**
* 代理工厂<br>
* 根据用户引入代理库的不同产生不同的代理对象
*
* @author looly
*/
public interface ProxyFactory extends Serializable {
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
* @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/
static <T> T createProxy(final T target, final Class<? extends Aspect> aspectClass) {
return createProxy(target, ConstructorUtil.newInstance(aspectClass));
}
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
static <T> T createProxy(final T target, final Aspect aspect) {
return of().proxy(target, aspect);
}
/**
* 根据用户引入Cglib与否创建代理工厂
*
* @return 代理工厂
*/
static ProxyFactory of() {
return SpiUtil.loadFirstAvailable(ProxyFactory.class);
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类自动实例化
* @return 代理对象
* @since 5.3.1
*/
default <T> T proxy(final T target, final Class<? extends Aspect> aspectClass) {
return proxy(target, ConstructorUtil.newInstanceIfPossible(aspectClass));
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
<T> T proxy(T target, Aspect aspect);
}

View File

@ -13,41 +13,54 @@
package org.dromara.hutool.extra.aop; package org.dromara.hutool.extra.aop;
import org.dromara.hutool.core.classloader.ClassLoaderUtil; import org.dromara.hutool.core.classloader.ClassLoaderUtil;
import org.dromara.hutool.extra.aop.engine.ProxyEngine;
import org.dromara.hutool.extra.aop.engine.ProxyEngineFactory;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
/** /**
* 代理工具类 * 代理工具类
* @author Looly
* *
* @author Looly
*/ */
public final class ProxyUtil { public final class ProxyUtil {
/** /**
* 使用切面代理对象 * 获取动态代理引擎
* *
* @param <T> 切面对象类型 * @return {@link ProxyEngine}
* @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/ */
public static <T> T proxy(final T target, final Class<? extends Aspect> aspectClass){ public static ProxyEngine getEngine() {
return ProxyFactory.createProxy(target, aspectClass); return ProxyEngineFactory.getEngine();
} }
/** /**
* 使用切面代理对象 * 使用切面代理对象
* *
* @param <T> 被代理对象类型 * @param <T> 切面对象类型
* @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/
public static <T> T proxy(final T target, final Class<? extends Aspect> aspectClass) {
return getEngine().proxy(target, aspectClass);
}
/**
* 使用切面代理对象
*
* @param <T> 被代理对象类型
* @param target 被代理对象 * @param target 被代理对象
* @param aspect 切面对象 * @param aspect 切面对象
* @return 代理对象 * @return 代理对象
*/ */
public static <T> T proxy(final T target, final Aspect aspect){ public static <T> T proxy(final T target, final Aspect aspect) {
return ProxyFactory.createProxy(target, aspect); return getEngine().proxy(target, aspect);
} }
// region ----- JDK Proxy utils
/** /**
* 创建动态代理对象<br> * 创建动态代理对象<br>
* 动态代理对象的创建原理是<br> * 动态代理对象的创建原理是<br>
@ -58,10 +71,10 @@ public final class ProxyUtil {
* 4将$Proxy0的实例返回给客户端 <br> * 4将$Proxy0的实例返回给客户端 <br>
* 5当调用代理类的相应方法时相当于调用 {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])} 方法 * 5当调用代理类的相应方法时相当于调用 {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])} 方法
* *
* @param <T> 被代理对象类型 * @param <T> 被代理对象类型
* @param classloader 被代理类对应的ClassLoader * @param classloader 被代理类对应的ClassLoader
* @param invocationHandler {@link InvocationHandler} 被代理类通过实现此接口提供动态代理功能 * @param invocationHandler {@link InvocationHandler} 被代理类通过实现此接口提供动态代理功能
* @param interfaces 代理类中需要实现的被代理类的接口方法 * @param interfaces 代理类中需要实现的被代理类的接口方法
* @return 代理类 * @return 代理类
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -72,12 +85,13 @@ public final class ProxyUtil {
/** /**
* 创建动态代理对象 * 创建动态代理对象
* *
* @param <T> 被代理对象类型 * @param <T> 被代理对象类型
* @param invocationHandler {@link InvocationHandler} 被代理类通过实现此接口提供动态代理功能 * @param invocationHandler {@link InvocationHandler} 被代理类通过实现此接口提供动态代理功能
* @param interfaces 代理类中需要实现的被代理类的接口方法 * @param interfaces 代理类中需要实现的被代理类的接口方法
* @return 代理类 * @return 代理类
*/ */
public static <T> T newProxyInstance(final InvocationHandler invocationHandler, final Class<?>... interfaces) { public static <T> T newProxyInstance(final InvocationHandler invocationHandler, final Class<?>... interfaces) {
return newProxyInstance(ClassLoaderUtil.getClassLoader(), invocationHandler, interfaces); return newProxyInstance(ClassLoaderUtil.getClassLoader(), invocationHandler, interfaces);
} }
// endregion
} }

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.aop.engine;
import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.extra.aop.Aspect;
/**
* 动态代理引擎接口
*
* @author looly
* @since 6.0.0
*/
public interface ProxyEngine {
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
<T> T proxy(T target, Aspect aspect);
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类自动实例化
* @return 代理对象
* @since 5.3.1
*/
default <T> T proxy(final T target, final Class<? extends Aspect> aspectClass) {
return proxy(target, ConstructorUtil.newInstanceIfPossible(aspectClass));
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.aop.engine;
import org.dromara.hutool.core.lang.Singleton;
import org.dromara.hutool.core.spi.SpiUtil;
/**
* 代理引擎简单工厂<br>
* 根据用户引入代理库的不同产生不同的代理引擎对象
*
* @author looly
*/
public class ProxyEngineFactory {
/**
* 获得单例的ProxyEngine
*
* @return 单例的ProxyEngine
*/
public static ProxyEngine getEngine() {
return Singleton.get(ProxyEngine.class.getName(), ProxyEngineFactory::createEngine);
}
/**
* 根据用户引入Cglib与否创建代理工厂
*
* @return 代理工厂
*/
public static ProxyEngine createEngine() {
return SpiUtil.loadFirstAvailable(ProxyEngine.class);
}
}

View File

@ -12,17 +12,16 @@
package org.dromara.hutool.extra.aop.engine.jdk; package org.dromara.hutool.extra.aop.engine.jdk;
import org.dromara.hutool.extra.aop.ProxyFactory;
import org.dromara.hutool.extra.aop.ProxyUtil;
import org.dromara.hutool.extra.aop.Aspect; import org.dromara.hutool.extra.aop.Aspect;
import org.dromara.hutool.extra.aop.ProxyUtil;
import org.dromara.hutool.extra.aop.engine.ProxyEngine;
/** /**
* JDK实现的切面代理 * JDK实现的切面代理
* *
* @author looly * @author looly
*/ */
public class JdkProxyFactory implements ProxyFactory { public class JdkProxyEngine implements ProxyEngine {
private static final long serialVersionUID = 1L;
@Override @Override
public <T> T proxy(final T target, final Aspect aspect) { public <T> T proxy(final T target, final Aspect aspect) {

View File

@ -12,8 +12,8 @@
package org.dromara.hutool.extra.aop.engine.spring; package org.dromara.hutool.extra.aop.engine.spring;
import org.dromara.hutool.extra.aop.ProxyFactory;
import org.dromara.hutool.extra.aop.Aspect; import org.dromara.hutool.extra.aop.Aspect;
import org.dromara.hutool.extra.aop.engine.ProxyEngine;
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.Enhancer;
/** /**
@ -22,8 +22,7 @@ import org.springframework.cglib.proxy.Enhancer;
* @author looly * @author looly
* *
*/ */
public class SpringCglibProxyFactory implements ProxyFactory { public class SpringCglibProxyEngine implements ProxyEngine {
private static final long serialVersionUID = 1L;
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -17,6 +17,10 @@
* <li>基于Spring-cglib代理</li> * <li>基于Spring-cglib代理</li>
* </ul> * </ul>
* 考虑到cglib库不再更新且对JDK9+兼容性问题不再封装 * 考虑到cglib库不再更新且对JDK9+兼容性问题不再封装
* <pre>
* createEngine proxy
* ProxyEngineFactory = ProxyEngine = Proxy
* </pre>
* *
* @author looly * @author looly
* *

View File

@ -13,37 +13,75 @@
package org.dromara.hutool.extra.pinyin; package org.dromara.hutool.extra.pinyin;
import org.dromara.hutool.core.exception.ExceptionUtil; import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
/** /**
* 模板异常 * 模板异常
* *
* @author xiaoleilu * @author looly
*/ */
public class PinyinException extends RuntimeException { public class PinyinException extends HutoolException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 构造
*
* @param e 异常
*/
public PinyinException(final Throwable e) { public PinyinException(final Throwable e) {
super(ExceptionUtil.getMessage(e), e); super(e);
} }
/**
* 构造
*
* @param message 消息
*/
public PinyinException(final String message) { public PinyinException(final String message) {
super(message); super(message);
} }
/**
* 构造
*
* @param messageTemplate 消息模板
* @param params 参数
*/
public PinyinException(final String messageTemplate, final Object... params) { public PinyinException(final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params)); super(messageTemplate, params);
} }
public PinyinException(final String message, final Throwable throwable) { /**
super(message, throwable); * 构造
*
* @param message 消息
* @param cause 被包装的子异常
*/
public PinyinException(final String message, final Throwable cause) {
super(message, cause);
} }
public PinyinException(final String message, final Throwable throwable, final boolean enableSuppression, final boolean writableStackTrace) { /**
super(message, throwable, enableSuppression, writableStackTrace); * 构造
*
* @param message 消息
* @param cause 被包装的子异常
* @param enableSuppression 是否启用抑制
* @param writableStackTrace 堆栈跟踪是否应该是可写的
*/
public PinyinException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
} }
public PinyinException(final Throwable throwable, final String messageTemplate, final Object... params) { /**
super(StrUtil.format(messageTemplate, params), throwable); * 构造
*
* @param cause 被包装的子异常
* @param messageTemplate 消息模板
* @param params 参数
*/
public PinyinException(final Throwable cause, final String messageTemplate, final Object... params) {
super(cause, messageTemplate, params);
} }
} }

View File

@ -12,25 +12,26 @@
package org.dromara.hutool.extra.pinyin; package org.dromara.hutool.extra.pinyin;
import org.dromara.hutool.core.regex.PatternPool;
import org.dromara.hutool.core.regex.ReUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.pinyin.engine.PinyinFactory; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import org.dromara.hutool.extra.pinyin.engine.PinyinEngineFactory;
/** /**
* 拼音工具类封装了TinyPinyinJPinyinPinyin4j通过SPI自动识别 * 拼音工具类用于快速获取拼音
* *
* @author looly * @author looly
*/ */
public class PinyinUtil { public class PinyinUtil {
private static final String CHINESE_REGEX = "[\\u4e00-\\u9fa5]";
/** /**
* 获得全局单例的拼音引擎 * 获得全局单例的拼音引擎
* *
* @return 全局单例的拼音引擎 * @return 全局单例的拼音引擎
*/ */
public static PinyinEngine getEngine(){ public static PinyinEngine getEngine() {
return PinyinFactory.get(); return PinyinEngineFactory.getEngine();
} }
/** /**
@ -92,6 +93,6 @@ public class PinyinUtil {
* @return 是否为中文字符 * @return 是否为中文字符
*/ */
public static boolean isChinese(final char c) { public static boolean isChinese(final char c) {
return '' == c || String.valueOf(c).matches(CHINESE_REGEX); return '' == c || ReUtil.isMatch(PatternPool.CHINESE, String.valueOf(c));
} }
} }

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.extra.pinyin; package org.dromara.hutool.extra.pinyin.engine;
import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;

View File

@ -15,24 +15,24 @@ package org.dromara.hutool.extra.pinyin.engine;
import org.dromara.hutool.core.lang.Singleton; import org.dromara.hutool.core.lang.Singleton;
import org.dromara.hutool.core.spi.SpiUtil; import org.dromara.hutool.core.spi.SpiUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.pinyin.PinyinEngine;
import org.dromara.hutool.extra.pinyin.PinyinException; import org.dromara.hutool.extra.pinyin.PinyinException;
import org.dromara.hutool.log.StaticLog; import org.dromara.hutool.log.StaticLog;
/** /**
* 简单拼音引擎工厂用于根据用户引入的拼音库jar自动创建对应的拼音引擎对象 * 简单拼音引擎工厂用于根据用户引入的拼音库jar自动创建对应的拼音引擎对象<br>
* 使用简单工厂Simple Factory模式
* *
* @author looly * @author looly
*/ */
public class PinyinFactory { public class PinyinEngineFactory {
/** /**
* 获得单例的PinyinEngine * 获得单例的PinyinEngine
* *
* @return 单例的PinyinEngine * @return 单例的PinyinEngine
*/ */
public static PinyinEngine get(){ public static PinyinEngine getEngine(){
return Singleton.get(PinyinEngine.class.getName(), PinyinFactory::of); return Singleton.get(PinyinEngine.class.getName(), PinyinEngineFactory::createEngine);
} }
/** /**
@ -41,8 +41,8 @@ public class PinyinFactory {
* *
* @return {@link PinyinEngine} * @return {@link PinyinEngine}
*/ */
public static PinyinEngine of() { public static PinyinEngine createEngine() {
final PinyinEngine engine = doCreate(); final PinyinEngine engine = doCreateEngine();
StaticLog.debug("Use [{}] Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine")); StaticLog.debug("Use [{}] Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine"));
return engine; return engine;
} }
@ -53,7 +53,7 @@ public class PinyinFactory {
* *
* @return {@link PinyinEngine} * @return {@link PinyinEngine}
*/ */
private static PinyinEngine doCreate() { private static PinyinEngine doCreateEngine() {
final PinyinEngine engine = SpiUtil.loadFirstAvailable(PinyinEngine.class); final PinyinEngine engine = SpiUtil.loadFirstAvailable(PinyinEngine.class);
if(null != engine){ if(null != engine){
return engine; return engine;

View File

@ -13,7 +13,7 @@
package org.dromara.hutool.extra.pinyin.engine.bopomofo4j; package org.dromara.hutool.extra.pinyin.engine.bopomofo4j;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.pinyin.PinyinEngine; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import com.rnkrsoft.bopomofo4j.Bopomofo4j; import com.rnkrsoft.bopomofo4j.Bopomofo4j;
import com.rnkrsoft.bopomofo4j.ToneType; import com.rnkrsoft.bopomofo4j.ToneType;
@ -39,6 +39,9 @@ import com.rnkrsoft.bopomofo4j.ToneType;
*/ */
public class Bopomofo4jEngine implements PinyinEngine { public class Bopomofo4jEngine implements PinyinEngine {
/**
* 构造
*/
public Bopomofo4jEngine(){ public Bopomofo4jEngine(){
Bopomofo4j.local(); Bopomofo4j.local();
} }

View File

@ -12,7 +12,7 @@
package org.dromara.hutool.extra.pinyin.engine.houbbpinyin; package org.dromara.hutool.extra.pinyin.engine.houbbpinyin;
import org.dromara.hutool.extra.pinyin.PinyinEngine; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import com.github.houbb.pinyin.constant.enums.PinyinStyleEnum; import com.github.houbb.pinyin.constant.enums.PinyinStyleEnum;
import com.github.houbb.pinyin.util.PinyinHelper; import com.github.houbb.pinyin.util.PinyinHelper;

View File

@ -13,7 +13,7 @@
package org.dromara.hutool.extra.pinyin.engine.jpinyin; package org.dromara.hutool.extra.pinyin.engine.jpinyin;
import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.extra.pinyin.PinyinEngine; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import com.github.stuxuhai.jpinyin.PinyinException; import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinFormat; import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper; import com.github.stuxuhai.jpinyin.PinyinHelper;

View File

@ -13,7 +13,7 @@
package org.dromara.hutool.extra.pinyin.engine.pinyin4j; package org.dromara.hutool.extra.pinyin.engine.pinyin4j;
import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.extra.pinyin.PinyinEngine; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import org.dromara.hutool.extra.pinyin.PinyinException; import org.dromara.hutool.extra.pinyin.PinyinException;
import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;

View File

@ -12,7 +12,7 @@
package org.dromara.hutool.extra.pinyin.engine.tinypinyin; package org.dromara.hutool.extra.pinyin.engine.tinypinyin;
import org.dromara.hutool.extra.pinyin.PinyinEngine; import org.dromara.hutool.extra.pinyin.engine.PinyinEngine;
import com.github.promeg.pinyinhelper.Pinyin; import com.github.promeg.pinyinhelper.Pinyin;
/** /**

View File

@ -11,7 +11,11 @@
*/ */
/** /**
* 拼音工具封装入口为PinyinUtil * 拼音相关封装
* <pre>
* createEngine getPinyin
* PinyinEngineFactory = PinyinEngine = 拼音
* </pre>
* *
* @author looly * @author looly
* *

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* Servlet封装包括Servlet参数获取文件上传Response写出等入口为ServletUtil
*
* @author looly
*
*/
package org.dromara.hutool.extra.servlet;

View File

@ -28,6 +28,9 @@ import org.dromara.hutool.extra.template.engine.TemplateEngine;
public class TemplateConfig implements Serializable { public class TemplateConfig implements Serializable {
private static final long serialVersionUID = 2933113779920339523L; private static final long serialVersionUID = 2933113779920339523L;
/**
* 默认配置
*/
public static final TemplateConfig DEFAULT = new TemplateConfig(); public static final TemplateConfig DEFAULT = new TemplateConfig();
/** /**
@ -206,17 +209,17 @@ public class TemplateConfig implements Serializable {
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o){ if (this == o) {
return true; return true;
} }
if (o == null || getClass() != o.getClass()){ if (o == null || getClass() != o.getClass()) {
return false; return false;
} }
final TemplateConfig that = (TemplateConfig) o; final TemplateConfig that = (TemplateConfig) o;
return Objects.equals(charset, that.charset) && return Objects.equals(charset, that.charset) &&
Objects.equals(path, that.path) && Objects.equals(path, that.path) &&
resourceMode == that.resourceMode && resourceMode == that.resourceMode &&
Objects.equals(customEngine, that.customEngine); Objects.equals(customEngine, that.customEngine);
} }
@Override @Override

View File

@ -12,38 +12,74 @@
package org.dromara.hutool.extra.template; package org.dromara.hutool.extra.template;
import org.dromara.hutool.core.exception.ExceptionUtil; import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.text.StrUtil;
/** /**
* 模板异常 * 模板异常
* *
* @author xiaoleilu * @author xiaoleilu
*/ */
public class TemplateException extends RuntimeException { public class TemplateException extends HutoolException {
private static final long serialVersionUID = 8247610319171014183L; private static final long serialVersionUID = 8247610319171014183L;
/**
* 构造
*
* @param e 异常
*/
public TemplateException(final Throwable e) { public TemplateException(final Throwable e) {
super(ExceptionUtil.getMessage(e), e); super(e);
} }
/**
* 构造
*
* @param message 消息
*/
public TemplateException(final String message) { public TemplateException(final String message) {
super(message); super(message);
} }
/**
* 构造
*
* @param messageTemplate 消息模板
* @param params 参数
*/
public TemplateException(final String messageTemplate, final Object... params) { public TemplateException(final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params)); super(messageTemplate, params);
} }
public TemplateException(final String message, final Throwable throwable) { /**
super(message, throwable); * 构造
*
* @param message 消息
* @param cause 被包装的子异常
*/
public TemplateException(final String message, final Throwable cause) {
super(message, cause);
} }
public TemplateException(final String message, final Throwable throwable, final boolean enableSuppression, final boolean writableStackTrace) { /**
super(message, throwable, enableSuppression, writableStackTrace); * 构造
*
* @param message 消息
* @param cause 被包装的子异常
* @param enableSuppression 是否启用抑制
* @param writableStackTrace 堆栈跟踪是否应该是可写的
*/
public TemplateException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
} }
public TemplateException(final Throwable throwable, final String messageTemplate, final Object... params) { /**
super(StrUtil.format(messageTemplate, params), throwable); * 构造
*
* @param cause 被包装的子异常
* @param messageTemplate 消息模板
* @param params 参数
*/
public TemplateException(final Throwable cause, final String messageTemplate, final Object... params) {
super(cause, messageTemplate, params);
} }
} }

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.extra.template;
import org.dromara.hutool.extra.template.engine.TemplateEngine;
import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
import java.io.Writer;
import java.util.Map;
/**
* 提供模板工具类用于快捷模板融合
*
* @author looly
*/
public class TemplateUtil {
/**
* 获取单例的模板引擎
*
* @return {@link TemplateEngine}
*/
public static TemplateEngine getEngine() {
return TemplateEngineFactory.getEngine();
}
/**
* 融合模板和参数返回融合后的内容
*
* @param templateContent 模板内容
* @param bindingMap 参数
* @return 内容
*/
public static String render(final String templateContent, final Map<?, ?> bindingMap) {
return getEngine().getTemplate(templateContent).render(bindingMap);
}
/**
* 融合模板和参数返回融合后的内容
*
* @param templateContent 模板内容
* @param bindingMap 参数
* @param writer 融合内容输出的位置
*/
public static void render(final String templateContent, final Map<?, ?> bindingMap, final Writer writer) {
getEngine().getTemplate(templateContent).render(bindingMap, writer);
}
}

View File

@ -10,21 +10,23 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.extra.template; package org.dromara.hutool.extra.template.engine;
import org.dromara.hutool.core.lang.Singleton; import org.dromara.hutool.core.lang.Singleton;
import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.core.spi.SpiUtil; import org.dromara.hutool.core.spi.SpiUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.template.engine.TemplateEngine; import org.dromara.hutool.extra.template.TemplateConfig;
import org.dromara.hutool.extra.template.TemplateException;
import org.dromara.hutool.log.StaticLog; import org.dromara.hutool.log.StaticLog;
/** /**
* 简单模板殷勤工厂用于根据用户引入的模板引擎jar自动创建对应的模板引擎对象 * 简单模板引擎工厂用于根据用户引入的模板引擎jar自动创建对应的模板引擎对象<br>
* 使用简单工厂Simple Factory模式
* *
* @author looly * @author looly
*/ */
public class TemplateFactory { public class TemplateEngineFactory {
/** /**
* 根据用户引入的模板引擎jar自动创建对应的模板引擎对象<br> * 根据用户引入的模板引擎jar自动创建对应的模板引擎对象<br>
@ -33,7 +35,7 @@ public class TemplateFactory {
* @return 单例的TemplateEngine * @return 单例的TemplateEngine
*/ */
public static TemplateEngine getEngine() { public static TemplateEngine getEngine() {
return Singleton.get(TemplateEngine.class.getName(), TemplateFactory::createEngine); return Singleton.get(TemplateEngine.class.getName(), TemplateEngineFactory::createEngine);
} }
/** /**
@ -55,7 +57,7 @@ public class TemplateFactory {
* @return {@link TemplateEngine} * @return {@link TemplateEngine}
*/ */
public static TemplateEngine createEngine(final TemplateConfig config) { public static TemplateEngine createEngine(final TemplateConfig config) {
final TemplateEngine engine = doCreate(config); final TemplateEngine engine = doCreateEngine(config);
StaticLog.debug("Use [{}] Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine")); StaticLog.debug("Use [{}] Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine"));
return engine; return engine;
} }
@ -67,7 +69,7 @@ public class TemplateFactory {
* @param config 模板配置包括编码模板文件path等信息 * @param config 模板配置包括编码模板文件path等信息
* @return {@link TemplateEngine} * @return {@link TemplateEngine}
*/ */
private static TemplateEngine doCreate(final TemplateConfig config) { private static TemplateEngine doCreateEngine(final TemplateConfig config) {
final Class<? extends TemplateEngine> customEngineClass = config.getCustomEngine(); final Class<? extends TemplateEngine> customEngineClass = config.getCustomEngine();
final TemplateEngine engine; final TemplateEngine engine;
if (null != customEngineClass) { if (null != customEngineClass) {

View File

@ -11,10 +11,15 @@
*/ */
/** /**
* 第三方模板引擎封装提供统一的接口用于适配第三方模板引擎 * 第三方模板引擎封装提供统一的接口用于适配第三方模板引擎提供
* <ul>
* <li>TemplateEngine模板引擎接口用于不同引擎的实现</li>
* <li>Template 模板接口用于不同引擎模板对象包装</li>
* <li>TemplateConfig模板配置用于提供公共配置项</li>
* </ul>
* <pre> * <pre>
* * createEngine getTemplate render
* TemplateFactory = TemplateEngine = Template = 内容 * TemplateEngineFactory = TemplateEngine = Template = 内容
* </pre> * </pre>
* *
* @author looly * @author looly

View File

@ -10,5 +10,5 @@
# See the Mulan PSL v2 for more details. # See the Mulan PSL v2 for more details.
# #
org.dromara.hutool.extra.aop.engine.spring.SpringCglibProxyFactory org.dromara.hutool.extra.aop.engine.spring.SpringCglibProxyEngine
org.dromara.hutool.extra.aop.engine.jdk.JdkProxyFactory org.dromara.hutool.extra.aop.engine.jdk.JdkProxyEngine

View File

@ -3,6 +3,7 @@ package org.dromara.hutool.extra.template;
import org.dromara.hutool.core.map.Dict; import org.dromara.hutool.core.map.Dict;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.template.engine.TemplateEngine; import org.dromara.hutool.extra.template.engine.TemplateEngine;
import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
import org.dromara.hutool.extra.template.engine.jetbrick.JetbrickEngine; import org.dromara.hutool.extra.template.engine.jetbrick.JetbrickEngine;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -14,7 +15,7 @@ public class JetbrickTest {
//classpath模板 //classpath模板
final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH) final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH)
.setCustomEngine(JetbrickEngine.class); .setCustomEngine(JetbrickEngine.class);
final TemplateEngine engine = TemplateFactory.createEngine(config); final TemplateEngine engine = TemplateEngineFactory.createEngine(config);
final Template template = engine.getTemplate("jetbrick_test.jetx"); final Template template = engine.getTemplate("jetbrick_test.jetx");
final String result = template.render(Dict.of().set("name", "hutool")); final String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("你好,hutool", StrUtil.trim(result)); Assertions.assertEquals("你好,hutool", StrUtil.trim(result));
@ -25,7 +26,7 @@ public class JetbrickTest {
// 字符串模板 // 字符串模板
final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.STRING) final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.STRING)
.setCustomEngine(JetbrickEngine.class); .setCustomEngine(JetbrickEngine.class);
final TemplateEngine engine = TemplateFactory.createEngine(config); final TemplateEngine engine = TemplateEngineFactory.createEngine(config);
final Template template = engine.getTemplate("hello,${name}"); final Template template = engine.getTemplate("hello,${name}");
final String result = template.render(Dict.of().set("name", "hutool")); final String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", StrUtil.trim(result)); Assertions.assertEquals("hello,hutool", StrUtil.trim(result));

View File

@ -4,6 +4,7 @@ import org.dromara.hutool.core.map.Dict;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.extra.template.TemplateConfig.ResourceMode; import org.dromara.hutool.extra.template.TemplateConfig.ResourceMode;
import org.dromara.hutool.extra.template.engine.TemplateEngine; import org.dromara.hutool.extra.template.engine.TemplateEngine;
import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
import org.dromara.hutool.extra.template.engine.beetl.BeetlEngine; import org.dromara.hutool.extra.template.engine.beetl.BeetlEngine;
import org.dromara.hutool.extra.template.engine.enjoy.EnjoyEngine; import org.dromara.hutool.extra.template.engine.enjoy.EnjoyEngine;
import org.dromara.hutool.extra.template.engine.freemarker.FreemarkerEngine; import org.dromara.hutool.extra.template.engine.freemarker.FreemarkerEngine;
@ -31,13 +32,13 @@ public class TemplateFactoryTest {
@Test @Test
public void createEngineTest() { public void createEngineTest() {
// 字符串模板, 默认模板引擎此处为Beetl // 字符串模板, 默认模板引擎此处为Beetl
TemplateEngine engine = TemplateFactory.createEngine(new TemplateConfig()); TemplateEngine engine = TemplateEngineFactory.createEngine(new TemplateConfig());
final Template template = engine.getTemplate("hello,${name}"); final Template template = engine.getTemplate("hello,${name}");
final String result = template.render(Dict.of().set("name", "hutool")); final String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", result); Assertions.assertEquals("hello,hutool", result);
// classpath中获取模板 // classpath中获取模板
engine = TemplateFactory.createEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH)); engine = TemplateEngineFactory.createEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH));
final Template template2 = engine.getTemplate("beetl_test.btl"); final Template template2 = engine.getTemplate("beetl_test.btl");
final String result2 = template2.render(Dict.of().set("name", "hutool")); final String result2 = template2.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", result2); Assertions.assertEquals("hello,hutool", result2);
@ -61,7 +62,7 @@ public class TemplateFactoryTest {
@Test @Test
public void rythmEngineTest() { public void rythmEngineTest() {
// 字符串模板 // 字符串模板
final TemplateEngine engine = TemplateFactory.createEngine( final TemplateEngine engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates").setCustomEngine(RythmEngine.class)); new TemplateConfig("templates").setCustomEngine(RythmEngine.class));
final Template template = engine.getTemplate("hello,@name"); final Template template = engine.getTemplate("hello,@name");
final String result = template.render(Dict.of().set("name", "hutool")); final String result = template.render(Dict.of().set("name", "hutool"));
@ -76,14 +77,14 @@ public class TemplateFactoryTest {
@Test @Test
public void freemarkerEngineTest() { public void freemarkerEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = TemplateFactory.createEngine( TemplateEngine engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(FreemarkerEngine.class)); new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(FreemarkerEngine.class));
Template template = engine.getTemplate("hello,${name}"); Template template = engine.getTemplate("hello,${name}");
String result = template.render(Dict.of().set("name", "hutool")); String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", result); Assertions.assertEquals("hello,hutool", result);
//ClassPath模板 //ClassPath模板
engine = TemplateFactory.createEngine( engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(FreemarkerEngine.class)); new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(FreemarkerEngine.class));
template = engine.getTemplate("freemarker_test.ftl"); template = engine.getTemplate("freemarker_test.ftl");
result = template.render(Dict.of().set("name", "hutool")); result = template.render(Dict.of().set("name", "hutool"));
@ -93,14 +94,14 @@ public class TemplateFactoryTest {
@Test @Test
public void velocityEngineTest() { public void velocityEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = TemplateFactory.createEngine( TemplateEngine engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(VelocityEngine.class)); new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(VelocityEngine.class));
Template template = engine.getTemplate("你好,$name"); Template template = engine.getTemplate("你好,$name");
String result = template.render(Dict.of().set("name", "hutool")); String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("你好,hutool", result); Assertions.assertEquals("你好,hutool", result);
//ClassPath模板 //ClassPath模板
engine = TemplateFactory.createEngine( engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(VelocityEngine.class)); new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(VelocityEngine.class));
template = engine.getTemplate("velocity_test.vtl"); template = engine.getTemplate("velocity_test.vtl");
result = template.render(Dict.of().set("name", "hutool")); result = template.render(Dict.of().set("name", "hutool"));
@ -114,7 +115,7 @@ public class TemplateFactoryTest {
@Test @Test
public void enjoyEngineTest() { public void enjoyEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = TemplateFactory.createEngine( TemplateEngine engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates").setCustomEngine(EnjoyEngine.class)); new TemplateConfig("templates").setCustomEngine(EnjoyEngine.class));
Template template = engine.getTemplate("#(x + 123)"); Template template = engine.getTemplate("#(x + 123)");
String result = template.render(Dict.of().set("x", 1)); String result = template.render(Dict.of().set("x", 1));
@ -131,14 +132,14 @@ public class TemplateFactoryTest {
@Test @Test
public void thymeleafEngineTest() { public void thymeleafEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = TemplateFactory.createEngine( TemplateEngine engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates").setCustomEngine(ThymeleafEngine.class)); new TemplateConfig("templates").setCustomEngine(ThymeleafEngine.class));
Template template = engine.getTemplate("<h3 th:text=\"${message}\"></h3>"); Template template = engine.getTemplate("<h3 th:text=\"${message}\"></h3>");
String result = template.render(Dict.of().set("message", "Hutool")); String result = template.render(Dict.of().set("message", "Hutool"));
Assertions.assertEquals("<h3>Hutool</h3>", result); Assertions.assertEquals("<h3>Hutool</h3>", result);
//ClassPath模板 //ClassPath模板
engine = TemplateFactory.createEngine( engine = TemplateEngineFactory.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(ThymeleafEngine.class)); new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(ThymeleafEngine.class));
template = engine.getTemplate("thymeleaf_test.ttl"); template = engine.getTemplate("thymeleaf_test.ttl");
result = template.render(Dict.of().set("message", "Hutool")); result = template.render(Dict.of().set("message", "Hutool"));
@ -151,13 +152,13 @@ public class TemplateFactoryTest {
@Test @Test
public void pebbleEngineTest() { public void pebbleEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = TemplateFactory.createEngine(new TemplateConfig("templates").setCustomEngine(PebbleTemplateEngine.class)); TemplateEngine engine = TemplateEngineFactory.createEngine(new TemplateConfig("templates").setCustomEngine(PebbleTemplateEngine.class));
Template template = engine.getTemplate("<h3>{{ message }}</h3>"); Template template = engine.getTemplate("<h3>{{ message }}</h3>");
String result = template.render(Dict.of().set("message", "Hutool")); String result = template.render(Dict.of().set("message", "Hutool"));
Assertions.assertEquals("<h3>Hutool</h3>", result); Assertions.assertEquals("<h3>Hutool</h3>", result);
//ClassPath模板 //ClassPath模板
engine = TemplateFactory.createEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(PebbleTemplateEngine.class)); engine = TemplateEngineFactory.createEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(PebbleTemplateEngine.class));
template = engine.getTemplate("pebble_test.peb"); template = engine.getTemplate("pebble_test.peb");
result = template.render(Dict.of().set("name", "Hutool")); result = template.render(Dict.of().set("name", "Hutool"));
Assertions.assertEquals("hello, Hutool", result); Assertions.assertEquals("hello, Hutool", result);
@ -180,7 +181,7 @@ public class TemplateFactoryTest {
//classpath模板 //classpath模板
TemplateConfig config = new TemplateConfig("templates", ResourceMode.CLASSPATH) TemplateConfig config = new TemplateConfig("templates", ResourceMode.CLASSPATH)
.setCustomEngine(WitEngine.class); .setCustomEngine(WitEngine.class);
TemplateEngine engine = TemplateFactory.createEngine(config); TemplateEngine engine = TemplateEngineFactory.createEngine(config);
Template template = engine.getTemplate("/wit_test.wit"); Template template = engine.getTemplate("/wit_test.wit");
String result = template.render(Dict.of().set("name", "hutool")); String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", StrUtil.trim(result)); Assertions.assertEquals("hello,hutool", StrUtil.trim(result));
@ -188,7 +189,7 @@ public class TemplateFactoryTest {
// 字符串模板 // 字符串模板
config = new TemplateConfig("templates", ResourceMode.STRING) config = new TemplateConfig("templates", ResourceMode.STRING)
.setCustomEngine(WitEngine.class); .setCustomEngine(WitEngine.class);
engine = TemplateFactory.createEngine(config); engine = TemplateEngineFactory.createEngine(config);
template = engine.getTemplate("<%var name;%>hello,${name}"); template = engine.getTemplate("<%var name;%>hello,${name}");
result = template.render(Dict.of().set("name", "hutool")); result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("hello,hutool", StrUtil.trim(result)); Assertions.assertEquals("hello,hutool", StrUtil.trim(result));

View File

@ -3,6 +3,7 @@ package org.dromara.hutool.extra.template;
import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.map.Dict; import org.dromara.hutool.core.map.Dict;
import org.dromara.hutool.extra.template.engine.TemplateEngine; import org.dromara.hutool.extra.template.engine.TemplateEngine;
import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
import org.dromara.hutool.extra.template.engine.thymeleaf.ThymeleafEngine; import org.dromara.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
@ -29,7 +30,7 @@ public class ThymeleafTest {
@Test @Test
@Disabled @Disabled
public void addDialectTest(){ public void addDialectTest(){
final TemplateEngine engine = TemplateFactory.createEngine(); final TemplateEngine engine = TemplateEngineFactory.createEngine();
if(engine instanceof ThymeleafEngine){ if(engine instanceof ThymeleafEngine){
final org.thymeleaf.TemplateEngine rawEngine = ((ThymeleafEngine) engine).getRawEngine(); final org.thymeleaf.TemplateEngine rawEngine = ((ThymeleafEngine) engine).getRawEngine();
rawEngine.addDialect(new StandardDialect()); rawEngine.addDialect(new StandardDialect());

View File

@ -3,6 +3,7 @@ package org.dromara.hutool.extra.template;
import org.dromara.hutool.core.map.Dict; import org.dromara.hutool.core.map.Dict;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.extra.template.engine.TemplateEngine; import org.dromara.hutool.extra.template.engine.TemplateEngine;
import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
import org.dromara.hutool.extra.template.engine.velocity.VelocityEngine; import org.dromara.hutool.extra.template.engine.velocity.VelocityEngine;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -14,7 +15,7 @@ public class VelocityTest {
final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH); final TemplateConfig config = new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH);
config.setCustomEngine(VelocityEngine.class); config.setCustomEngine(VelocityEngine.class);
config.setCharset(CharsetUtil.GBK); config.setCharset(CharsetUtil.GBK);
final TemplateEngine engine = TemplateFactory.createEngine(config); final TemplateEngine engine = TemplateEngineFactory.createEngine(config);
final Template template = engine.getTemplate("velocity_test_gbk.vtl"); final Template template = engine.getTemplate("velocity_test_gbk.vtl");
final String result = template.render(Dict.of().set("name", "hutool")); final String result = template.render(Dict.of().set("name", "hutool"));
Assertions.assertEquals("你好,hutool", result); Assertions.assertEquals("你好,hutool", result);