1.0          其他语言
 
 

3.2 控制器 Controller

 
 

org.velocityweb.controller.Controller 是一个纯 Java 类。使用 VelocityWeb 的应用程序应该写一个 Controller 类的子类。在 VelocityWeb 中有另一个类是 org.velocityweb.controller.Controller 的子类,类名叫 org.velocityweb.controller.impl.SimpleController。新的应用程序应该写一个新类,比如,PetStoreController,让它成为 SimpleController 或者 Controller 的子类。一般地,新的控制器应该覆盖以下函数:

protected Object getDataSource()
public boolean initApplication()
public Object getSessionUser(HttpServletRequest request)
public void setSessionUser(HttpServletRequest request, Object user)
public boolean hasAccessRight(LeafDispatcher leafDispatcher, HttpServletRequest request)
public boolean needLogin(LeafDispatcher leafDispatcher, HttpServletRequest request)
public Template getTemplate(String fileName, String templateHtmlCharsetName)
public void destroyApplication()

在 VPetstore 中有一个现成的例子,PetStoreController 使用 JNDI 来查找数据源,这也是 Web 应用程序正常运行的工作方式:

 
    public class PetStoreController extends SimpleController {
        protected Object getDataSource() {
                //some J2EE container need jndi name begin with "java:comp", others not
                Object dataSource = getDataSource("java:comp/env/jdbc/vpetstore");
                if (dataSource == null) {
                        dataSource = getDataSource("jdbc/vpetstore");
                }
                log.debug(dataSource);
                log.debug(dataSource.getClass());
                return dataSource;
        }

        ...

         public Object getSessionUser(HttpServletRequest request) {
                  HttpSession session = request.getSession(false);
                  if (session == null) {
                           return null;
                  }
                  Object user = session.getAttribute(USER_KEY_IN_SESSION);
                  return user;
         }

        public void setSessionUser(HttpServletRequest request, Object user) {
                  HttpSession session = request.getSession(true);
                  session.setAttribute(USER_KEY_IN_SESSION, user);
         }

        public boolean hasAccessRight(LeafDispatcher leafDispatcher, HttpServletRequest request) {
                  // default all user can access all pages
                  return true;
         }
        
        ...

}
 
   


对于单元测试,我们需要写一个新的控制器,覆盖函数 getDataSource()。比如,我们可以使用 Apache DBCP 来提供数据源:

 
    public class TestPetStoreController extends PetStoreController {
        private Log log = LogFactory.getLog(this.getClass());

        protected Object getDataSource() {
                log.debug("getDataSourceByDBCP");
                BasicDataSource dataSource = new BasicDataSource();
                dataSource.setUrl("jdbc:postgresql:jpetstore");
                dataSource.setDriverClassName("org.postgresql.Driver");
                dataSource.setUsername("postgres");
                dataSource.setPassword("postgres");
                return dataSource;
        }
}
 
   


函数 getDataSource() 是 protected,是为了防止 DAO 类之外的代码调用它。我们将这个 Datasource 对象放入到 AppContext 对象中,然后会从 web 层的分发器 dispatcher 传到 DAO 层中。