mirror of
https://gitee.com/nutz/nutzboot.git
synced 2024-11-29 18:28:01 +08:00
add: 重新实现starter-thymeleaf,并添加thymeleaf+shiro的demo
refer: https://nutz.cn/yvr/t/7gareesackiftr1bgo2tadmobq
This commit is contained in:
parent
6d35aef3e3
commit
63ac1ff3ed
@ -0,0 +1,60 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-demo-simple</artifactId>
|
||||
<version>2.3.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nutzboot-demo-simple-thymeleaf-shiro</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-layout-dialect</artifactId>
|
||||
<version>2.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-mvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-nutz-dao</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-shiro</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.nutz</groupId>
|
||||
<artifactId>nutzboot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.196</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,60 @@
|
||||
package io.nutz.demo.simple;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.crypto.hash.Sha256Hash;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.nutz.boot.NbApp;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.util.Daos;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.random.R;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import io.nutz.demo.simple.bean.User;
|
||||
|
||||
@IocBean
|
||||
public class MainLauncher {
|
||||
|
||||
@Inject
|
||||
protected Dao dao;
|
||||
|
||||
@At({"/", "/index"})
|
||||
@Ok("th:/index.html")
|
||||
public NutMap index() {
|
||||
return NutMap.NEW().setv("name", "NB").setv("age", 18);
|
||||
}
|
||||
|
||||
@Ok("raw")
|
||||
@At("/shiro/test")
|
||||
public boolean isAuthenticated(HttpSession session) {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
return subject.isAuthenticated();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
Daos.createTablesInPackage(dao, User.class, false);
|
||||
dao.insert(newUser("admin", "123456"));
|
||||
dao.insert(newUser("wendal", "123123"));
|
||||
}
|
||||
|
||||
protected static User newUser(String name, String password) {
|
||||
User user = new User();
|
||||
user.setName(name);
|
||||
user.setSalt(R.UU32());
|
||||
user.setPassword(new Sha256Hash(password, user.getSalt()).toHex());
|
||||
user.setCreateTime(new Date());
|
||||
return user;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NbApp().run();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package io.nutz.demo.simple.bean;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Name;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
|
||||
@Table("t_user")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
@Name
|
||||
private String name;
|
||||
private String password;
|
||||
private String salt;
|
||||
private Date createTime;
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
public void setSalt(String salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package io.nutz.demo.simple.module;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.crypto.hash.Sha256Hash;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.integration.shiro.SimpleShiroToken;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Fail;
|
||||
import org.nutz.mvc.annotation.GET;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import io.nutz.demo.simple.bean.User;
|
||||
|
||||
@At("/user")
|
||||
@IocBean
|
||||
public class UserModule {
|
||||
|
||||
@Inject
|
||||
Dao dao;
|
||||
|
||||
@GET
|
||||
@At("/login")
|
||||
@Ok(">>:/login.html")
|
||||
public void loginPage() {}
|
||||
|
||||
|
||||
@Ok("json")
|
||||
@Fail("http:500")
|
||||
@POST
|
||||
@At("/login")
|
||||
public boolean login(@Param("username")String username, @Param("password")String password, HttpSession session) {
|
||||
User user = dao.fetch(User.class, username);
|
||||
if (user == null)
|
||||
return false;
|
||||
Sha256Hash hash = new Sha256Hash(password, user.getSalt());
|
||||
if (!hash.toHex().equals(user.getPassword())) {
|
||||
return false;
|
||||
}
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
subject.login(new SimpleShiroToken(user.getId()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Ok(">>:/index.html")
|
||||
@At
|
||||
public void logout() {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
if (subject.isAuthenticated())
|
||||
subject.logout();
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package io.nutz.demo.simple.shiro;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAccount;
|
||||
import org.apache.shiro.authc.credential.CredentialsMatcher;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.nutz.integration.shiro.AbstractSimpleAuthorizingRealm;
|
||||
import org.nutz.integration.shiro.SimpleShiroToken;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import io.nutz.demo.simple.bean.User;
|
||||
|
||||
@IocBean(name="shiroRealm", fields="dao")
|
||||
public class SimpleAuthorizingRealm extends AbstractSimpleAuthorizingRealm {
|
||||
|
||||
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
// null usernames are invalid
|
||||
if (principals == null) {
|
||||
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
|
||||
}
|
||||
long userId = ((Number) principals.getPrimaryPrincipal()).longValue();
|
||||
User user = dao().fetch(User.class, userId);
|
||||
if (user == null)
|
||||
return null;
|
||||
SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
|
||||
auth.addRole(user.getName());
|
||||
auth.addStringPermission("user:list");
|
||||
return auth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
|
||||
SimpleShiroToken upToken = (SimpleShiroToken) token;
|
||||
|
||||
User user = dao().fetch(User.class, (Long)upToken.getPrincipal());
|
||||
if (user == null)
|
||||
return null;
|
||||
return new SimpleAccount(user.getId(), user.getPassword(), getName());
|
||||
}
|
||||
|
||||
public SimpleAuthorizingRealm() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public SimpleAuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
|
||||
super(cacheManager, matcher);
|
||||
setAuthenticationTokenClass(SimpleShiroToken.class);
|
||||
}
|
||||
|
||||
public SimpleAuthorizingRealm(CacheManager cacheManager) {
|
||||
this(cacheManager, null);
|
||||
}
|
||||
|
||||
public SimpleAuthorizingRealm(CredentialsMatcher matcher) {
|
||||
this(null, matcher);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
server.port=8080
|
||||
server.host=0.0.0.0
|
||||
|
||||
jdbc.url=jdbc:h2:mem:~
|
||||
shiro.ini.urls:
|
||||
/rs = anon
|
||||
/home.html = authc
|
||||
#end
|
||||
|
||||
thymeleaf.dialects=nz.net.ultraq.thymeleaf.LayoutDialect
|
||||
thymeleaf.dialects.shiro=at.pollux.thymeleaf.shiro.dialect.ShiroDialect
|
@ -0,0 +1,8 @@
|
||||
log4j.rootLogger=debug,Console
|
||||
|
||||
log4j.logger.org.eclipse.jetty=info
|
||||
log4j.logger.org.thymeleaf=debug
|
||||
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>用户个人主页</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>登录成功才能看到我,<a href="user/logout">现在登出</a></h2>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Shiro测试页</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h2>
|
||||
<a href="home.html?_=1">点我,访问一个未授权路径,会跳转到登录页面</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
当前登录状态: <a shiro:authenticated href="#">已登录</a> <a shiro:guest href="#">未登录</a>
|
||||
</h2>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>这是登录页面</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="user/login" id="user_login_form">
|
||||
账号<input name="username" value="admin">
|
||||
密码<input name="password" type="password" value="123456">
|
||||
<input type="submit" id="user_login">
|
||||
</form>
|
||||
</body>
|
||||
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#user_login").click(function() {
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
url : "user/login",
|
||||
data : $("#user_login_form").serialize(),
|
||||
dataType : "json",
|
||||
success : function(re) {
|
||||
if (re) {
|
||||
window.location = "/home.html";
|
||||
}
|
||||
else {
|
||||
alert("登录失败,用户名应该是admin或者wendal,密码是123456");
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
@ -58,7 +58,7 @@
|
||||
<module>nutzboot-demo-simple-ftp</module>
|
||||
<module>nutzboot-demo-simple-fastdfs</module>
|
||||
<module>nutzboot-demo-simple-sqlxmltpl</module>
|
||||
|
||||
<module>nutzboot-demo-simple-thymeleaf-shiro</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
@ -1,50 +1,32 @@
|
||||
package org.nutz.boot.starter.thymeleaf;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.nutz.lang.util.Context;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
import org.nutz.mvc.Mvcs;
|
||||
import org.nutz.mvc.view.AbstractPathView;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.WebContext;
|
||||
import org.thymeleaf.dialect.IDialect;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
public class ThymeleafView extends AbstractPathView {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
private TemplateEngine templateEngine = new TemplateEngine();
|
||||
protected TemplateEngine templateEngine;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private String encoding;
|
||||
|
||||
public ThymeleafView(ClassLoader classLoader, NutMap prop, String path) {
|
||||
protected String contentType;
|
||||
protected String encoding;
|
||||
|
||||
public ThymeleafView(TemplateEngine templateEngine, String path, String contentType, String encoding) {
|
||||
super(path);
|
||||
templateEngine.setTemplateResolver(initializeTemplateResolver(classLoader, prop));
|
||||
|
||||
encoding = prop.getString("encoding", "UTF-8");
|
||||
contentType = prop.getString("contentType", "text/html") + "; charset=" + encoding;
|
||||
|
||||
prop.getList("dialects", String.class).forEach(dialect -> {
|
||||
try {
|
||||
Object obj = Class.forName(dialect).getDeclaredConstructor().newInstance();
|
||||
if (obj instanceof IDialect) {
|
||||
log.debugf("在 thymeleaf 视图中加载 %s 类。", dialect);
|
||||
templateEngine.setDialect((IDialect) obj);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
|
||||
log.debugf("未在 thymeleaf 视图中加载 %s 类,因为其并不是 org.thymeleaf.dialect.IDialect 合法的实现类。", dialect);
|
||||
}
|
||||
});
|
||||
this.templateEngine = templateEngine;
|
||||
this.contentType = contentType;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,17 +47,4 @@ public class ThymeleafView extends AbstractPathView {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private ITemplateResolver initializeTemplateResolver(ClassLoader classLoader, NutMap prop) {
|
||||
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(classLoader);
|
||||
|
||||
templateResolver.setTemplateMode(prop.getString("mode", "HTML"));
|
||||
templateResolver.setPrefix(prop.getString("prefix", "template/"));
|
||||
templateResolver.setSuffix(prop.getString("suffix", ".html"));
|
||||
templateResolver.setCharacterEncoding(prop.getString("encoding", "UTF-8"));
|
||||
templateResolver.setCacheable(prop.getBoolean("cache", true));
|
||||
templateResolver.setCacheTTLMs(prop.getLong("cacheTTLMs", 3600000L));
|
||||
|
||||
return templateResolver;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,64 @@
|
||||
package org.nutz.boot.starter.thymeleaf;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.File;
|
||||
|
||||
import org.nutz.boot.AppContext;
|
||||
import org.nutz.boot.annotation.PropDoc;
|
||||
import org.nutz.ioc.Ioc;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.Mirror;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.log.Log;
|
||||
import org.nutz.log.Logs;
|
||||
import org.nutz.mvc.View;
|
||||
import org.nutz.mvc.ViewMaker;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.dialect.IDialect;
|
||||
import org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.FileTemplateResolver;
|
||||
|
||||
@IocBean(name="$views_thymeleaf", create="init")
|
||||
@IocBean(name = "$views_thymeleaf", create = "init")
|
||||
public class ThymeleafViewMakerStarter implements ViewMaker {
|
||||
|
||||
private static final Log log = Logs.get();
|
||||
|
||||
public static String PRE = "thymeleaf.";
|
||||
|
||||
@PropDoc(value = "渲染模式", defaultValue = "html")
|
||||
public static final String PROP_MODE = PRE + "mode";
|
||||
|
||||
@PropDoc(value = "路径前缀", defaultValue = "template/")
|
||||
public static final String PROP_PREFIX = PRE + "prefix";
|
||||
|
||||
@PropDoc(value = "模板文件后缀", defaultValue = ".html")
|
||||
public static final String PROP_SUFFIX = PRE + "suffix";
|
||||
|
||||
@PropDoc(value = "模板文件编码", defaultValue = "UTF-8")
|
||||
public static final String PROP_ENCODING = PRE + "encoding";
|
||||
|
||||
@PropDoc(value = "启用模板缓存", defaultValue = "true")
|
||||
public static final String PROP_CACHE_ENABLE = PRE + "cache.enable";
|
||||
|
||||
@PropDoc(value = "模板缓存生存时长", defaultValue = "3000")
|
||||
public static final String PROP_CACHE_TTL_MS = PRE + "cache.ttl";
|
||||
|
||||
@PropDoc(value = "模板目录的绝对路径,若不存在,回落到'模板目录的路径'")
|
||||
public static final String PROP_TEMPLATE_ROOT_LOCAL = PRE + "resolver.rootLocal";
|
||||
|
||||
@PropDoc(value = "加载dialects,需要完整类名,逗号分隔")
|
||||
public static final String PROP_DIALECTS = PRE + "dialects";
|
||||
|
||||
@PropDoc(value = "带前缀加载dialect,需要完整类名,逗号分隔")
|
||||
public static final String PROP_DIALECTS_XXX = PRE + "dialects.xx";
|
||||
|
||||
@PropDoc(value = "响应的默认类型", defaultValue="text/html")
|
||||
public static final String PROP_CONTENT_TYPE = PRE + "contentType";
|
||||
|
||||
@Inject
|
||||
protected PropertiesProxy conf;
|
||||
|
||||
@ -28,29 +67,95 @@ public class ThymeleafViewMakerStarter implements ViewMaker {
|
||||
|
||||
protected NutMap prop = NutMap.NEW();
|
||||
|
||||
protected TemplateEngine templateEngine = new TemplateEngine();
|
||||
|
||||
protected String contentType;
|
||||
|
||||
protected String encoding;
|
||||
|
||||
protected AbstractConfigurableTemplateResolver setupTemplateResolver(AbstractConfigurableTemplateResolver templateResolver) {
|
||||
|
||||
templateResolver.setTemplateMode(conf.get(PROP_MODE, "HTML"));
|
||||
templateResolver.setPrefix(conf.get(PROP_PREFIX, "template/"));
|
||||
templateResolver.setSuffix(conf.get(PROP_SUFFIX, ".html"));
|
||||
templateResolver.setCharacterEncoding(encoding);
|
||||
templateResolver.setCacheable(conf.getBoolean(PROP_CACHE_ENABLE, true));
|
||||
templateResolver.setCacheTTLMs(conf.getLong(PROP_CACHE_TTL_MS, 3000L));
|
||||
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
protected ClassLoaderTemplateResolver createClassLoaderTemplateResolver() {
|
||||
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(appContext.getClassLoader());
|
||||
setupTemplateResolver(templateResolver);
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
protected FileTemplateResolver createFileTemplateResolver(String root) {
|
||||
FileTemplateResolver templateResolver = new FileTemplateResolver();
|
||||
setupTemplateResolver(templateResolver);
|
||||
templateResolver.setPrefix(root);
|
||||
templateResolver.setCacheable(false);
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (conf == null) {
|
||||
return;
|
||||
}
|
||||
log.debug("thymeleaf init ....");
|
||||
|
||||
contentType = conf.get(PROP_CONTENT_TYPE, "text/html");
|
||||
encoding = conf.get(PROP_ENCODING, "UTF-8");
|
||||
|
||||
if (conf.has("thymeleaf.dialects")) {
|
||||
addDialect(null, conf.get("thymeleaf.dialects"));
|
||||
}
|
||||
for (String key : conf.keySet()) {
|
||||
if (key.startsWith("thymeleaf.")) {
|
||||
if (key.startsWith("thymeleaf.dialects.")) {
|
||||
prop.put("dialects", Arrays.stream(conf.get(key).split(",")).map(Strings::trim).collect(Collectors.toList()));
|
||||
} else {
|
||||
prop.put(key.substring("thymeleaf.".length()), conf.get(key));
|
||||
}
|
||||
if (key.startsWith("thymeleaf.dialects.")) {
|
||||
String prefix = key.substring("thymeleaf.dialects.".length());
|
||||
if ("default".equals(prefix))
|
||||
prefix = null;
|
||||
String dialects = conf.get(key);
|
||||
addDialect(prefix, dialects);
|
||||
}
|
||||
}
|
||||
if (conf.has(PROP_TEMPLATE_ROOT_LOCAL)) {
|
||||
String path = conf.get(PROP_TEMPLATE_ROOT_LOCAL);
|
||||
File f = new File(path);
|
||||
if (f.exists()) {
|
||||
log.debugf("add local template path = %s", f.getAbsolutePath());
|
||||
FileTemplateResolver resolver = createFileTemplateResolver(f.getAbsolutePath());
|
||||
resolver.setCacheable(false);
|
||||
templateEngine.addTemplateResolver(resolver);
|
||||
}
|
||||
}
|
||||
templateEngine.addTemplateResolver(createClassLoaderTemplateResolver());
|
||||
log.debug("thymeleaf init complete");
|
||||
}
|
||||
|
||||
public void addDialect(String prefix, String klassNames) {
|
||||
for (String dialect : Strings.splitIgnoreBlank(klassNames)) {
|
||||
log.debugf("loading thymeleaf dialect " + dialect);
|
||||
Class<?> klass = Lang.loadClassQuite(dialect);
|
||||
if (klass == null) {
|
||||
log.info("no such thymeleaf dialect class = " + dialect);
|
||||
continue;
|
||||
}
|
||||
Object obj = Mirror.me(klass).born();
|
||||
if (obj instanceof IDialect) {
|
||||
templateEngine.addDialect(prefix, (IDialect) obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View make(Ioc ioc, String type, String value) {
|
||||
if ("th".equalsIgnoreCase(type)) {
|
||||
return new ThymeleafView(appContext.getClassLoader(), prop, value);
|
||||
} else {
|
||||
return null;
|
||||
return new ThymeleafView(templateEngine, value, contentType, encoding);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@IocBean(name = "thymeleafTemplateEngine")
|
||||
public TemplateEngine getTemplateEngine() {
|
||||
return templateEngine;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user