templateservlet.java
来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 512 行 · 第 1/2 页
JAVA
512 行
/*
* $Id: TemplateServlet.java 4032 2006-08-30 07:18:49Z mguillem $
*
* Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 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 name "groovy" must not be used to endorse or promote products derived
* from this Software without prior written permission of The Codehaus. For
* written permission, please contact info@codehaus.org.
*
* 4. Products derived from this Software may not be called "groovy" nor may
* "groovy" appear in their names without prior written permission of The
* Codehaus. "groovy" is a registered trademark of The Codehaus.
*
* 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/
*
* THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``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 CODEHAUS 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.
*
*/
package groovy.servlet;
import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import groovy.text.TemplateEngine;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.util.Map;
import java.util.WeakHashMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A generic servlet for serving (mostly HTML) templates.
*
* <p>
* It delegates work to a <code>groovy.text.TemplateEngine</code> implementation
* processing HTTP requests.
*
* <h4>Usage</h4>
*
* <code>helloworld.html</code> is a headless HTML-like template
* <pre><code>
* <html>
* <body>
* <% 3.times { %>
* Hello World!
* <% } %>
* <br>
* </body>
* </html>
* </code></pre>
*
* Minimal <code>web.xml</code> example serving HTML-like templates
* <pre><code>
* <web-app>
* <servlet>
* <servlet-name>template</servlet-name>
* <servlet-class>groovy.servlet.TemplateServlet</servlet-class>
* </servlet>
* <servlet-mapping>
* <servlet-name>template</servlet-name>
* <url-pattern>*.html</url-pattern>
* </servlet-mapping>
* </web-app>
* </code></pre>
*
* <h4>Template engine configuration</h4>
*
* <p>
* By default, the TemplateServer uses the {@link groovy.text.SimpleTemplateEngine}
* which interprets JSP-like templates. The init parameter <code>template.engine</code>
* defines the fully qualified class name of the template to use:
* <pre>
* template.engine = [empty] - equals groovy.text.SimpleTemplateEngine
* template.engine = groovy.text.SimpleTemplateEngine
* template.engine = groovy.text.GStringTemplateEngine
* template.engine = groovy.text.XmlTemplateEngine
* </pre>
*
* <h4>Logging and extra-output options</h4>
*
* <p>
* This implementation provides a verbosity flag switching log statements.
* The servlet init parameter name is:
* <pre>
* generate.by = true(default) | false
* </pre>
*
* @see TemplateServlet#setVariables(ServletBinding)
*
* @author Christian Stein
* @author Guillaume Laforge
* @version 2.0
*/
public class TemplateServlet extends AbstractHttpServlet {
/**
* Simple cache entry that validates against last modified and length
* attributes of the specified file.
*
* @author Christian Stein
*/
private static class TemplateCacheEntry {
Date date;
long hit;
long lastModified;
long length;
Template template;
public TemplateCacheEntry(File file, Template template) {
this(file, template, false); // don't get time millis for sake of speed
}
public TemplateCacheEntry(File file, Template template, boolean timestamp) {
if (file == null) {
throw new NullPointerException("file");
}
if (template == null) {
throw new NullPointerException("template");
}
if (timestamp) {
this.date = new Date(System.currentTimeMillis());
} else {
this.date = null;
}
this.hit = 0;
this.lastModified = file.lastModified();
this.length = file.length();
this.template = template;
}
/**
* Checks the passed file attributes against those cached ones.
*
* @param file
* Other file handle to compare to the cached values.
* @return <code>true</code> if all measured values match, else <code>false</code>
*/
public boolean validate(File file) {
if (file == null) {
throw new NullPointerException("file");
}
if (file.lastModified() != this.lastModified) {
return false;
}
if (file.length() != this.length) {
return false;
}
hit++;
return true;
}
public String toString() {
if (date == null) {
return "Hit #" + hit;
}
return "Hit #" + hit + " since " + date;
}
}
/**
* Simple file name to template cache map.
*/
private final Map cache;
/**
* Underlying template engine used to evaluate template source files.
*/
private TemplateEngine engine;
/**
* Flag that controls the appending of the "Generated by ..." comment.
*/
private boolean generateBy;
/**
* Create new TemplateSerlvet.
*/
public TemplateServlet() {
this.cache = new WeakHashMap();
this.engine = null; // assigned later by init()
this.generateBy = true; // may be changed by init()
}
/**
* Gets the template created by the underlying engine parsing the request.
*
* <p>
* This method looks up a simple (weak) hash map for an existing template
* object that matches the source file. If the source file didn't change in
* length and its last modified stamp hasn't changed compared to a precompiled
* template object, this template is used. Otherwise, there is no or an
* invalid template object cache entry, a new one is created by the underlying
* template engine. This new instance is put to the cache for consecutive
* calls.
* </p>
*
* @return The template that will produce the response text.
* @param file
* The HttpServletRequest.
* @throws ServletException
* If the request specified an invalid template source file
*/
protected Template getTemplate(File file) throws ServletException {
String key = file.getAbsolutePath();
Template template = null;
/*
* Test cache for a valid template bound to the key.
*/
if (verbose) {
log("Looking for cached template by key \"" + key + "\"");
}
TemplateCacheEntry entry = (TemplateCacheEntry) cache.get(key);
if (entry != null) {
if (entry.validate(file)) {
if (verbose) {
log("Cache hit! " + entry);
}
template = entry.template;
} else {
if (verbose) {
log("Cached template needs recompiliation!");
}
}
} else {
if (verbose) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?