`
guohf
  • 浏览: 419815 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

webwork生成静态页-简单方法

阅读更多

接触模板技术的时间不是很长,原来一直通过io的方法去自己生成静态文件,后来发现了模板技术,大家都在学习,我也就跟风是的加入了行列,已开始接触的是velocity,后来看了je上的大牛的介绍,开始试用Freemarker。使用模板技术除了在web app中用来显示view之外,还有一个典型的应用就是将页面静态化,这也是提高网站性能的一个基本的办法。我的目标是这样的,通过一套模板在显示页面的同时,自动生成静态页面,并保存在用户自己的目录中。

已开始看了网上介绍的例子,基本上是通过freemarker的template来实现的,于是自己也做了这样的例子,做一个通用的接口,然后实现页面的静态化功能
public class TemplateGenerateImpl implements TemplateGenerate {
 
 private Configuration cfg;
 
 public void init() {
        cfg = new Configuration();
        cfg.setClassForTemplateLoading(TemplateGenerateImpl.class, "/templates");
        cfg.setTemplateUpdateDelay(0);
        cfg.setTemplateExceptionHandler(
                TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        cfg.setDefaultEncoding("ISO-8859-1");
        cfg.setOutputEncoding("UTF-8");
        cfg.setLocale(Locale.CHINA);
 }
 
 public void init(ServletContext sc) {
        cfg = new Configuration();
        cfg.setServletContextForTemplateLoading(
                sc, SystemConstant.TEMPLATESPATH);
        cfg.setTemplateUpdateDelay(0);
        cfg.setTemplateExceptionHandler(
                TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        cfg.setDefaultEncoding("ISO-8859-1");
        cfg.setOutputEncoding("UTF-8");
        cfg.setLocale(Locale.CHINA);
 }

 public void init(String templatePath) {
        cfg = new Configuration();
        cfg.setClassForTemplateLoading(this.getClass(), templatePath);
        cfg.setTemplateUpdateDelay(0);
        cfg.setTemplateExceptionHandler(
                TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        cfg.setDefaultEncoding("ISO-8859-1");
        cfg.setOutputEncoding("UTF-8");
        cfg.setLocale(Locale.CHINA);
 }
 
 public void show(String templateFileName, PageWrapper pw) throws IOException, TemplateException{
  Template temp = cfg.getTemplate(templateFileName);
  
  pw.getResp().setContentType("text/html; charset=" + cfg.getOutputEncoding());
  pw.getResp().setHeader("Cache-Control", "no-store, no-cache, must-revalidate, "
                + "post-check=0, pre-check=0");
  pw.getResp().setHeader("Pragma", "no-cache");
  Writer out = pw.getResp().getWriter();
  temp.process(pw.getRoot(), out);
 }
 
 public void create(String templateFileName,  PageWrapper pw, String targetFileName) throws IOException, TemplateException{
  Template temp = cfg.getTemplate(templateFileName);
  targetFileName = "d:/temp/freemarker.html";
  File file = new File(targetFileName);   
        if(!file.exists())   
            file.mkdirs();
  Writer out = new OutputStreamWriter(new FileOutputStream(targetFileName),"UTF-8");
  temp.process(pw.getRoot(), out);
        out.flush();
 }
}
然后通过spring的注入功能,自动注入到webwork的action中,这样,在action中就可以调用生成静态页面的方法了。但是实际的实验结果是,如果freemarker的模板中使用了标签技术,在生成静态页面的时候,根本就不能render模板为正确的html文件,而是把ftl作为一个io流直接输出成html了,这样的结果是不行的。于是改变模板,不使用任何标签,而使用标准的html来写模板,然后在模板中使用freemarker的data+model方式来输出页面。这种方式解决了不解析tag的毛病,静态页面可以正确的输出了,但是发现一个问题,在ftl中使用i18n出现一些问题,比如:${action.getText('reg.title')}在生成静态页面的时候会出现错误。这里的原因主要是freemarker在处理静态文件生成的时候采用temp.process(Map root, Writer out);方法,如果webwork中的ognl中的stack value没有被放进root时,这样就会出现错误,一个最简单的办法是,定义一个super action,然后将stack初始化,并放入root中,然后每个action继承super action,这样root就能得到stack value了。这样的办法虽然能解决问题,但是总是感觉有些笨拙,于是考虑了下面一个更加简单的方法。

webwork在render freemaker模板的时候,有一个缺省的result type,就是freemarker,查看了他的源代码,通过下面的方式来实现的页面输出
public void doExecute(String location, ActionInvocation invocation) throws IOException, TemplateException {
        this.location = location;
        this.invocation = invocation;
        this.configuration = getConfiguration();
        this.wrapper = getObjectWrapper();
        ...
        ...
                if (preTemplateProcess(template, model)) {
            try {
                // Process the template
                // First, get the writer
                Writer writer = null;
                boolean useOutputStream = false;
                try {
                    writer = getWriter();
                }
                ...
                ...
            }
        }
    }
我们完全可以将输出到页面上的流转换为输出到静态文件,于是自己做了一个result type,并且配置三个缺省的参数:userDirectory、staticFileName、pContentType,分别可以定义静态文件的路径、名称、类型。然后在xwork.xml中添加一种result type
<result-types>
         <result-type name="viewstatic" class="com.example.ViewAndStaticResult">
                   </result-type>
         </result-types>
<action name="register" class="com.example.Register" method="init">
      <result name="success" type="freemarker">/WEB-INF/classes/templates/register/reg.ftl</result>
      <interceptor-ref name="wsStack"></interceptor-ref>
      <!--
      <result name="success" type="viewstatic">
       <param name="location">${templateFile}</param>
       <param name="userDirectory">${userDirectory}</param>
       <param name="staticFileName">${staticFileName}</param>
      </result>
       -->
     </action>
实现的方法如下:
protected void doExecute(String location, ActionInvocation invocation) throws Exception {
  
  this.location = location;
        this.invocation = invocation;
        this.configuration = getConfiguration();
        this.wrapper = getObjectWrapper();
        this.userDirectory = (String)conditionalParse(userDirectory, invocation);
        this.staticFileName = (String)conditionalParse(staticFileName, invocation);
        if (!location.startsWith("/")) {
            ActionContext ctx = invocation.getInvocationContext();
            HttpServletRequest req = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
            String base = ResourceUtil.getResourceBase(req);
            location = base + "/" + location;
        }
       
        Template template = configuration.getTemplate(location, deduceLocale());
        TemplateModel model = createModel();

        // Give subclasses a chance to hook into preprocessing
        if (preTemplateProcess(template, model)) {
            //make static file
         makeStatic(template,model);
         //make Browser view
            makeView(template,model);
        }
    }
private void makeStatic(Template template,TemplateModel model) throws IOException, TemplateException{
     try {
            // Process the template
            // First, get the writers
            Writer swriter = null;
            boolean useOutputStream = false;
            try {
             if(getFilePath()){
              swriter = getStaticFileWriter(userDirectory+"/"+staticFileName);
             }else{
              useOutputStream = true;
             }
             
            }
            catch (IllegalStateException ise) {
                 useOutputStream = true;
            }
            ...
            ...
                template.process(model, swriter);
           
        } finally {
            // Give subclasses a chance to hook into postprocessing
            postTemplateProcess(template, model);
        }
    }
这里可以看到location是缺省参数,定义模板的位置,对于另外两个参数,用户可以定义变量${userDirectory},然后在action中给它赋值,同时也可以定义常量,在reslut中都可以正确的被解析出来,主要的方法是通过WebWorkResultSupport.conditionalParse来实现的。用户可以在xwork.xml中使用这个reslut type,在view的同时生成静态页面

分享到:
评论

相关推荐

    webwork2+velocity的登陆例子(无需改动)

    WebWork2是一个基于Java的MVC(模型-视图-控制器)框架,它在Web应用程序开发中提供了结构和可维护性。Velocity则是Apache组织开发的一个模板引擎,它允许开发者将内容与表现分离,使得HTML页面的创建更加简洁高效。...

    webwork所需的jar包

    Velocity是Apache的一个模板引擎,用于生成静态HTML、XML或其他格式的文档。在WebWork中,Velocity可以作为视图技术,用于渲染动态内容。开发者可以编写Velocity模板文件,其中包含变量和控制结构,然后使用...

    Struts2中关于ValueStack的一些操作

    通过EL,我们可以存、取对象数据,而且还可以直接访问类的静态数据,调用静态方法。 3、 WebWork的ValueStack底层有第三方开源项目OGNL实现。所以EL也都遵循OGNL的规范。我们在开发中,几乎不需要知道OGNL的细节。...

    ajax在jsp、struts、servlet、webwork中的应用

    由于WebWork已经被Struts 2所取代,这里不再详细展开其配置方法。WebWork框架中的配置与Struts框架类似,主要是通过配置文件指定Action的处理逻辑。 #### 五、总结 通过上述示例可以看出,无论是在JSP、Struts、...

    J-HI 手册 how to手册

    - **实现方式**: 枚举类型的获取可以通过枚举类本身的静态方法或Spring框架提供的工具类来实现。 **6. 如何将扩展生成的业务组件,加入手写方法代码** - **实现方式**: 在业务组件中,可以扩展生成的组件类并添加...

    学习struts2--会用前先明白原理

    - 从静态HTML页面到动态的JSP和Servlet,随着需求的增长,开发者需要更灵活的动态内容生成能力。 - MVC模式的引入,例如Struts1,将业务逻辑、视图和控制分离,提高代码可维护性。 - Struts2作为Struts1的进化版...

    struts2-指南

    - **早期Web应用**:主要是静态的HTML页面,用于简单地展示文本信息,这些信息直接写在HTML文件中,无法实现与用户的动态交互。 - **CGI技术**:通用网关接口技术(CGI)使得Web应用能够读取数据库中的信息并将其...

    freemarker(语法+实例)

    Freemarker是一个强大的Java模板引擎,它允许开发者将业务逻辑与视图层分离,使得HTML、XML等静态页面可以通过模板动态生成。以下是关于Freemarker语法和实例的详细讲解: 1. **概念** - **Sequence**:序列,类似...

    总结Java部分的框架和开源项目.docx

    ### Java框架及开源项目知识点概览 #### 一、Spring Framework ...- 生成静态网页或其他格式的文档,特别是在需要根据动态数据生成内容的情况下。 - 为 Web 应用生成动态内容,如用户界面、报表等。

    JSP框架介绍.pdf

    1. **WebWork**:WebWork是由OpenSymphony组织开发的MVC框架,它分为Xwork和WebWork2两个项目。Xwork是一个Command模式实现,提供拦截器、表单验证、类型转换等功能,而WebWork2则负责处理HTTP请求,支持多种视图...

    freemarker 学习手册

    1. WebWork是一个轻量级的MVC框架,它的控制器负责处理请求,模型处理业务逻辑,而Freemarker作为视图层,负责生成响应。 2. 结合点:WebWork将处理后的模型数据注入到Freemarker的环境中,通过模板渲染后返回给...

    struts2

    - **Servlet的工作原理**:用户通过浏览器向特定URL发起请求,Web服务器接收并处理请求,然后调用相应的Servlet来生成响应。整个过程高度自动化且高效。 ##### 1.2 MVC思想概述 - **MVC架构简介**:MVC(Model-...

    struts2讲义.doc

    Struts 2基于WebWork框架,并引入了拦截器(Interceptor)机制,使得框架更加灵活和强大,同时也支持更多的功能,如AJAX、文件上传等。 ##### Struts2的核心特性 - **标签库**:Struts 2提供了丰富的标签库,用于...

    Java EE 学习方向

    - 报表生成、测试工具、集群管理等工具和技术。 #### 五、Java Web系统设计与架构 在掌握了基础和核心技术之后,还需要学习如何设计和架构大型系统。 **技术分类:** - **Java与UML建模** - 对象图、用例图、...

    velocity demo

    它的模板文件(.vm)中,开发者可以定义变量、控制结构(如条件语句和循环)、以及调用Java方法,将动态数据嵌入到静态HTML结构中。 【压缩包子文件的文件名称列表】"AUTOCODE"可能是一个自动生成的文件或者目录名...

    Wicket开发指南

    **Wicket**是一个基于Java的Web应用开发框架,它的设计理念和技术实现与Struts、WebWork、Tapestry等框架相似,但也有其独特之处。根据给定的文档,我们可以总结出以下关键知识点: ##### 1.1 Wicket的历史背景 - ...

    JSP Tech Learn.ppt

    - **Web框架**:随着MVC(Model-View-Controller)、AOP(面向切面编程)和IoC(Inversion of Control)等设计模式的发展,出现了如Struts、WebWork、Tapestry、Spring MVC和JSF等框架,进一步提升了Web应用的开发...

Global site tag (gtag.js) - Google Analytics