关于VelocityServlet应用时velocity.properties作为通用属性文件

来源:互联网 发布:管理快递的软件 编辑:程序博客网 时间:2024/05/16 10:09

在文章 VelocityServlet的应用 中的那个例子,只把所有的关于Velocity的velocity.properties属性文件的加载,以及日志设置都放在了一个自己实现的VelocityServlet的子类中。

在实际应用中,关注的是获取到一个所需要的模板,来显示需要显示的数据。这样,如果把velocity.properties属性文件都放在一个自己实现的VelocityServlet的子类中,那样造成了重复编码的问题,每当实现一个VelocityServlet的子类时,都要硬编码解析一次属性文件,这是程序员最不想做的。

因为VelocityServlet自带的velocity.properties属性文件一般都不能满足实际的需要,其实,可以在重写默认的velocity.properties属性文件的基础上,在一个应用中,再抽象出一层,让该通用的velocity servlet实现VelocityServlet类,假设GenericVelocityServlet继承了VelocityServlet,在GenericVelocityServlet中实现的就是解析velocity.properties属性文件,以及日志的设置等,这些操作是每个具体的子类velocity servlet都能够使用的。

在我们抽象出来的GenericVelocityServlet的基础上,进行扩展,这时,只需要让每个实际的velocity servlet继承GenericVelocityServlet即可,而且,只需要在其中重写handleRequest方法,获取指定的Velocity模板,显示实际需要显示的数据。

GenericVelocityServlet的实现可以按照如下所示去实现:

package org.shirdrn.velocity.generic;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletConfig;

import org.apache.velocity.app.Velocity;
import org.apache.velocity.servlet.VelocityServlet;

public class GenericVelocityServlet extends VelocityServlet {
protected Properties loadConfiguration(ServletConfig config)throws IOException, FileNotFoundException{
   String propsFileName = config.getInitParameter(INIT_PROPS_KEY);
   Properties props = new Properties();
   if(propsFileName != null){
    String realPath = getServletContext().getRealPath(propsFileName);
    if(realPath != null){
     propsFileName = realPath;
    }
    props.load(new FileInputStream(propsFileName));
   }

   String logFileName = props.getProperty(Velocity.RUNTIME_LOG);
   if(logFileName != null){
    String log = getServletContext().getRealPath(logFileName);
    if(log != null){
     props.setProperty(Velocity.RUNTIME_LOG,log);
    }
   }
  
   String path = props.getProperty(Velocity.FILE_RESOURCE_LOADER_PATH);
   if(path != null){
    String realPath = getServletContext().getRealPath(path);
    if(realPath != null){
     props.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, realPath);
    }
   }
   return props;
}
}

该通用的GenericVelocityServlet实现的就是velocity.properties属性文件的解析,以及设置日志,将当前的可能使用到的Velocity模板全部放到Velocity上下文(Context)中,在子类继承GenericVelocityServlet的时候,只要从已经设置好的Velocity上下文中获取到(getTemplate())相应的Velocity模板即可。也就是说,每个GenericVelocityServlet的主要功能就是处理模板的选择,设置上下文数据列表,可能还有其它的一些功能,但是最好让每个GenericVelocityServlet的子类的功能尽量单一,便于维护。

例如,拿文章 VelocityServlet的应用 中的那个例子,是要显示Person的数据列表,只需要让ListPersonsServlet继承GenericVelocityServlet即可,如下所示:

package org.shirdrn.velocity.servlet;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

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

import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.shirdrn.velocity.dao.PersonDao;
import org.shirdrn.velocity.generic.GenericVelocityServlet;
import org.shirdrn.velocity.service.PersonService;

public class ListPersonsServlet extends GenericVelocityServlet {

public Template handleRequest(HttpServletRequest request,HttpServletResponse response,Context ctx){
   PersonDao personDao = new PersonService();
   List personList = personDao.queryPersons("from Person");
   ctx.put("personList", personList);
   Template template = null;
   try {
    template = getTemplate("lists.vm","UTF-8");
   } catch (ResourceNotFoundException e) {
    e.printStackTrace();
   } catch (ParseErrorException e) {
    e.printStackTrace();
   } catch (Exception e) {
    e.printStackTrace();
   }
   return template;
}
}

这样,同样能够实现。而且,如果该应用中有另一个需求,要显示一个人的博客的文章列表,同样可以轻松地实现一个velocity servlet,让其继承GenericVelocityServlet即可,设置文章列表到Velocity上下文中,之后选择指定的视图模板。

原创粉丝点击