最近在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.csdn.net/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 多视图配置(Jsp Freemarket Json)实例
SpringMVC自定义多视图,多视图实现
springMVC配置好的环境
SpringMVC及视图解析器
配置多数据源、SpringMVC框架下多数据源的配置问题、如何在同一个项目中使用多个数据库、如果在同一个项目中使用不同的数据库。
SpringMVC两种配置的Demo
主要包含springmvc的基本配置内容,及spring定时任务quartz的配置与动态修改。
SpringMVC 使用JSON、XML视图,json-lib jackson,xstream castor,jibx jaxb2
本篇文章主要介绍了浅谈SpringMVC之视图解析器(ViewResolver),具有一定的参考价值,有兴趣的可以了解一下
springmvc+mybaits配置示例
SSM笔记-SpringMVC自定义视图及重定向视图、语言国际化
springmvc 3.1 多视图,freemarker jsp
通过注解配置完全代替web.xml、Spring的xml文件配置,jquery递归遍历后台返回的json对象并进行拼接
springMVC整合ibatis,springMVC采用注解方式,配置详细
IDEA用maven创建springMVC项目和配置(XML配置和Java配置)
SSM(Spring+SpringMVC+MyBatis)多数据源配置框架,精简版
SpringMVC配置文件 SpringMVC配置文件 SpringMVC配置文件
springMVC最简单的配置,springMVC最简单的配置,springMVC最简单的配置
Spring MVC 全注解配置,吾运行环境:server tomcat8,elcipse,jdk1.8. 注:任何服务器必须是servlet是3.0以上的,否则不能运行,当然也有解决办法,自己百度吧
springmvc + hibernate annotation 配置