出家如初,成佛有余

Struts2中静态页面生成策略

Posted in Uncategorized by chuanliang on 2008/05/26

    利用Struts2生成静态页面其实很灵活,很强大,尤其是利用Struts2对Freemarker较好的支持,充分利用Freemarker的模板功能来生成静态页面。

    基本思路为:利用Struts2对自定义result type的支持,自定义能够生成静态页面的result type,结合模板引擎Freemarker可以实现大批量静态页面的生成。

    参看org.apache.struts2.views.freemarker.FreemarkerResult的代码实现,自定义了自己的生成静态页面的result type。此种方案不单纯用于生成静态页面,其实也可以用于生成诸如wml、xhtml等内容,具体可以参考Struts2缺省提供的各种result type的实现。

1、com.mobilesoft.esales.webapp.action.FreemarkerResult

package com.mobilesoft.esales.webapp.action;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.util.ResourceUtil;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

public class FreemarkerResult extends StrutsResultSupport {

    private static final long serialVersionUID = -3778230771704661631L;

    protected ActionInvocation invocation;
    protected Configuration configuration;
    protected ObjectWrapper wrapper;
    protected FreemarkerManager freemarkerManager;
    private Writer writer;
    protected String location;
    private String pContentType = “text/html”;

    protected String fileName; // 要生成的静态页面名称
    protected String filePath; // 要生成的静态页面的路径
    protected String staticTemplate; // 用于生成静态页面Freemarker模板的路径

    public FreemarkerResult() {
        super();
    }

    public FreemarkerResult(String location) {
        super(location);
    }

    @Inject
    public void setFreemarkerManager(FreemarkerManager mgr) {
        this.freemarkerManager = mgr;
    }

    public void setContentType(String aContentType) {
        pContentType = aContentType;
    }

    public String getContentType() {
        return pContentType;
    }

    public void doExecute(String location, ActionInvocation invocation)
            throws IOException, TemplateException {
        this.location = location;
        this.invocation = invocation;
        this.configuration = getConfiguration();
        this.wrapper = getObjectWrapper();

        this.fileName = (String) conditionalParse(fileName, invocation);
        this.staticTemplate = (String) conditionalParse(staticTemplate, invocation);
        this.filePath = ((String) conditionalParse(filePath, invocation)) == null ? “”
                : ((String) conditionalParse(filePath, invocation));

        if (!location.startsWith(“/”)) {
            ActionContext ctx = invocation.getInvocationContext();
            HttpServletRequest req = (HttpServletRequest) ctx
                    .get(ServletActionContext.HTTP_REQUEST);
            String base = ResourceUtil.getResourceBase(req);
            location = base + “/” + location;
        }

        //生成html页面的模板类
        Template template = configuration.getTemplate(location, deduceLocale());
        // 生成静态页面的的模板类
        Template staticTemplate = configuration.getTemplate(this.staticTemplate,
                deduceLocale());

        TemplateModel model = createModel();
        String path = ServletActionContext.getServletContext().getRealPath(
                filePath)
                + File.separator;
        Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(path + fileName)));

        if (preTemplateProcess(template, model)) {
            try {
                staticTemplate.process(model, out);
                template.process(model, getWriter());
            } finally {
                postTemplateProcess(template, model);
                postTemplateProcess(staticTemplate, model);
            }
        }
    }

    protected Configuration getConfiguration() throws TemplateException {
        return freemarkerManager.getConfiguration(ServletActionContext
                .getServletContext());
    }

    protected ObjectWrapper getObjectWrapper() {
        return configuration.getObjectWrapper();
    }

    public void setWriter(Writer writer) {
        this.writer = writer;
 &
nbsp;  }

    protected Writer getWriter() throws IOException {
        if (writer != null) {
            return writer;
        }
        return ServletActionContext.getResponse().getWriter();
    }

    protected TemplateModel createModel() throws TemplateModelException {
        ServletContext servletContext = ServletActionContext
                .getServletContext();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        ValueStack stack = ServletActionContext.getContext().getValueStack();

        Object action = null;
        if (invocation != null)
            action = invocation.getAction(); // Added for NullPointException
        return freemarkerManager.buildTemplateModel(stack, action,
                servletContext, request, response, wrapper);
    }

    protected Locale deduceLocale() {
        if (invocation.getAction() instanceof LocaleProvider) {
            return ((LocaleProvider) invocation.getAction()).getLocale();
        } else {
            return configuration.getLocale();
        }
    }

    protected void postTemplateProcess(Template template, TemplateModel data)
            throws IOException {
    }

    protected boolean preTemplateProcess(Template template, TemplateModel model)
            throws IOException {
        Object attrContentType = template.getCustomAttribute(“content_type”);

        if (attrContentType != null) {
            ServletActionContext.getResponse().setContentType(
                    attrContentType.toString());
        } else {
            String contentType = getContentType();

            if (contentType == null) {
                contentType = “text/html”;
            }

            String encoding = template.getEncoding();

            if (encoding != null) {
                contentType = contentType + “; charset=” + encoding;
            }

            ServletActionContext.getResponse().setContentType(contentType);
        }

        return true;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public String getStaticTemplate() {
        return staticTemplate;
    }

    public void setStaticTemplate(String staticTemplate) {
        this.staticTemplate = staticTemplate;
    }
}

 

2、struts.xml

        <action name=”staticViewAction” class=”com.mobilesoft.esales.webapp.action.StaticViewtAction”>
            <result name=”success” type=”staticview”>
                <param name=”location”>test/freemarkertest.ftl</param>
                <param name=”contentType”>text/html</param>
                 <param name=”fileName”>${filename}</param>
                <param name=”staticTemplate”>test/freemarkertest.ftl</param>
                <param name=”filePath”>static</param>
            </result>                   
        </action>

 

No Responses Yet

Subscribe to comments with RSS.

  1. devil said, on 2008/06/27 at 17:35

    请教个问题,自己写一个result是没有问题的,但是如果批量生成静态的,该如何实现?

  2. talangniao said, on 2009/01/15 at 14:35

    怎样大批量生成?

  3. flyer said, on 2009/09/03 at 17:23

    真的不错!比那些小的好多了

  4. jeff said, on 2009/12/15 at 16:00

    为什么重复生成页面时,会报错?文件已经被使用。


发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: