也談 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發動起來,看一下效果吧。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章