最近在springmvc上集成velocity,磕磕绊绊,总算是有所收获,在此记录一下。
Velocity是一种易用的模板语言。Velocity将Java代码从Web 页面中分离出来,使用Web站点从长远看更容易维护,并且提供了一种可行的JavaServer Pages替代解决方案。除了JSP,Velocity可能是用于Web应用的最流行的模板语言之一。很多web系统也都采用Velocity作为视图层技术,Spring对Velocity作为视图模板语言提供了很好的支持。
怎么配置,来,一步步走:
1、首先,在Web.xml进行配置,DispatcherServlet配置的映射为所有请求类型,这样以后如果要集成其他如Freemaker等只需要加入其配置就可以了。
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
2、配置spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.per.action"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<!-- 定义JSP视图解析器-->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
<property name="contentType" value="text/html;charset=UTF-8" />
</bean>
<!-- velocity视图解析器 -->
<!-- velocity环境配置 -->
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<!-- velocity配置文件路径 -->
<property name="configLocation" value="classpath:velocity.properties"/>
<!-- velocity模板路径 -->
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>
<bean id="velocityViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="false"/>
<property name="prefix" value=""/>
<property name="suffix" value=".vm"/>
<property name="contentType" value="text/html;charset=UTF-8" />
<!-- 多ViewResovler配置 -->
<property name="order" value="1" />
</bean>
</beans>
注意,“order”属性是必须加的,为什么呢,可以查看我前一篇内容
SpringMVC ViewResolver查找序列
velocity.properties配置文件,位置要与spring-mvc.xml中配置的一样。
#encoding input.encoding=UTF-8 output.encoding=UTF-8 contentType=text/html;charset=UTF-8 #autoreload when vm changed file.resource.loader.cache=false file.resource.loader.modificationCheckInterval=1 velocimacro.library.autoreload=true runtime.log=velocity.log #runtime.log.logsystem.class=org.springframework.ui.velocity.CommonsLoggingLogSystem runtime.log.logsystem.class=org.apache.velocity.runtime.log.NullLogSystem #runtime.log.logsystem.class=org.springframework.ui.velocity.NullLogSystem runtime.log.error.stacktrace=false runtime.log.warn.stacktrace=false runtime.log.info.stacktrace=false runtime.log.invalid.reference=false
当然这里面的jspViewResover和velocityViewResover是可以单独运行的,合并也是可以运行的,不过我集成时,运行一个JSP,页面是正常的,但日志总是会提示“[Error]Resource Not Found :xxxx.vm”,查了资料都说这个可以ignore,可是怎么设置呢,这个很头疼,试着去掉velocity.jar包中日志配置也不行,可日志不能老让报error啊,求解!
当然还有方法,就是打开ResourceBundleViewResover这个配置,设置view.properties,在里面加入视图的路径配置,这样就不会报异常了,也是可以正常运行的。可是新的问题来了,一个是页面会有乱码,到我写这篇文字的时候也没能解决,高人指点下啊;另外一个是你的controller的每个view路径都要在view.properties中配置,这也比较麻烦,毕竟一个项目那么多view呢。
修改后,加入ResourceBundleViewResover配置:
<!-- ResourceBundleViewResolver用于多个视图集成,是通过解析资源文件来解析请求输出文件的。 <property name="basename"
value="views"></property>,即表示在/WEB-INF/classes路径下有一个 views.properties文件 -->
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="order" value="0" />
</bean>
<!-- 定义JSP视图解析器-->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
<property name="contentType" value="text/html;charset=UTF-8" />
</bean>
<!-- velocity视图解析器 -->
<!-- velocity环境配置 -->
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<!-- velocity配置文件路径 -->
<property name="configLocation" value="classpath:velocity.properties"/>
<!-- velocity模板路径 -->
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>
<bean id="velocityViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="false"/>
<property name="prefix" value=""/>
<property name="suffix" value=".vm"/>
<property name="contentType" value="text/html;charset=UTF-8" />
<!-- 多ViewResovler配置
<property name="order" value="1" /> -->
</bean>
view.properties配置文件
#welcome为modelAndView.setViewName("welcome");中的welcome .(class)固定写法
welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
#welcome.url 路径 welcome.vm模板名称
welcome.url=welcome.vm
#IndexController路径
velocity_main.(class)=org.springframework.web.servlet.view.velocity.VelocityView
velocity_main.url=velocity_main.vm
无奈,看来,只有自己写个ViewResover来处理多视图了,google了一下,还真有人也是这么做的,看来不只是我一个人这么想啊,手懒了些,直接抄了http://blog.youkuaiyun.com/rommel1/article/details/7673325的代码,好了,来看看配置吧:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<context:component-scan
base-package="com.spring.action"/>
<!--
org.springframework.web.servlet.view.ResourceBundleViewResolver
用于多个视图集成时,ResourceBundleViewResolver是通过解析资源文件来解析请求输出文件的。
<property name="basename" value="views"></property>,即表示在/WEB-INF/classes路径下有一个
views.properties文件,本例中views.properties的内容为
welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
welcome.url=welcome.vm
freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
freemarker.url=freemarker.ftl
-->
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views">
</property>
<!--
<property name="order" value="0"></property>
-->
</bean>
<!-- FreeMarker环境配置 -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- freemarker模板位置 -->
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
</bean>
<!-- velocity环境配置 -->
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<!-- velocity配置文件路径 -->
<property name="configLocation" value="/WEB-INF/velocity.properties"/>
<!-- velocity模板路径 -->
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>
<bean id="viewResolver"
class="com.spring.action.MultiViewResover">
<property name="resolvers">
<map>
<entry key="jsp">
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</entry>
<entry key="ftl">
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".ftl"/>
</bean>
</entry>
<entry key="vm">
<bean
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".vm"/>
</bean>
</entry>
</map>
</property>
</bean>
</beans>
MultiViewResover代码,这里我默认的是使用jsp视图解析,如果你没有默认的可以去掉
public class MultiViewResover implements ViewResolver {
private Map<String, ViewResolver> resolvers;
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
int n = viewName.lastIndexOf("."); // 获取
// viewName(modelAndView中的名字)看其有没有下划线
String suffix = "";
// 没有默认使用“jsp“方式 解析,有的话截取下划线后面的字符串 这里一般是jsp,ftl,vm与配置文件中的<entry
// key="ftl">的key匹配
if (n == (-1)) {
suffix = "jsp";
}
else {
suffix = viewName.substring(n + 1);
// 取下划线前面的部分 那时真正的资源名.比如我们要使用hello.jsp 那viewName就应该是hello_jsp
viewName = viewName.substring(0, n);
}
// 根据下划线后面的字符串去获取托管的视图解析类对象
ViewResolver resolver = resolvers.get(suffix);
if (resolver != null) {
return resolver.resolveViewName(viewName, locale);
}
else {
return null;
}
}
public Map<String, ViewResolver> getResolvers() {
return resolvers;
}
public void setResolvers(Map<String, ViewResolver> resolvers) {
this.resolvers = resolvers;
}
}
好了,第二步这个配置总算完成了,真累 啊,继续看下面。
3、编写controller代码,注意,你的view名字中,要加上".vm",".jsp",".ftl"这些后缀哦,要不默认都使用jsp的解析器了
@Controller
public class IndexController{
@RequestMapping(value="/index")
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("velocity_main.vm");
Person p1 = new Person();
p1.setId(1);
p1.setName("胡楠");
p1.setPassword("123456");
p1.setAge(24);
p1.setBirthday(new Date());
List<Person> list = new ArrayList<Person>();
for(int i=0;i<10;i++){
Person p = new Person();
p.setId(1000+i);
p.setName("胡楠"+i);
p.setPassword("123456"+i);
p.setAge(24+i);
p.setBirthday(new Date());
list.add(p);
}
//集合
mav.addObject("persons", list);
//对象
mav.addObject("person",p1);
//request范围数据
request.setAttribute("requestData", "hunan");
//session范围数据
request.getSession().setAttribute("sessionData", "123456");
return mav;
}
@RequestMapping(value="/welcome")
public ModelAndView helloVm(){
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("welcome.vm");
modelAndView.addObject("message", "Hello,Velocity");
return modelAndView;
}
}
4、编写velocity模板代码,以下是velocity_main.vm代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
显示对象的属性<br>
$person.id<br>
$person.name<br>
$person.password<br>
$person.age<br>
if语句<br>
#if($person.id <2)
id大于2
#else
id小于2
#end
#if($person.password=="123456")
密码等于123456
#end
<hr>
foreach语句<br>
#foreach($p in $persons)
$p.id<br>
$p.name<br>
$!p.email<br>
$dateTool.format("yyyy-MM-dd HH:mm:ss", $p.birthday)<br>
#end
<hr>
request范围数据<br>
$requestData<br>
session范围数据<br>
$sessionData<br>
</body>
</html>
呼~~写完了终于,把tomcat发动起来,看一下效果吧。
本文详细介绍了如何在SpringMVC框架中集成Velocity模板引擎,包括Web.xml和spring-mvc.xml的配置步骤,以及如何编写Controller代码和Velocity模板。
147

被折叠的 条评论
为什么被折叠?



