最近在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的DispatcherServlet分析 在本篇文章中,我们将对SpringMVC的DispatcherServlet进行深入分析,并了解其在Web应用程序中的作用。 一、DispatcherServlet的配置 在SpringMVC中,DispatcherServlet是...
总的来说,SpringMVC通过`@RequestMapping`、`@PathVariable`等注解和`DispatcherServlet`的配置,有效地支持了RESTful风格的API开发。同时,通过`<mvc:resources>`配置,可以确保静态资源的正常访问,从而在实现...
浅谈SpringMVC中Interceptor和Filter区别 SpringMVC中Interceptor和Filter是两个重要的概念,它们都是用来处理用户请求的,但它们有着不同的作用和实现机制。本文将详细介绍Interceptor和Filter的区别,帮助读者更...
视图解析器根据视图名和配置来找到具体的视图模板,如JSP、FreeMarker等。 7. **视图渲染**:最后,视图渲染模型数据并呈现给用户。视图会使用模型中的数据来填充模板,生成最终的HTML响应,然后将其发送回客户端。...
SpringMVC的工作流程包括:请求到达前端控制器DispatcherServlet,它根据配置的映射规则转发到相应的处理器,处理器执行业务逻辑后返回Model,最后由视图解析器渲染视图并展示给用户。 MyBatis是一个优秀的持久层...
SpringMVC是Java领域中广泛使用的Web开发框架,它为开发者提供了强大的功能,包括模型-视图-控制器(MVC)架构、依赖注入以及丰富的注解支持。当我们谈到“注解式权限验证”,我们指的是通过在控制器方法上添加特定...
3. **配置SpringMVC**:在`spring-servlet.xml`中,我们需要定义HandlerMapping、ViewResolver、以及自定义的处理器和拦截器等,来指定SpringMVC如何处理请求和呈现视图。 4. **配置Hibernate**:创建Hibernate的...
17. 内容协商视图控制器:讲解了如何配置内容协商视图控制器。 18. 自动化部署和其他维护工作:概述了自动化部署的相关任务和其他维护工作。 文档翻译过程中遇到的翻译问题、取舍及最终解决方案被记录在翻译注记中...
在`web.xml`中,我们配置了一个`DispatcherServlet`,这个Servlet是Spring MVC的核心,它有自己的ApplicationContext,也就是子容器。`DispatcherServlet`的`init-param`配置项指定了Spring MVC的配置文件路径。当`...
3. `afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)`: 在整个请求完成,包括视图渲染后调用,用于清理资源或进行其他收尾工作。 ```java public class...
- **ViewResolver**:视图解析器,根据返回的逻辑视图名解析成实际视图。 ### 2. 创建 Spring MVC 项目 本例中的 `WebDemo1` 应该包含以下结构: - **src/main/java**:存放 Java 类,如 Controller、Service 和 ...
Tomcat作为最常用的Java Web服务器,其性能优化和运行机制也是面试常谈: 1. **Tomcat架构**:介绍Catalina、 Coyote、Jasper等核心组件的功能。 2. **部署与启动**:如何配置server.xml,以及调整线程池参数以...