diff --git a/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/pom.xml b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/pom.xml new file mode 100644 index 00000000..1cbc2279 --- /dev/null +++ b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/pom.xml @@ -0,0 +1,43 @@ + + + nutzboot-demo-simple + org.nutz + 2.2-SNAPSHOT + + 4.0.0 + + nutzboot-demo-simple-freemarker + jar + + nutzboot-demo-simple-freemarker + http://maven.apache.org + + + UTF-8 + + + + + org.nutz + nutzboot-starter-nutz-mvc + + + org.nutz + nutzboot-starter-jetty + + + org.nutz + nutzboot-starter-freemarker + + + org.slf4j + slf4j-log4j12 + + + nz.net.ultraq.thymeleaf + thymeleaf-layout-dialect + 2.2.2 + + + diff --git a/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/java/io/nutz/demo/simple/MainLauncher.java b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/java/io/nutz/demo/simple/MainLauncher.java new file mode 100644 index 00000000..726b7d29 --- /dev/null +++ b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/java/io/nutz/demo/simple/MainLauncher.java @@ -0,0 +1,22 @@ +package io.nutz.demo.simple; + +import org.nutz.boot.NbApp; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +@IocBean +public class MainLauncher { + + @At + @Ok("fm:/index") + public Object index(){ + return NutMap.NEW().setv("name","wendal").setv("age",18); + } + + + public static void main(String[] args) { + new NbApp().setPrintProcDoc(true).start(); + } +} diff --git a/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/application.properties b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/application.properties new file mode 100644 index 00000000..7de1524d --- /dev/null +++ b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8080 +server.host=0.0.0.0 + +freemarker.suffix=.html \ No newline at end of file diff --git a/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/log4j.properties b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/log4j.properties new file mode 100644 index 00000000..f6d90e75 --- /dev/null +++ b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +log4j.rootLogger=info,Console + +log4j.logger.org.nutz.mvc=debug +log4j.logger.org.eclipse.jetty=info + +log4j.appender.Console=org.apache.log4j.ConsoleAppender +log4j.appender.Console.layout=org.apache.log4j.PatternLayout +log4j.appender.Console.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] %5p [%t] --- %c{1}: %m%n diff --git a/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/template/index.html b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/template/index.html new file mode 100644 index 00000000..926e7096 --- /dev/null +++ b/nutzboot-demo/nutzboot-demo-simple/nutzboot-demo-simple-freemarker/src/main/resources/template/index.html @@ -0,0 +1,16 @@ + + + + +NB demo for Freemarker + + +
+

Context Path = ${obj.base!}

+
+
+

From Action name= ${obj.name}, age=${obj.age!}

+
+ + + diff --git a/nutzboot-demo/nutzboot-demo-simple/pom.xml b/nutzboot-demo/nutzboot-demo-simple/pom.xml index 89a32c44..ca33c22c 100644 --- a/nutzboot-demo/nutzboot-demo-simple/pom.xml +++ b/nutzboot-demo/nutzboot-demo-simple/pom.xml @@ -42,7 +42,8 @@ nutzboot-demo-simple-quartz nutzboot-demo-simple-j2cache nutzboot-demo-simple-dao-with-slave - + nutzboot-demo-simple-freemarker + diff --git a/nutzboot-starter/nutzboot-starter-freemarker/pom.xml b/nutzboot-starter/nutzboot-starter-freemarker/pom.xml new file mode 100644 index 00000000..29f70357 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + + nutzboot-starter + org.nutz + 2.2-SNAPSHOT + + nutzboot-starter-freemarker + jar + nutzboot-starter-freemarker + + + UTF-8 + + NutzBoot, micoservice base on Nutz + + + + Github Issue + http://github.com/nutzam/nutzboot/issues + + + + The Apache Software License, Version 2.0 + http://apache.org/licenses/LICENSE-2.0.txt + + + + + 蛋蛋 + 王庆华 + TopCoderMyDream@gmail.com + https://github.com/TopCoderMyDream + + + + scm:git:git://github.com/nutzam/nutzboot.git + scm:git:git://github.com/nutzam/nutzboot.git + git://github.com/nutzam/nutzboot.git + + + + nutzcn-snapshots + NutzCN snapshot repository + https://jfrog.nutz.cn/artifactory/snapshots + + + + sonatype-release-staging + Sonatype Nexus release repository + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + + + org.freemarker + freemarker + + + diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreeMarkerConfigurer.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreeMarkerConfigurer.java new file mode 100644 index 00000000..281fc1f9 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreeMarkerConfigurer.java @@ -0,0 +1,158 @@ +package org.nutz.boot.starter.freemarker; + +import freemarker.template.*; +import org.nutz.boot.annotation.PropDoc; +import org.nutz.ioc.Ioc; +import org.nutz.ioc.IocContext; +import org.nutz.ioc.Iocs; +import org.nutz.ioc.impl.PropertiesProxy; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Files; +import org.nutz.lang.Lang; +import org.nutz.lang.Streams; +import org.nutz.lang.Strings; +import org.nutz.lang.util.ClassTools; +import org.nutz.log.Log; +import org.nutz.log.Logs; +import org.nutz.mvc.Mvcs; + +import javax.servlet.ServletContext; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.*; +import java.util.Map.Entry; + +@IocBean(create = "init") +public class FreeMarkerConfigurer { + + private final static Log log = Logs.get(); + + protected static final String PRE = "freemarker."; + public static final String PRE_SUFFIX = PRE + "suffix"; + + private Configuration configuration; + private String prefix; + private String suffix; + private FreemarkerDirectiveFactory freemarkerDirectiveFactory; + private Map tags = new HashMap(); + + public FreeMarkerConfigurer() { + Configuration configuration = new Configuration(Configuration.VERSION_2_3_26); + Ioc ioc = Mvcs.ctx().getDefaultIoc(); + PropertiesProxy conf = ioc.get(PropertiesProxy.class,"conf"); + this.initp(configuration, Mvcs.getServletContext(), "template", conf.get(PRE_SUFFIX,".html"), new FreemarkerDirectiveFactory()); + } + + + protected void initp(Configuration configuration, ServletContext sc, String prefix, String suffix, FreemarkerDirectiveFactory freemarkerDirectiveFactory) { + this.configuration = configuration; + URL url = ClassTools.getClassLoader().getResource(prefix); + String path = url.getPath(); + this.prefix =path; + this.suffix = suffix; + this.freemarkerDirectiveFactory = freemarkerDirectiveFactory; + if (this.prefix == null) + this.prefix = sc.getRealPath("/") + prefix; + + this.configuration.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX); + this.configuration.setTemplateUpdateDelayMilliseconds(-1000); + this.configuration.setDefaultEncoding("UTF-8"); + this.configuration.setURLEscapingCharset("UTF-8"); + this.configuration.setLocale(Locale.CHINA); + this.configuration.setBooleanFormat("true,false"); + this.configuration.setDateTimeFormat("yyyy-MM-dd HH:mm:ss"); + this.configuration.setDateFormat("yyyy-MM-dd"); + this.configuration.setTimeFormat("HH:mm:ss"); + this.configuration.setNumberFormat("0.######"); + this.configuration.setWhitespaceStripping(true); + } + + public Configuration getConfiguration() { + return configuration; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public void init() { + try { + initFreeMarkerConfigurer(); + Iterator> iterator = tags.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + configuration.setSharedVariable(entry.getKey(), entry.getValue()); + } + if (freemarkerDirectiveFactory == null) + return; + for (FreemarkerDirective freemarkerDirective : freemarkerDirectiveFactory.getList()) { + configuration.setSharedVariable(freemarkerDirective.getName(), freemarkerDirective.getTemplateDirectiveModel()); + } + } catch (IOException e) { + log.error(e); + } catch (TemplateException e) { + log.error(e); + } + } + + public String getSuffix() { + return Strings.isBlank(freemarkerDirectiveFactory.getSuffix()) ? this.suffix : freemarkerDirectiveFactory.getSuffix(); + } + + public String getPrefix() { + return prefix; + } + + protected void initFreeMarkerConfigurer() throws IOException, TemplateException { + String path = freemarkerDirectiveFactory.getFreemarker(); + File file = Files.findFile(path); + if (!Lang.isEmpty(file)) { + Properties p = new Properties(); + p.load(Streams.fileIn(file)); + configuration.setSettings(p); + } + File f = Files.findFile(prefix); + configuration.setDirectoryForTemplateLoading(f); + } + + public void setTags(Map map) { + Iterator> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + String key = entry.getKey(); + Object obj = entry.getValue(); + tags.put(key, obj); + } + } + + public FreeMarkerConfigurer setSuffix(String suffix) { + this.suffix = suffix; + return this; + } + + public FreeMarkerConfigurer setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + /** + * + * @param map + * @return + * + * mapTags : { factory : "$freeMarkerConfigurer#addTags", args : [ { + * 'abc' : 1, 'def' : 2 } ] } + */ + public FreeMarkerConfigurer addTags(Map map) { + if (map != null) { + try { + configuration.setAllSharedVariables(new SimpleHash(map, new DefaultObjectWrapper(Configuration.VERSION_2_3_26))); + } catch (TemplateModelException e) { + log.error(e); + } + } + return this; + } +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirective.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirective.java new file mode 100644 index 00000000..b2a772c7 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirective.java @@ -0,0 +1,25 @@ +package org.nutz.boot.starter.freemarker; + +import freemarker.template.TemplateDirectiveModel; + +/** + * @author 科技㊣²º¹³ + * 2014年1月1日 下午5:42:54 + * http://www.rekoe.com + * QQ:5382211 + */ +public class FreemarkerDirective { + private String name; + private TemplateDirectiveModel templateDirectiveModel; + public FreemarkerDirective(String name, TemplateDirectiveModel templateDirectiveModel) { + super(); + this.name = name; + this.templateDirectiveModel = templateDirectiveModel; + } + public String getName() { + return name; + } + public TemplateDirectiveModel getTemplateDirectiveModel() { + return templateDirectiveModel; + } +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirectiveFactory.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirectiveFactory.java new file mode 100644 index 00000000..925f5b40 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerDirectiveFactory.java @@ -0,0 +1,56 @@ +package org.nutz.boot.starter.freemarker; + +import org.nutz.lang.Lang; + +import java.util.ArrayList; +import java.util.List; + +public class FreemarkerDirectiveFactory { + + private List list = new ArrayList(); + + private String freemarker; + + private String suffix; + + private FreemarkerDirective[] objs; + + public FreemarkerDirectiveFactory() { + this.freemarker = "freemarker.properties"; + } + + public FreemarkerDirectiveFactory(FreemarkerDirective... objs) { + this.objs = objs; + } + + public List getList() { + return list; + } + + public String getFreemarker() { + return freemarker; + } + + public String getSuffix() { + return suffix; + } + + public void init() { + if (Lang.isEmptyArray(objs)) { + return; + } + for (FreemarkerDirective freemarkerDirective : objs) { + list.add(freemarkerDirective); + } + } + + public FreemarkerDirectiveFactory create(FreemarkerDirective... objs) { + if (Lang.isEmptyArray(objs)) { + return this; + } + for (FreemarkerDirective freemarkerDirective : objs) { + list.add(freemarkerDirective); + } + return this; + } +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerView.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerView.java new file mode 100644 index 00000000..282f5035 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerView.java @@ -0,0 +1,154 @@ +package org.nutz.boot.starter.freemarker; + +import freemarker.ext.jsp.TaglibFactory; +import freemarker.ext.servlet.HttpRequestHashModel; +import freemarker.ext.servlet.HttpRequestParametersHashModel; +import freemarker.ext.servlet.HttpSessionHashModel; +import freemarker.ext.servlet.ServletContextHashModel; +import freemarker.template.Configuration; +import freemarker.template.ObjectWrapper; +import freemarker.template.Template; +import freemarker.template.TemplateModel; +import org.nutz.lang.Files; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.nutz.mvc.Mvcs; +import org.nutz.mvc.view.AbstractPathView; + +import javax.servlet.GenericServlet; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class FreemarkerView extends AbstractPathView { + + private FreeMarkerConfigurer freeMarkerConfigurer; + private static final String ATTR_APPLICATION_MODEL = ".freemarker.Application"; + private static final String ATTR_JSP_TAGLIBS_MODEL = ".freemarker.JspTaglibs"; + private static final String ATTR_REQUEST_MODEL = ".freemarker.Request"; + private static final String ATTR_REQUEST_PARAMETERS_MODEL = ".freemarker.RequestParameters"; + private static final String KEY_APPLICATION = "Application"; + private static final String KEY_REQUEST_MODEL = "Request"; + private static final String KEY_SESSION_MODEL = "Session"; + private static final String KEY_REQUEST_PARAMETER_MODEL = "Parameters"; + private static final String KEY_EXCEPTION = "exception"; + private static final String OBJ = "obj"; + private static final String REQUEST = "request"; + private static final String RESPONSE = "response"; + private static final String SESSION = "session"; + private static final String APPLICATION = "application"; + private static final String KEY_JSP_TAGLIBS = "JspTaglibs"; + public static final String PATH_BASE = "base"; + + public FreemarkerView(FreeMarkerConfigurer freeMarkerConfigurer, String path) { + super(path); + this.freeMarkerConfigurer = freeMarkerConfigurer; + } + + public void render(HttpServletRequest request, HttpServletResponse response, Object value) throws Throwable { + String $temp = evalPath(request, value); + String path = getPath($temp); + ServletContext sc = request.getSession().getServletContext(); + Configuration cfg = freeMarkerConfigurer.getConfiguration(); + Map root = new HashMap(); + root.put(OBJ, value); + root.put(REQUEST, request); + root.put(RESPONSE, response); + HttpSession session = request.getSession(); + root.put(SESSION, session); + root.put(APPLICATION, sc); + root.put("props", System.getProperties());// .get("java.version") + Map msgs = Mvcs.getMessages(request); + root.put("mvcs", msgs); + Enumeration reqs = request.getAttributeNames(); + while (reqs.hasMoreElements()) { + String strKey = (String) reqs.nextElement(); + root.put(strKey, request.getAttribute(strKey)); + } + jspTaglibs(sc, request, response, root, cfg.getObjectWrapper()); + try { + Template template = cfg.getTemplate(path); + response.setContentType("text/html; charset=" + template.getEncoding()); + template.process(root, response.getWriter()); + } catch (Exception e) { + throw Lang.wrapThrow(e); + } + } + + /** + * 子类可以覆盖这个方法,给出自己特殊的后缀 + * + * @return 后缀 + */ + protected String getExt() { + return freeMarkerConfigurer.getSuffix(); + } + + private String getPath(String path) { + StringBuffer sb = new StringBuffer(); + // 空路径,采用默认规则 + if (Strings.isBlank(path)) { + sb.append(Mvcs.getServletContext().getRealPath(freeMarkerConfigurer.getPrefix())); + sb.append((path.startsWith("/") ? "" : "/")); + sb.append(Files.renameSuffix(path, getExt())); + } + // 绝对路径 : 以 '/' 开头的路径不增加 '/WEB-INF' + else if (path.charAt(0) == '/') { + String ext = getExt(); + sb.append(path); + if (!path.toLowerCase().endsWith(ext)) + sb.append(ext); + } + // 包名形式的路径 + else { + sb.append(path.replace('.', '/')); + sb.append(getExt()); + } + return sb.toString(); + } + + protected void jspTaglibs(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response, Map model, ObjectWrapper wrapper) { + synchronized (servletContext) { + ServletContextHashModel servletContextModel = (ServletContextHashModel) servletContext.getAttribute(ATTR_APPLICATION_MODEL); + if (Lang.isEmpty(servletContextModel)) { + GenericServlet servlet = JspSupportServlet.jspSupportServlet; + if (!Lang.isEmpty(servlet)) { + servletContextModel = new ServletContextHashModel(servlet, wrapper); + servletContext.setAttribute(ATTR_APPLICATION_MODEL, servletContextModel); + TaglibFactory taglibs = new TaglibFactory(servletContext); + servletContext.setAttribute(ATTR_JSP_TAGLIBS_MODEL, taglibs); + } + } + model.put(KEY_APPLICATION, servletContextModel); + TemplateModel tempModel = (TemplateModel) servletContext.getAttribute(ATTR_JSP_TAGLIBS_MODEL); + model.put(KEY_JSP_TAGLIBS, tempModel); + } + HttpSession session = request.getSession(false); + if (!Lang.isEmpty(session)) { + model.put(KEY_SESSION_MODEL, new HttpSessionHashModel(session, wrapper)); + } + HttpRequestHashModel requestModel = (HttpRequestHashModel) request.getAttribute(ATTR_REQUEST_MODEL); + if (Lang.isEmpty(requestModel) || !Lang.equals(requestModel.getRequest(), request)) { + requestModel = new HttpRequestHashModel(request, response, wrapper); + request.setAttribute(ATTR_REQUEST_MODEL, requestModel); + } + model.put(KEY_REQUEST_MODEL, requestModel); + HttpRequestParametersHashModel reqParametersModel = (HttpRequestParametersHashModel) request.getAttribute(ATTR_REQUEST_PARAMETERS_MODEL); + if (Lang.isEmpty(reqParametersModel) || !Lang.equals(requestModel.getRequest(), request)) { + reqParametersModel = new HttpRequestParametersHashModel(request); + request.setAttribute(ATTR_REQUEST_PARAMETERS_MODEL, reqParametersModel); + } + model.put(KEY_REQUEST_PARAMETER_MODEL, reqParametersModel); + Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); + if (Lang.isEmpty(exception)) { + exception = (Throwable) request.getAttribute("javax.servlet.error.JspException"); + } + if (!Lang.isEmpty(exception)) { + model.put(KEY_EXCEPTION, exception); + } + } +} \ No newline at end of file diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerViewMaker.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerViewMaker.java new file mode 100644 index 00000000..0c10e4d2 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/FreemarkerViewMaker.java @@ -0,0 +1,47 @@ +package org.nutz.boot.starter.freemarker; + +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.mvc.View; +import org.nutz.mvc.ViewMaker; + +@IocBean(name="$views_freekmarker") +public class FreemarkerViewMaker implements ViewMaker { + + protected FreeMarkerConfigurer freeMarkerConfigurer; + + protected String iocName = "freeMarkerConfigurer"; + + protected static final String PRE = "freemarker."; + + @PropDoc(group = "freemarker", value = "文件后缀",defaultValue = ".html") + public static final String PROP_SUFFIX = PRE + "suffix"; + + + @Inject + PropertiesProxy conf; + + + public View make(Ioc ioc, String type, String value) { + if ("fm".equalsIgnoreCase(type) || "ftl".equalsIgnoreCase(type)) { + if (freeMarkerConfigurer == null) { + for (String name : ioc.getNames()) { + if (iocName.equals(name)) { + freeMarkerConfigurer = ioc.get(FreeMarkerConfigurer.class); + break; + } + } + if (freeMarkerConfigurer == null) { + freeMarkerConfigurer = new FreeMarkerConfigurer(); + freeMarkerConfigurer.init(); + } + } + return new FreemarkerView(freeMarkerConfigurer, value); + } + return null; + } + +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/JspSupportServlet.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/JspSupportServlet.java new file mode 100644 index 00000000..7e805598 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/JspSupportServlet.java @@ -0,0 +1,17 @@ +package org.nutz.boot.starter.freemarker; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; + +/** + */ +public class JspSupportServlet extends HttpServlet { + + private static final long serialVersionUID = 8302309812391541933L; + public static JspSupportServlet jspSupportServlet; + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + jspSupportServlet = this; + } +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/directive/CurrentTimeDirective.java b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/directive/CurrentTimeDirective.java new file mode 100644 index 00000000..aa9b22b8 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/java/org/nutz/boot/starter/freemarker/directive/CurrentTimeDirective.java @@ -0,0 +1,25 @@ +package org.nutz.boot.starter.freemarker.directive; + +import freemarker.core.Environment; +import freemarker.template.TemplateDirectiveBody; +import freemarker.template.TemplateDirectiveModel; +import freemarker.template.TemplateException; +import freemarker.template.TemplateModel; +import org.nutz.lang.Times; + +import java.io.IOException; +import java.io.Writer; +import java.util.Map; + +/** + * 执行时间标签 + * + */ +public class CurrentTimeDirective implements TemplateDirectiveModel { + + @SuppressWarnings({ "rawtypes" }) + public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { + Writer out = env.getOut(); + out.append(Times.format("yyyy-MM-dd HH:mm", Times.now())); + } +} diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/META-INF/nutz/org.nutz.boot.starter.NbStarter b/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/META-INF/nutz/org.nutz.boot.starter.NbStarter new file mode 100644 index 00000000..86936780 --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/META-INF/nutz/org.nutz.boot.starter.NbStarter @@ -0,0 +1 @@ +org.nutz.boot.starter.freemarker.FreemarkerViewMaker \ No newline at end of file diff --git a/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/freemarker.properties b/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/freemarker.properties new file mode 100644 index 00000000..2744c1bc --- /dev/null +++ b/nutzboot-starter/nutzboot-starter-freemarker/src/main/resources/freemarker.properties @@ -0,0 +1,9 @@ +#demo configure +url_escaping_charset=UTF-8 +locale=zh_CN +boolean_format=true,false +datetime_format=yyyy-MM-dd HH:mm:ss +date_format=yyyy-MM-dd +time_format=HH:mm:ss +number_format=0.###### +#auto_import=/ftl/pony/index.ftl as p,/ftl/spring.ftl as s diff --git a/nutzboot-starter/pom.xml b/nutzboot-starter/pom.xml index 5503b98d..527d7565 100644 --- a/nutzboot-starter/pom.xml +++ b/nutzboot-starter/pom.xml @@ -55,6 +55,7 @@ nutzboot-starter-apollo-client nutzboot-starter-config-client nutzboot-starter-j2cache + nutzboot-starter-freemarker diff --git a/pom.xml b/pom.xml index eb7e518e..7bb4fd5b 100644 --- a/pom.xml +++ b/pom.xml @@ -793,6 +793,16 @@ nutzboot-starter-j2cache ${nutzboot.version} + + org.freemarker + freemarker + 2.3.26-incubating + + + org.nutz + nutzboot-starter-freemarker + ${nutzboot.version} +