/** * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jfinal.template.ext.spring; import java.util.ArrayList; import java.util.List; import java.util.Locale; import javax.servlet.ServletContext; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.AbstractTemplateViewResolver; import com.jfinal.kit.StrKit; import com.jfinal.template.Directive; import com.jfinal.template.Engine; import com.jfinal.template.source.ClassPathSourceFactory; import com.jfinal.template.source.ISourceFactory; /** * JFinalViewResolver * *
* 关键配置: * 1:setDevMode(true) 设置支持热加载模板文件 * * 2:addSharedFunction(file) 添加共享函数文件 * * 3:setSourceFactory(new ClassPathSourceFactory()),从 class path 与 jar 包中加载模板文件 * 一般用于 sprint boot * * 4:setSessionInView(true) 设置在模板中可通过 #(session.value) 访问 session 中的数据 * * 5:setCreateSession(boolean) 用来设置 request.getSession(boolean) 调时的参数 * * 6:setBaseTemplatePath(path) 设置模板文件所在的基础路径,通常用于 spring mvc * 默认值为 web 根路径,一般不需要设置 **/ public class JFinalViewResolver extends AbstractTemplateViewResolver { public static final Engine engine = new Engine(); static List
* 配置示例: **/ public void setSharedFunctionList(List* **
*_layout.html *_paginate.html *
* 配置为 ClassPathSourceFactory 时特别注意: * 由于在 initServletContext() 通过如下方法中已设置了 baseTemplatePath 值: * setBaseTemplatePath(servletContext.getRealPath("/")) * * 而 ClassPathSourceFactory 在 initServletContext() 方法中设置的 * 值之下不能工作,所以在本方法中通过如下方法清掉了该值: * setBaseTemplatePath(null) * * 这种处理方式适用于绝大部分场景,如果在使用 ClassPathSourceFactory 的同时 * 仍然需要设置 baseTemplatePath,则在调用该方法 “之后” 通过如下代码再次配置: * setBaseTemplatePath(value) **/ public void setSourceFactory(ISourceFactory sourceFactory) { if (sourceFactory instanceof ClassPathSourceFactory) { engine.setBaseTemplatePath(null); } engine.setSourceFactory(sourceFactory); } /** * 设置模板基础路径 */ public void setBaseTemplatePath(String baseTemplatePath) { engine.setBaseTemplatePath(baseTemplatePath); } /** * 设置为 true 时支持在模板中使用 #(session.value) 形式访问 session 中的数据 */ public void setSessionInView(boolean sessionInView) { JFinalViewResolver.sessionInView = sessionInView; } /** * 在使用 request.getSession(createSession) 时传入 * 用来指示 session 不存在时是否立即创建 */ public void setCreateSession(boolean createSession) { JFinalViewResolver.createSession = createSession; } /** * 设置 encoding */ public void setEncoding(String encoding) { engine.setEncoding(encoding); } /** * 设置 #date(...) 指令,对于 Date、Timestamp、Time 的输出格式 */ public void setDatePattern(String datePattern) { engine.setDatePattern(datePattern); } // --------------------------------------------------------------- public JFinalViewResolver() { synchronized(JFinalViewResolver.class) { if (me == null) { me = this; } } setViewClass(requiredViewClass()); setOrder(0); setContentType("text/html;charset=UTF-8"); // setPrefix("/view/"); // setSuffix(".html"); } @Override protected Class> requiredViewClass() { return JFinalView.class; } /** * 支持 jfinal enjoy、jsp、freemarker、velocity 四类模板共存于一个项目中 * * 注意:这里采用识别 ".jsp"、".ftl"、".vm" 模板后缀名的方式来实现功能 * 所以 jfinal enjoy 模板不要采用上述三种后缀名,否则功能将失效 * 还要注意与 jsp、freemarker、velocity 以外类型模板共存使用时 * 需要改造该方法 */ protected View loadView(String viewName, Locale locale) throws Exception { String suffix = getSuffix(); if (".jsp".equals(suffix) || ".ftl".equals(suffix) || ".vm".equals(suffix)) { return null; } else { return super.loadView(viewName, locale); } } /** * spring 回调,利用 ServletContext 做必要的初始化工作 */ @Override protected void initServletContext(ServletContext servletContext) { super.initServletContext(servletContext); super.setExposeRequestAttributes(true); initBaseTemplatePath(servletContext); initSharedFunction(); } /** * 初始化 baseTemplatePath 值,启用 ClassPathSourceFactory 时 * 无需设置 baseTemplatePath 为 web 根路径 */ private void initBaseTemplatePath(ServletContext servletContext) { if (engine.getSourceFactory() instanceof ClassPathSourceFactory) { // do nothing } else { if (StrKit.isBlank(engine.getBaseTemplatePath())) { String path = servletContext.getRealPath("/"); engine.setBaseTemplatePath(path); } } } /** * 利用 sharedFunctionFiles 延迟调用 addSharedFunction * 因为需要等待 baseTemplatePath 以及 ISourceFactory 设置完毕以后 * 才能正常工作 */ private void initSharedFunction() { for (String file : sharedFunctionFiles) { engine.addSharedFunction(file.trim()); } } }