分享
 
 
 

Velocity实例

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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();

}

}

}

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有