处理 FreeMarker 模板中的错误都有哪些不同的方法?
Posted
技术标签:
【中文标题】处理 FreeMarker 模板中的错误都有哪些不同的方法?【英文标题】:What are different ways to handle error in FreeMarker template?处理 FreeMarker 模板中的错误有哪些不同的方法? 【发布时间】:2013-02-13 22:44:57 【问题描述】:如何抑制 FreeMarker 模板错误? 我在看这里:http://freemarker.sourceforge.net/docs/pgui_config_errorhandling.html 但我不明白如何“TemplateExceptionHandler.IGNORE_HANDLER”。我正在使用 Struts2 以及如何显示另一个 ftl 页面而不是显示堆栈跟踪?
class MyTemplateExceptionHandler implements TemplateExceptionHandler
public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out)
throws TemplateException
try
out.write("[ERROR: " + te.getMessage() + "]");
catch (IOException e)
throw new TemplateException("Failed to print error message. Cause: " + e, env);
...
cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());
在http://freemarker.sourceforge.net/docs/pgui_config_errorhandling.html找到了上面的文章 我该如何使用它?最后一行,cfg 是从哪里来的?
“FreeMarker API 的主要入口点”...http://massapi.com/source/freemarker-2.3.18/src/freemarker/template/Configuration.java.html
所以,这是主要的入口点,我猜 cfg 来自这个类。我仍然没有看到控制器将如何进入我的 MyTemplateExceptionHandler 类。
以下行需要去哪里?
cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());
只是将这条线放在正确的位置吗?
这就是我现在的班级的样子:
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.Properties;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.WebappTemplateLoader;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
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.ObjectWrapper;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateModel;
import javax.servlet.GenericServlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.views.JspSupportServlet;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.freemarker.ScopesHashModel;
import org.apache.struts2.views.freemarker.StrutsBeanWrapper;
import org.apache.struts2.views.freemarker.StrutsClassTemplateLoader;
import org.omg.CORBA.PUBLIC_MEMBER;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.FileManager;
import com.opensymphony.xwork2.util.ValueStack;
public class MyTemplateExceptionHandler extends org.apache.struts2.views.freemarker.FreemarkerManager
freemarker.template.Configuration configuration = new freemarker.template.Configuration();
public MyTemplateExceptionHandler()
System.out.println("MyTemplateExceptionHandler constructor()");
configuration.setTemplateExceptionHandler(new Test1());
class Test1 implements TemplateExceptionHandler
@Override
public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out) throws TemplateException
System.out.println("MyTemplateExceptionHandler1 handleTemplateException()");
try
out.write("[ERROR TEST TEST: " + te.getMessage() + "]");
catch (IOException e)
throw new TemplateException("Failed to print error message. Cause: " + e, env);
我的代码将进入 MyTemplateExceptionHandler 构造函数()。但不能进入 MyTemplateExceptionHandler1 handleTemplateException()。我需要做什么?
我仍然看到黄色的 FTL 堆栈跟踪。
这个博客上也指出了同样的事情:http://blog.cherouvim.com/freemarker-exception-handling/ 我在哪里配置我的 freemarker 以及如何配置?我仍然不知道那条线需要去哪里。
我的另一个问题是,博客上发布的类似乎是一个内部类,我是把那个内部类放到任何类中还是那是一个外部类?
【问题讨论】:
【参考方案1】:如果你想在 freemarker 中处理它,使用它的attempt-recover 机制:
<#attempt>
attempt block
<#recover>
recover block
</#attempt>
类似于 Java 的 try-catch。
【讨论】:
不,我正在为产品发布做准备。我需要从一个地方处理所有事情。我喜欢上面的答案,但我仍然找不到一些例子。 这是个好方法【参考方案2】:如果您想在 Struts2 中将 TemplateExceptionHandler
设置为 TemplateExceptionHandler.IGNORE_HANDLER
,您需要扩展 org.apache.struts2.views.freemarker.FreemarkerManager
类,覆盖 init
和 createConfiguration
方法并在 struts.properties
文件中配置您的自定义管理器。
struts.freemarker.manager.classname = your.package.YourFreeMarkerManager
更新
您的自定义 FreemarkerManager 应如下所示:
public class MyFreemarkerManager extends
org.apache.struts2.views.freemarker.FreemarkerManager
private static final Logger LOG = LoggerFactory
.getLogger(MyFreemarkerManager.class);
@Override
public void init(ServletContext servletContext) throws TemplateException
config = createConfiguration(servletContext);
// Set defaults:
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
contentType = DEFAULT_CONTENT_TYPE;
// Process object_wrapper init-param out of order:
wrapper = createObjectWrapper(servletContext);
if(LOG.isDebugEnabled())
LOG.debug("Using object wrapper of class " + wrapper.getClass().getName());
config.setObjectWrapper(wrapper);
// Process TemplatePath init-param out of order:
templatePath = servletContext.getInitParameter(INITPARAM_TEMPLATE_PATH);
if(templatePath == null)
templatePath = servletContext.getInitParameter("templatePath");
config
.setTemplateLoader(createTemplateLoader(servletContext, templatePath));
loadSettings(servletContext);
@Override
protected Configuration createConfiguration(ServletContext servletContext)
throws TemplateException
Configuration configuration = new Configuration();
configuration
.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
if(mruMaxStrongSize > 0)
configuration.setSetting(Configuration.CACHE_STORAGE_KEY, "strong:"
+ mruMaxStrongSize);
if(templateUpdateDelay != null)
configuration.setSetting(Configuration.TEMPLATE_UPDATE_DELAY_KEY,
templateUpdateDelay);
if(encoding != null)
configuration.setDefaultEncoding(encoding);
configuration.setWhitespaceStripping(true);
return configuration;
将该常量放入您的 struts.xml 文件中:
<constant name="struts.freemarker.manager.classname" value="your_package.MyFreemarkerManager" />
【讨论】:
有什么例子吗?我在哪里可以找到一些代码示例?有什么参考吗?我在哪里可以更深入地了解这一点?谢谢。 @NomanArain:看看org.apache.struts2.views.freemarker.FreemarkerManager
类。
嘿,如果你能回答我最新的问题,那真的很有帮助。这条线需要去哪里:cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());?只是将这条线放在正确的位置吗?
在 Struts2 中,您需要创建自己的自定义类来扩展 org.apache.struts2.views.freemarker.FreemarkerManager
。看一下这个类的源代码,你会看到TemplateExceptionHandler
的设置位置。
我在这里看到:docjar.com/html/api/org/apache/struts2/views/freemarker/… 但是该类与freemarker.sourceforge.net/docs/pgui_config_errorhandling.html 提供的内部类有什么关系?我不明白看 FreemarkerManager 课程对我有什么帮助?【参考方案3】:
您还可以将freemarker.properties
与以下key=value
一起使用:
template_exception_handler = rethrow
只需将您的 freemarker.properties
放在类路径中即可。
我认为这是一种更清洁的方法。
【讨论】:
这将无法创建您自己的异常处理程序以上是关于处理 FreeMarker 模板中的错误都有哪些不同的方法?的主要内容,如果未能解决你的问题,请参考以下文章
在 Freemarker 模板中显示 Spring MVC 验证错误
处理 Mozilla Firefox 中的“可见性:折叠”错误都有哪些好的解决方法?