问题描述
如何抑制 FreeMarker 模板错误?我在看这里:http://www.51sjk.com/Upload/Articles/1/0/333/333361_20221021152535147.html但我不明白如何TemplateExceptionHandler.IGNORE_HANDLER".我正在使用 Struts2 以及如何显示另一个 ftl 页面而不是显示堆栈跟踪?
How to suppress FreeMarker template error? I am looking here: http://www.51sjk.com/Upload/Articles/1/0/333/333361_20221021152535147.html But I do not understand how to "TemplateExceptionHandler.IGNORE_HANDLER." I am using Struts2 and also how to show another ftl page instead of showing the stack trace?
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://www.51sjk.com/Upload/Articles/1/0/333/333361_20221021152535147.html我该如何使用它?最后一行,cfg 是从哪里来的?
Found the above piece at http://www.51sjk.com/Upload/Articles/1/0/333/333361_20221021152535147.html How do I use this? That last line, where does cfg come from?
FreeMarker API 的主要入口点"... http://massapi.com/source/freemarker-2.3.18/src/freemarker/template/Configuration.java.html
"Main entry point into the FreeMarker API"... http://massapi.com/source/freemarker-2.3.18/src/freemarker/template/Configuration.java.html
所以,这是主要的入口点,我猜 cfg 来自这个类.我仍然没有看到控制器将如何进入我的 MyTemplateExceptionHandler 类.
So, that is the main entry point, I am guessing cfg comes from this class. I am still not seeing how the controller will come into my class MyTemplateExceptionHandler.
以下行需要去哪里?
cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());
只是将这条线放在正确的位置吗?
And is it just a matter of placing this line in correct spot?
这就是我现在的班级的样子:
This is how my current class looks like:
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().我需要做什么?
My code is going into MyTemplateExceptionHandler constructor(). But not into MyTemplateExceptionHandler1 handleTemplateException(). What do I need to do?
我仍然看到黄色的 FTL 堆栈跟踪.
I am still seeing the yellow FTL stack trace.
这个博客也指出了同样的事情:http://blog.cherouvim.com/freemarker-exception-handling/ 我应该在哪里配置我的 freemarker 以及如何配置?我仍然不知道那条线需要去哪里.
Same thing is being pointed out on this blog: http://blog.cherouvim.com/freemarker-exception-handling/ Where excatly do I configure my freemarker and how? I am still stuck as to where that line needs to go.
我的另一个问题是,博客上发布的类似乎是一个内部类,我是把那个内部类放到任何类中还是那是一个外部类?
My other question is, the class posted on the blog seems to be an inner class, do I just put that inner class into any class or is that an outer class?
推荐答案
如果想在Struts2中设置TemplateExceptionHandler为TemplateExceptionHandler.IGNORE_HANDLER,需要扩展org.apache.struts2.views.freemarker.FreemarkerManager 类,覆盖 init 和 createConfiguration 方法并在 struts.properties中配置您的自定义管理器代码>文件.
If you want to set TemplateExceptionHandler to TemplateExceptionHandler.IGNORE_HANDLER in Struts2 you need to extend org.apache.struts2.views.freemarker.FreemarkerManager class, override init and createConfiguration methods and configure your custom manager in struts.properties file.
struts.freemarker.manager.classname = your.package.YourFreeMarkerManager
更新
您的自定义 FreemarkerManager 应如下所示:
Your custom FreemarkerManager should look like that:
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 文件中:
Put that constant in your struts.xml file:
<constant name="struts.freemarker.manager.classname" value="your_package.MyFreemarkerManager" />