服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

velocity实例

 


 velocity 是一个基于 java 的通用模板工具,来自于 jakarta.apache.org 。

velocity 的介绍请参考 velocity -- java web 开发新技术。这里是它的一个应用示例。

这个例子参照了 php-nuke 的结构, 即所有 http 请求都以 http://www.some.com/xxx/modules?name=xxx&arg1=xxx&bbb=xxx 的形式进行处理。例子中所有文件都是 .java 和 .html , 没有其他特殊的文件格式。除了 modules.java 是 java servlet, 其余的 .java 文件都是普通的 java class.

所有 http 请求都通过 modules.java 处理。modules.java 通过 velocity 加载 modules.htm。 modules.htm 有页头,页脚,页左导航链接,页中内容几个部分。其中页头广告、页中内容是变化部分。页头广告由 modules.java 处理,页中内容部分由 modules.java dispatch 到子页面类处理。

1) modules.java

        import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.velocity.*;
import org.apache.velocity.context.*;
import org.apache.velocity.exception.*;
import org.apache.velocity.servlet.*;
import commontools.*;

public class modules
  extends velocityservlet {
  public template handlerequest(httpservletrequest request,
                 httpservletresponse response,
                 context context) {
    //init
    response.setcontenttype("text/html; charset=utf-8");
    response.setcharacterencoding("utf-8");

    //prepare function page
    processsubpage page = null;
    processsubpage mainpage = new homesubpage();
    string requestfunctionname = (string) request.getparameter("name");
    boolean logined = false;

    string loginaccount = (string) request.getsession(true).getattribute(
      "loginaccount");
    if (loginaccount != null) {
      logined = true;
    }

    //default page is mainpage
    page = mainpage;
    if (requestfunctionname == null||requestfunctionname.equalsignorecase("home")) {
      page = mainpage;
    }

    //no login , can use these page
    else if (requestfunctionname.equalsignorecase("login")) {
      page = new loginprocesssubpage();
    }
    else if (requestfunctionname.equalsignorecase("changepassword")) {
      page = new changepasswordsubpage();
    }
    else if (requestfunctionname.equalsignorecase("forgetpassword")) {
      page = new forgetpassword();
    }
    else if (requestfunctionname.equalsignorecase("about")) {
      page = new aboutsubpage();
    }
    else if (requestfunctionname.equalsignorecase("contact")) {
      page = new contactsubpage();
    }


    //for other page, need login first
    else if (logined == false) {
      page = new loginprocesssubpage();
    }

    else if (requestfunctionname.equalsignorecase("listprogram")) {
      page = new listtransactionprogramsubpage();
    }
    else if (requestfunctionname.equalsignorecase(
      "viewprogramitem")) {
      page = new viewtransactionprogramitemsubpage();
    }
    else if (requestfunctionname.equalsignorecase(
      "updateprogramobjstatus")) {
      page = new updatetransactionprogramobjstatussubpage();
    }
    else if (requestfunctionname.equalsignorecase(
      "search")) {
      page = new searchsubpage();
    }

    //check if this is administrator
    else if (utilities.isadministratorlogined(request)) {
      //utilities.debugprintln("isadministratorlogined : true");
      if (requestfunctionname.equalsignorecase("usermanagement")) {
        page = new usermanagementsubpage();
      }
      else if (requestfunctionname.equalsignorecase(
        "uploadfiles")) {
        page = new uploadfilessubpage();
      }
      else if (requestfunctionname.equalsignorecase(
        "downloadfile")) {
        page = new downloadfilesubpage();
      }
      else if (requestfunctionname.equalsignorecase(
        "report")) {
        page = new reportsubpage();
      }

    }
    else {
      //no right to access.
      //utilities.debugprintln("isadministratorlogined : false");
      page = null;
    }
    //utilities.debugprintln("page : " + page.getclass().getname());

    if(page != null){
      context.put("function_page",
            page.gethtml(this, request, response, context));
    }else{
      string msg = "sorry, this module is for administrator only.you are not administrator.";
      context.put("function_page",msg);
    }
    
    context.put("page_header",getpageheaderhtml());
    context.put("page_footer",getpagefooterhtml());

    template template = null;
    try {
      template = gettemplate("/templates/modules.htm"); //good
    }
    catch (resourcenotfoundexception rnfe) {
      utilities.debugprintln("resourcenotfoundexception 2");
      rnfe.printstacktrace();
    }
    catch (parseerrorexception pee) {
      utilities.debugprintln("parseerrorexception2 " + pee.getmessage());
    }
    catch (exception e) {
      utilities.debugprintln("exception2 " + e.getmessage());
    }

    return template;
  }

  /**
   * loads the configuration information and returns that information as a properties, e
   * which will be used to initializ the velocity runtime.
   */
  protected java.util.properties loadconfiguration(servletconfig config) throws
    java.io.ioexception, java.io.filenotfoundexception {
    return utilities.initservletenvironment(this);

  }

}        
2) processsubpage.java , 比较简单,只定义了一个函数接口 gethtml

     
  import javax.servlet.http.*;
import org.apache.velocity.context.*;
import org.apache.velocity.servlet.*;
import commontools.*;

public abstract class processsubpage implements java.io.serializable {
  public processsubpage() {
  }

  public string gethtml(velocityservlet servlet, httpservletrequest request,
             httpservletresponse response,
             context context) {
    utilities.debugprintln(
      "you need to override this method in sub class of processsubpage:"
      + this.getclass().getname());
    return "sorry, this module not finish yet.";
  }

}
  
     

他的 .java 文件基本上是 processsubpage 的子类和一些工具类。 processsubpage 的子类基本上都是一样的流程, 用类似
context.put("page_footer",getpagefooterhtml());
的写法置换 .html 中的可变部分即可。如果没有可变部分,完全是静态网页,比如 aboutsubpage, 就更简单。

3) aboutsubpage.java

     
  import org.apache.velocity.servlet.velocityservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.apache.velocity.context.context;

public class aboutsubpage extends processsubpage {
  public aboutsubpage() {
  }

  public string gethtml(velocityservlet servlet, httpservletrequest request,
             httpservletresponse response, context context) {
    //prepare data
    //context.put("xxx","xxxx");         
             
    template template = null;
    string filename = "about.htm";
    try {
      template = servlet.gettemplate(filename);
      stringwriter sw = new stringwriter();
      template.merge(context, sw);
      return sw.tostring();
    }
    catch (exception ex) {
      return "error get template " + filename + " " + ex.getmessage();
    }
  }
}
  
     

其他 processsubpage 的子类如上面基本类似,只不过会多了一些 context.put("xxx","xxxx") 的语句。

通过以上的例子,我们可以看到,使用 velocity + servlet , 所有的代码为: 1 个 java serverlet + m 个 java class + n 个 html 文件。

这里是用了集中处理,然后分发(dispatch)的机制。不用担心用户在没有登陆的情况下访问某些页面。用户验证,页眉页脚包含都只写一次,易于编写、修改和维护。代码比较简洁,并且很容易加上自己的页面缓冲功能。可以随意将某个页面的 html 在内存中保存起来,缓存几分钟,实现页面缓冲功能。成功、出错页面也可以用同样的代码封装成函数,通过参数将 message/title 传入即可。

因为 java 代码与 html 代码完全在不同的文件中,美工与java代码人员可以很好的分工,每个人修改自己熟悉的文件,基本上不需要花时间做协调工作。而用 jsp, 美工与java代码人员共同修改维护 .jsp 文件,麻烦多多,噩梦多多。而且这里没有用 xml ,说实话,懂 xml/xls 之类的人只占懂 java 程序员中的几分之一,人员不好找。

因为所有 java 代码人员写的都是标准 java 程序,可以用任何 java 编辑器,调试器,因此开发速度也会大大提高。美工写的是标准 html 文件,没有 xml, 对于他们也很熟悉,速度也很快。并且,当需要网站改版的时候,只要美工把 html 文件重新修饰排版即可,完全不用改动一句 java 代码。

爽死了!!

4) 工具类 utilities.java

     
  import java.io.*;
import java.sql.*;
import java.text.*;
import java.util.*;
import java.util.date;
import javax.naming.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.velocity.*;
import org.apache.velocity.app.*;
import org.apache.velocity.context.context;
import org.apache.velocity.servlet.*;

public class utilities {
  private static properties m_servletconfig = null;

  private utilities() {
  }

  static {
    initjavamail();
  }

  public static void debugprintln(object o) {
    string msg = "proj debug message at " + getnowtimestring() +
      " ------------- ";
    system.err.println(msg + o);
  }

  public static properties initservletenvironment(velocityservlet v) {
    // init only once
    if (m_servletconfig != null) {
      return m_servletconfig;
    }

    //debugprintln("initservletenvironment....");

    try {
      /*
       * call the overridable method to allow the
       * derived classes a shot at altering the configuration
       * before initializing runtime
       */
      properties p = new properties();

      servletconfig config = v.getservletconfig();

      // set the velocity.file_resource_loaded_path property
      // to the root directory of the context.
      string path = config.getservletcontext().getrealpath("/");
      //debugprintln("real path of / is : " + path);
      p.setproperty(velocity.file_resource_loader_path, path);

      // set the velocity.runtime_log property to be the file
      // velocity.log relative to the root directory
      // of the context.
      p.setproperty(velocity.runtime_log, path +
             "velocity.log");
// return the properties object.
//return p;

      velocity.init(p);
      m_servletconfig = p;
      return p;
    }
    catch (exception e) {
      debugprintln(e.getmessage());
      //throw new servletexception("error initializing velocity: " + e);
    }
    return null;

    //this.getservletcontext().getrealpath("/");
  }

  private static void initjavamail() {
  }

  public static connection getdatabaseconnection() {
    connection con = null;
    try {
      initialcontext initctx = new initialcontext();
      javax.naming.context context = (javax.naming.context) initctx.
        lookup("java:comp/env");
      javax.sql.datasource ds = (javax.sql.datasource) context.lookup(
        "jdbc/testdb");
      //utilities.debugprintln("ds = " + ds);
      con = ds.getconnection();
    }
    catch (exception e) {
      utilities.debugprintln("exception = " + e.getmessage());
      return null;
    }
    //utilities.debugprintln("con = " + con);
    return con;
  }

  public static java.sql.resultset excutedbquery(connection con, string sql,
    object[] parameters) {
    //exception err = null;
    //utilities.debugprintln("excutedbquery" + parameters[0] + " ,sql=" + sql);

    try {
      java.sql.preparedstatement ps = con.preparestatement(sql);
      for (int i = 0; i < parameters.length; i++) {
        processparameter(ps, i + 1, parameters[i]);
      }
      return ps.executequery();
    }
    catch (exception e) {
      //utilities.debugprintln(e.getmessage());
      e.printstacktrace();
    }
    return null;
  }

  public static void excutedbupdate(string sql, object[] parameters) {
    connection con = utilities.getdatabaseconnection();
    excutedbupdate(con, sql, parameters);
    closedbconnection(con);
  }

  public static void excutedbupdate(connection con, string sql,
                   object[] parameters) {
    exception err = null;
    try {
      java.sql.preparedstatement ps = con.preparestatement(sql);
      for (int i = 0; i < parameters.length; i++) {
        processparameter(ps, i + 1, parameters[i]);
      }
      ps.execute();
    }
    catch (exception e) {
      err = e;
      //utilities.debugprintln(err.getmessage());
      e.printstacktrace();
    }
  }

  private static void processparameter(java.sql.preparedstatement ps,
                     int index, object parameter) {
    try {
      if (parameter instanceof string) {
        ps.setstring(index, (string) parameter);
      }
      else {
        ps.setobject(index, parameter);
      }
    }
    catch (exception e) {
      //utilities.debugprintln(e.getmessage());
      e.printstacktrace();
    }
  }

  public static void closedbconnection(java.sql.connection con) {
    try {
      con.close();
    }
    catch (exception e) {
      utilities.debugprintln(e.getmessage());
    }
  }

  public static string getresultpage(
    string title, string message, string jumplink,
    velocityservlet servlet, httpservletrequest request,
    httpservletresponse response, context context) {

    template template = null;

    context.put("messagetitle", title);
    context.put("resultmessage", message);
    context.put("jumplink", jumplink);

    try {
      template = servlet.gettemplate(
        "/templates/message.htm");
      stringwriter sw = new stringwriter();
      template.merge(context, sw);
      return sw.tostring();
    }
    catch (exception ex) {
      return "error get template message.htm " + ex.getmessage();
    }

  }

  public static string mergetemplate(string filename, velocityservlet servlet,
                    context context) {
    template template = null;

    try {
      template = servlet.gettemplate(filename);
      stringwriter sw = new stringwriter();
      template.merge(context, sw);
      return sw.tostring();
    }
    catch (exception ex) {
      return "error get template " + filename + " " + ex.getmessage();
    }
  }

}

  
     

 

注意:基于排版的需要,代码中使用了中文全角空格。如果要复制代码,请在复制后进行文字替换。

 

扫描关注微信公众号