templateservlet.java

来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 512 行 · 第 1/2 页

JAVA
512
字号
                log("Cache miss.");
            }
        }

        //
        // Template not cached or the source file changed - compile new template!
        //
        if (template == null) {
            if (verbose) {
                log("Creating new template from file " + file + "...");
            }
            FileReader reader = null;
            try {
                reader = new FileReader(file);
                template = engine.createTemplate(reader);
            } catch (Exception e) {
                throw new ServletException("Creation of template failed: " + e, e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException ignore) {
                        // e.printStackTrace();
                    }
                }
            }
            cache.put(key, new TemplateCacheEntry(file, template, verbose));
            if (verbose) {
                log("Created and added template to cache. [key=" + key + "]");
            }
        }

        //
        // Last sanity check.
        //
        if (template == null) {
            throw new ServletException("Template is null? Should not happen here!");
        }

        return template;

    }

    /**
     * Initializes the servlet from hints the container passes.
     * <p>
     * Delegates to sub-init methods and parses the following parameters:
     * <ul>
     * <li> <tt>"generatedBy"</tt> : boolean, appends "Generated by ..." to the
     *     HTML response text generated by this servlet.
     *     </li>
     * </ul>
     * @param config
     *  Passed by the servlet container.
     * @throws ServletException
     *  if this method encountered difficulties 
     *  
     * @see TemplateServlet#initTemplateEngine(ServletConfig)
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        this.engine = initTemplateEngine(config);
        if (engine == null) {
            throw new ServletException("Template engine not instantiated.");
        }
        String value = config.getInitParameter("generated.by");
        if (value != null) {
            this.generateBy = Boolean.valueOf(value).booleanValue();
        }
        log("Servlet " + getClass().getName() + " initialized on " + engine.getClass());
    }

    /**
     * Creates the template engine.
     * 
     * Called by {@link TemplateServlet#init(ServletConfig)} and returns just 
     * <code>new groovy.text.SimpleTemplateEngine()</code> if the init parameter
     * <code>template.engine</code> is not set by the container configuration.
     * 
     * @param config 
     *  Current serlvet configuration passed by the container.
     * 
     * @return The underlying template engine or <code>null</code> on error.
     */
    protected TemplateEngine initTemplateEngine(ServletConfig config) {
        String name = config.getInitParameter("template.engine");
        if (name == null) {
            return new SimpleTemplateEngine();
        }
        try {
            return (TemplateEngine) Class.forName(name).newInstance();
        } catch (InstantiationException e) {
            log("Could not instantiate template engine: " + name, e);
        } catch (IllegalAccessException e) {
            log("Could not access template engine class: " + name, e);
        } catch (ClassNotFoundException e) {
            log("Could not find template engine class: " + name, e);
        }
        return null;
    }

    /**
     * Services the request with a response.
     * <p>
     * First the request is parsed for the source file uri. If the specified file
     * could not be found or can not be read an error message is sent as response.
     * 
     * </p>
     * @param request
     *            The http request.
     * @param response
     *            The http response.
     * @throws IOException 
     *            if an input or output error occurs while the servlet is
     *            handling the HTTP request
     * @throws ServletException
     *            if the HTTP request cannot be handled
     */
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        if (verbose) {
            log("Creating/getting cached template...");
        }

        //
        // Get the template source file handle.
        //
        File file = super.getScriptUriAsFile(request);
        String name = file.getName();
        if (!file.exists()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return; // throw new IOException(file.getAbsolutePath());
        }
        if (!file.canRead()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Can not read \"" + name + "\"!");
            return; // throw new IOException(file.getAbsolutePath());
        }

        //
        // Get the requested template.
        //
        long getMillis = System.currentTimeMillis();
        Template template = getTemplate(file);
        getMillis = System.currentTimeMillis() - getMillis;

        //
        // Create new binding for the current request.
        //
        ServletBinding binding = new ServletBinding(request, response, servletContext);
        setVariables(binding);

        //
        // Prepare the response buffer content type _before_ getting the writer.
        // and set status code to ok
        //
        response.setContentType(CONTENT_TYPE_TEXT_HTML);
        response.setStatus(HttpServletResponse.SC_OK);

        //
        // Get the output stream writer from the binding.
        //
        Writer out = (Writer) binding.getVariable("out");
        if (out == null) {
            out = response.getWriter();
        }

        //
        // Evaluate the template.
        //
        if (verbose) {
            log("Making template \"" + name + "\"...");
        }
        // String made = template.make(binding.getVariables()).toString();
        // log(" = " + made);
        long makeMillis = System.currentTimeMillis();
        template.make(binding.getVariables()).writeTo(out);
        makeMillis = System.currentTimeMillis() - makeMillis;

        if (generateBy) {
            StringBuffer sb = new StringBuffer(100);
            sb.append("\n<!-- Generated by Groovy TemplateServlet [create/get=");
            sb.append(Long.toString(getMillis));
            sb.append(" ms, make=");
            sb.append(Long.toString(makeMillis));
            sb.append(" ms] -->\n");
            out.write(sb.toString());
        }

        //
        // flush the response buffer.
        //
        response.flushBuffer();

        if (verbose) {
            log("Template \"" + name + "\" request responded. [create/get=" + getMillis + " ms, make=" + makeMillis + " ms]");
        }

    }

    /**
     * Override this method to set your variables to the Groovy binding.
     * <p>
     * All variables bound the binding are passed to the template source text, 
     * e.g. the HTML file, when the template is merged.
     * </p>
     * <p>
     * The binding provided by TemplateServlet does already include some default
     * variables. As of this writing, they are (copied from 
     * {@link groovy.servlet.ServletBinding}):
     * <ul>
     * <li><tt>"request"</tt> : HttpServletRequest </li>
     * <li><tt>"response"</tt> : HttpServletResponse </li>
     * <li><tt>"context"</tt> : ServletContext </li>
     * <li><tt>"application"</tt> : ServletContext </li>
     * <li><tt>"session"</tt> : request.getSession(<b>false</b>) </li>
     * </ul>
     * </p>
     * <p>
     * And via implicite hard-coded keywords:
     * <ul>
     * <li><tt>"out"</tt> : response.getWriter() </li>
     * <li><tt>"sout"</tt> : response.getOutputStream() </li>
     * <li><tt>"html"</tt> : new MarkupBuilder(response.getWriter()) </li>
     * </ul>
     * </p>
     *
     * <p>Example binding all servlet context variables:
     * <pre><code>
     * class Mytlet extends TemplateServlet {
     * 
     *   protected void setVariables(ServletBinding binding) {
     *     // Bind a simple variable
     *     binding.setVariable("answer", new Long(42));
     *   
     *     // Bind all servlet context attributes...
     *     ServletContext context = (ServletContext) binding.getVariable("context");
     *     Enumeration enumeration = context.getAttributeNames();
     *     while (enumeration.hasMoreElements()) {
     *       String name = (String) enumeration.nextElement();
     *       binding.setVariable(name, context.getAttribute(name));
     *     }
     *   }
     * 
     * }
     * <code></pre>
     * </p>
     * 
     * @param binding
     *  to be modified
     */
    protected void setVariables(ServletBinding binding) {
        // empty
    }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?