心随风动

就像被PS过的照片,浮在表面的漂亮而已。
« 温州软件,路在何方 ――温州软件行业内幕... | 主页 | 用Java实现PDF报表 - 无色叶子... »
星期二 七月 01, 2008

Spring Velocity Integration

 


How I integrate Velocity template engine into the Spring Framework.

Spring Framework & Apache Velocity

I use Velocity a lot in my projects as I dont need over-engineered JSPs in my simple templates.
I use the View Layout tools to simplefy even further.


And by editing a couple of xml files, spring uses its full potential.


These libraries need to be included:



  • spring-1.2.3.jar

  • velocity-1.4.jar

  • velocity-tools-1.1.jar

  • velocity-tools-generic-1.1.jar

  • velocity-tools-view-1.1.jar


and their dependencies e.g.



  • velocity-dep-1.4.jar


And my own



but more about that later.


First here is sections of my web.xml. Some bits are just standard spring mvc setup.


<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>
 
<listener>
 <description>ServletContextListener</description>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener> 
  
<servlet>
 <servlet-name>spring</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/spring/spring-servlet.xml</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
</servlet> 


<servlet-mapping>
 <servlet-name>spring</servlet-name>
 <url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
 <servlet-name>spring</servlet-name>
 <url-pattern>*.do</url-pattern>
</servlet-mapping> 


<!-- 
 These two mappings is a fudge due to silly web-app specs.
 It avoids having jsp forward to html files
-->
<servlet-mapping>
 <servlet-name>spring</servlet-name>
 <url-pattern>/index.html</url-pattern>
</servlet-mapping> 
<servlet-mapping>
 <servlet-name>spring</servlet-name>
 <url-pattern>/contact/index.html</url-pattern>
</servlet-mapping> 


<welcome-file-list>
 <welcome-file>index.html</welcome-file>
</welcome-file-list>


<!-- My own error pages, not a requirement --> 
<error-page>
 <error-code>404</error-code>
 <location>/missing.html</location>
</error-page>
 
<error-page>
 <error-code>403</error-code>
 <location>/access.html</location>
</error-page>
 
<error-page>
 <error-code>500</error-code>
 <location>/error.html</location>
</error-page> 


And here is my spring-servlet.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> 
 
 <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> 
  <property name="resourceLoaderPath" value="/"/>
  <property name="configLocation" value="/WEB-INF/velocity/velocity.properties"/>
 </bean>
 
 <bean id="viewResolvers" class="com.flurdy.grid.mvc.view.VelocityLayoutViewResolver">
  <property name="layoutUrl" value="WEB-INF/templates/layout/grid.vm"/> 
  <property name="toolboxConfigLocation" value="/WEB-INF/velocity/toolbox.xml"/>
  <property name="prefix" value="/WEB-INF/templates/"/>
  <property name="suffix" value=".vm"/>
  <property name="exposeSpringMacroHelpers" value="true"/>
 </bean>
 
 <bean id="internalResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver">
  <property name="suffix" value="Handler"/>
 </bean>
   
 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basenames">
   <list>
    <value>text</value>
   </list>
  </property>
 </bean> 
 
 <bean id="handler" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/**/*.html">viewController</prop>
    <prop key="/**/*.do">viewController</prop>
   </props>
  </property>
 </bean> 
 
 <bean id="viewController" class="org.springframework.web.servlet.mvc.multiaction.MultiActionController">
  <property name="methodNameResolver" ref="internalResolver"/>
  <property name="delegate" ref="viewDelegate"/>
 </bean>
 <bean id="viewDelegate" class="some.package.ViewDelegate">  
 <!-- <property name="someinjection" ref="someotherbean"/> -->
 </bean>


</beans>
 


As you see the viewResolvers bean uses my own VelocityLayoutViewResolver. This is due to my set up uses the VelocityLayoutView tools. And spring does not include a resolver for it in its 1.x version. It is however included in the lastest versions. More details here.


Next thing is to create a grid.vm layout template referenced in the viewResolvers bean. I tend to use a specific css based layout, but that will be detailed in another doc sometime.


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>
  #springMessage("title";)
 </title>  
 <link rel="shortcut icon" href="$request.contextPath/favicon.ico" />
 <link type="text/css" rev="StyleSheet" rel="StyleSheet" href="http://flurdy.com/style/grid.css" />
 <link type="text/css" rev="StyleSheet" rel="StyleSheet" href="http://flurdy.com/style/ship.css" />
 <link type="text/css" rev="StyleSheet" rel="StyleSheet" href="http://flurdy.com/style/cargo.css" />
</head>
<body>
 <div id="ship">
  <div id="stern" class="grid head">
   <span>
    #springMessage("titlelong";)
   </span>
  </div>
  <div id="port" class="grid side column">
   <ul id="menu">
    <li><a href="$request.contextPath/index.html">Home</a></li>
   ## <li><a href="$request.contextPath/contact/">Contact</a></li>
   </ul>
  </div>
  <div id="starboard" class="grid side column">
  </div>  
  <div id="outerhull" class="">
   <div id="innerhull" class="grid column middle">
    <div id="cargo" class="">
     / <a href="$request.contextPath/">home</a>
$screen_content


    </div>
   </div>
  </div>
  <div id="aft" class="grid foot">
  </div>
 </div>
</body>
</html> 


What is of interest is the two #springMessage lines and the $screen_content. The springmessages prints out text from your resource bundles, ie the messageResource in the spring-servlet.xml.


The $screen_content is where your view templates will be inserted. More details here.


Final thing is to include the handler delegate. Here is quick example.


package some.package;


import java.util.*;
import javax.servlet.http.*;
import org.springframework.web.servlet.ModelAndView;
import org.apache.commons.logging.*;
//import org.apache.commons.collections.*;
//import ent.orm.*;
//import mng.face.*;
//import dao.face.*;
//import logic.face.*;


public class ViewDelegate {   
 
 private final Log log = LogFactory.getLog(getClass());
 
 public ModelAndView unspecified(
   HttpServletRequest req,HttpServletResponse resp ) {
  log.info("unspecified";);
  return indexHandler(req,resp);
 }
 
 public ModelAndView indexHandler(
   HttpServletRequest req,HttpServletResponse resp ) {
  Map model = new HashMap();
  return new ModelAndView("front",model);
 }
 
 public ModelAndView missingHandler(
   HttpServletRequest req,HttpServletResponse resp ) {
  log.warn("Page is missing:";);
  return new ModelAndView("core/missing";);
 }
 
 public ModelAndView accessHandler(
   HttpServletRequest req,HttpServletResponse resp ) {
  log.warn("No access";);
  return new ModelAndView("core/access";);
 }
 
 public ModelAndView errorHandler(
   HttpServletRequest req,HttpServletResponse resp ) {
  return new ModelAndView("core/error";);
 }



You will need to create some templates, e.g. front.vm. Which need to go into WEB-INF/templates.


Contact me if there is sections missing or if you have any questions.


Spring Velocity Integration

评论:

发表一条评论:


日历


订阅

搜索

书签

导航

访问