`
xiaoyaocao
  • 浏览: 274333 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

也谈 SpringMVC多视图配置

阅读更多

最近在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发动起来,看一下效果吧。

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics