com.jfinal.template.ext.spring.JFinalViewResolver Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2011-2023, James Zhan 詹波 ([email protected]).
*
* 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 sharedFunctionFiles = new ArrayList();
static boolean sessionInView = false;
static boolean createSession = true;
private static JFinalViewResolver me = null;
/**
* me 会保存在第一次被创建对象
*/
public static JFinalViewResolver me() {
return me;
}
public Engine getEngine() {
return engine;
}
/**
* 设置开发模式,值为 true 时支持模板文件热加载
*/
public void setDevMode(boolean devMode) {
engine.setDevMode(devMode);
}
/**
* 设置 shared function 文件,多个文件用逗号分隔
*
* 主要用于 Spring MVC 的 xml 配置方式
*
* Spring Boot 的代码配置方式可使用 addSharedFunction(...) 进行配置
*/
public void setSharedFunction(String sharedFunctionFiles) {
if (StrKit.isBlank(sharedFunctionFiles)) {
throw new IllegalArgumentException("sharedFunctionFiles can not be blank");
}
String[] fileArray = sharedFunctionFiles.split(",");
for (String fileName : fileArray) {
JFinalViewResolver.sharedFunctionFiles.add(fileName);
}
}
/**
* 通过 List 配置多个 shared function file
*
* 配置示例:
*
*
* _layout.html
* _paginate.html
*
*
*
*/
public void setSharedFunctionList(List sharedFunctionList) {
if (sharedFunctionList != null) {
JFinalViewResolver.sharedFunctionFiles.addAll(sharedFunctionList);
}
}
/**
* 添加 shared function 文件,可调用多次添加多个文件
*/
public void addSharedFunction(String fileName) {
// 等待 SourceFactory、baseTemplatePath 配置到位,利用 sharedFunctionFiles 实现延迟加载
sharedFunctionFiles.add(fileName);
}
/**
* 添加自定义指令
*/
public void addDirective(String directiveName, Class extends Directive> directiveClass) {
engine.addDirective(directiveName, directiveClass);
}
/**
* 添加自定义指令,已被 addDirective(String, Class extends Directive>) 方法取代
*/
@Deprecated
public void addDirective(String directiveName, Directive directive) {
addDirective(directiveName, directive.getClass());
}
/**
* 添加共享对象
*/
public void addSharedObject(String name, Object object) {
engine.addSharedObject(name, object);
}
/**
* 添加共享方法
*/
public void addSharedMethod(Object sharedMethodFromObject) {
engine.addSharedMethod(sharedMethodFromObject);
}
/**
* 添加共享方法
*/
public void addSharedMethod(Class> sharedMethodFromClass) {
engine.addSharedMethod(sharedMethodFromClass);
}
/**
* 添加扩展方法
*/
public static void addExtensionMethod(Class> targetClass, Object objectOfExtensionClass) {
Engine.addExtensionMethod(targetClass, objectOfExtensionClass);
}
/**
* 添加扩展方法
*/
public static void addExtensionMethod(Class> targetClass, Class> extensionClass) {
Engine.addExtensionMethod(targetClass, extensionClass);
}
/**
* 设置 ISourceFactory 用于为 engine 切换不同的 ISource 实现类
*
*
* 配置为 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);
}
/**
* 设置为 ClassPathSourceFactory 的快捷方法
* ClassPathSourceFactory 将从 CLASSPATH 与 jar 包中读取模板
*/
public void setToClassPathSourceFactory() {
engine.setToClassPathSourceFactory();
}
/**
* 设置模板基础路径
*/
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());
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy