📄 freemarkerservlet.java
字号:
/*
* Copyright (c) 2003 The Visigoth Software Society. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Visigoth Software Society (http://www.visigoths.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
* project contributors may be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact visigoths@visigoths.org.
*
* 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
* nor may "FreeMarker" or "Visigoth" appear in their names
* without prior written permission of the Visigoth Software Society.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Visigoth Software Society. For more
* information on the Visigoth Software Society, please see
* http://www.visigoths.org/
*/
package freemarker.ext.servlet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import freemarker.cache.WebappTemplateLoader;
import freemarker.core.Configurable;
import freemarker.ext.jsp.TaglibFactory;
import freemarker.log.Logger;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.StringUtil;
import java.util.Locale;
/**
* <p>This is a general-purpose FreeMarker view servlet.</p>
*
* <p>The main features are:
*
* <ul>
*
* <li>It makes all request, request parameters, session, and servlet
* context attributes available to templates through <code>Request</code>,
* <code>RequestParameters</code>, <code>Session</code>, and <code>Application</code>
* variables.
*
* <li>The scope variables are also available via automatic scope discovery. That is,
* writing <code>Application.attrName</code>, <code>Session.attrName</code>,
* <code>Request.attrName</code> is not mandatory; it's enough to write <code>attrName</code>,
* and if no such variable was created in the template, it will search the
* variable in <code>Request</code>, and then in <code>Session</code>,
* and finally in <code>Application</code>.
*
* <li>It creates a variable with name <code>JspTaglibs</code>, that can be used
* to load JSP taglibs. For example:<br>
* <code><#assign tiles=JspTaglibs["/WEB-INF/struts-tiles.tld"]></code>
*
* </ul>
*
* <p>The servlet will rethrow the errors occurring during template processing,
* wrapped into <code>ServletException</code>, except if the class name of the
* class set by the <code>template_exception_handler</code> contains the
* substring <code>"Debug"</code>. If it contains <code>"Debug"</code>, then it
* is assumed that the template exception handler prints the error message to the
* page, thus <code>FreemarkerServlet</code> will suppress the exception, and
* logs the problem with the servlet logger
* (<code>javax.servlet.GenericServlet.log(...)</code>).
*
* <p>Supported init-params are:</p>
*
* <ul>
*
* <li><strong>TemplatePath</strong> specifies the location of the templates.
* By default, this is interpreted as web application directory relative URI.<br>
* Alternatively, you can prepend it with <tt>file://</tt> to indicate a literal
* path in the file system (i.e. <tt>file:///var/www/project/templates/</tt>).
* Note that three slashes were used to specify an absolute path.<br>
* Also, you can prepend it with <tt>class://path/to/template/package</tt> to
* indicate that you want to load templates from the specified package
* accessible through the classloader of the servlet.<br>
* Default value is <tt>class://</tt> (that is, the root of the class hierarchy).
* <i>Note that this default is different than the default in FreeMarker 1.x, when
* it defaulted <tt>/</tt>, that is to loading from the webapp root directory.</i></li>
*
* <li><strong>NoCache</strong> if set to true, generates headers in the response
* that advise the HTTP client not to cache the returned page.
* The default is <tt>false</tt>.</li>
*
* <li><strong>ContentType</strong> if specified, response uses the specified
* Content-type HTTP header. The value may include the charset (e.g.
* <tt>"text/html; charset=ISO-8859-1"</tt>). If not specified, <tt>"text/html"</tt>
* is used. If the charset is not specified in this init-param, then the charset
* (encoding) of the actual template file will be used (in the response HTTP header
* and for encoding the output stream). Note that this setting can be overridden
* on a per-template basis by specifying a custom attribute named
* <tt>content_type</tt> in the <tt>attributes</tt> parameter of the
* <tt><#ftl></tt> directive.
* </li>
*
* <li>The following init-params are supported only for backward compatibility, and
* their usage is discouraged: TemplateUpdateInterval, DefaultEncoding,
* ObjectWrapper, TemplateExceptionHandler. Use setting init-params such as
* object_wrapper instead.
*
* <li>Any other init-param will be interpreted as <code>Configuration</code>
* level setting. See {@link Configuration#setSetting}</li>
*
* </ul>
*
* @author Attila Szegedi
* @version $Id: FreemarkerServlet.java,v 1.82.2.5 2006/06/21 13:02:01 ddekany Exp $
*/
public class FreemarkerServlet extends HttpServlet
{
private static final Logger logger = Logger.getLogger("freemarker.servlet");
public static final long serialVersionUID = -2440216393145762479L;
private static final String INITPARAM_TEMPLATE_PATH = "TemplatePath";
private static final String INITPARAM_NOCACHE = "NoCache";
private static final String INITPARAM_CONTENT_TYPE = "ContentType";
private static final String DEFAULT_CONTENT_TYPE = "text/html";
private static final String INITPARAM_DEBUG = "Debug";
private static final String DEPR_INITPARAM_TEMPLATE_DELAY = "TemplateDelay";
private static final String DEPR_INITPARAM_ENCODING = "DefaultEncoding";
private static final String DEPR_INITPARAM_OBJECT_WRAPPER = "ObjectWrapper";
private static final String DEPR_INITPARAM_WRAPPER_SIMPLE = "simple";
private static final String DEPR_INITPARAM_WRAPPER_BEANS = "beans";
private static final String DEPR_INITPARAM_WRAPPER_JYTHON = "jython";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER = "TemplateExceptionHandler";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW = "rethrow";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG = "debug";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_HTML_DEBUG = "htmlDebug";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_IGNORE = "ignore";
private static final String DEPR_INITPARAM_DEBUG = "debug";
public static final String KEY_REQUEST = "Request";
public static final String KEY_REQUEST_PRIVATE = "__FreeMarkerServlet.Request__";
public static final String KEY_REQUEST_PARAMETERS = "RequestParameters";
public static final String KEY_SESSION = "Session";
public static final String KEY_APPLICATION = "Application";
public static final String KEY_APPLICATION_PRIVATE = "__FreeMarkerServlet.Application__";
public static final String KEY_JSP_TAGLIBS = "JspTaglibs";
// Note these names start with dot, so they're essentially invisible from
// a freemarker script.
private static final String ATTR_REQUEST_MODEL = ".freemarker.Request";
private static final String ATTR_REQUEST_PARAMETERS_MODEL =
".freemarker.RequestParameters";
private static final String ATTR_SESSION_MODEL = ".freemarker.Session";
private static final String ATTR_APPLICATION_MODEL =
".freemarker.Application";
private static final String ATTR_JSP_TAGLIBS_MODEL =
".freemarker.JspTaglibs";
private static final String EXPIRATION_DATE;
static {
// Generate expiration date that is one year from now in the past
GregorianCalendar expiration = new GregorianCalendar();
expiration.roll(Calendar.YEAR, -1);
SimpleDateFormat httpDate =
new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z",
java.util.Locale.US);
EXPIRATION_DATE = httpDate.format(expiration.getTime());
}
private String templatePath;
private boolean nocache;
protected boolean debug;
private Configuration config;
private ObjectWrapper wrapper;
private String contentType;
private boolean noCharsetInContentType;
public void init() throws ServletException {
try {
config = createConfiguration();
// Set defaults:
config.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
contentType = DEFAULT_CONTENT_TYPE;
// Process object_wrapper init-param out of order:
wrapper = createObjectWrapper();
if (logger.isDebugEnabled()) {
logger.debug("Using object wrapper of class " + wrapper.getClass().getName());
}
config.setObjectWrapper(wrapper);
// Process TemplatePath init-param out of order:
templatePath = getInitParameter(INITPARAM_TEMPLATE_PATH);
if (templatePath == null)
templatePath = "class://";
if (templatePath.startsWith("class://")) {
// substring(7) is intentional as we "reuse" the last slash
config.setClassForTemplateLoading(
getClass(),
templatePath.substring(7));
} else {
if (templatePath.startsWith("file://")) {
templatePath = templatePath.substring(7);
config.setDirectoryForTemplateLoading(new File(templatePath));
} else {
config.setTemplateLoader(new WebappTemplateLoader(this.getServletContext(), templatePath));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -