Каковы различные способы обработки ошибок в шаблоне FreeMarker?
Как подавить ошибку шаблона 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?
"Главная точка входа в API FreeMarker"... 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
Если вы хотите установить TemplateExceptionHandler
в TemplateExceptionHandler.IGNORE_HANDLER
в Struts2, вам необходимо расширить классы org.apache.struts2.views.freemarker.FreemarkerManager
, переопределить init
и createConfiguration
и настроить свой пользовательский менеджер в файле struts.properties
.
struts.freemarker.manager.classname = your.package.YourFreeMarkerManager
UPDATE
Ваш пользовательский 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" />
Ответ 2
Если вы хотите обработать его внутри freemarker, используйте механизм try-recover:
<#attempt>
attempt block
<#recover>
recover block
</#attempt>
Он аналогичен Java try-catch.
Ответ 3
Вы также можете использовать freemarker.properties
со следующим key=value
:
template_exception_handler = rethrow
Просто поместите свой freemarker.properties
в путь к классам.
Я думаю, что это намного более чистый подход.