- spring mvc
我們用struts2時采用的傳統的配置文件的方式,並沒有使用傳說中的0配置。spring3 mvc可以認為已經100%零配置了(除了配置spring mvc-servlet.xml外)。
Spring MVC和Struts2的區別:
1. 機制:spring mvc的入口是servlet,而struts2是filter(這里要指出,filter和servlet是不同的。以前認為filter是servlet的一種特殊),這樣就導致了二者的機制不同,這里就牽涉到servlet和filter的區別了。
2. 性能:spring會稍微比struts快。spring mvc是基於方法的設計,而sturts是基於類,每次發一次請求都會實例一個action,每個action都會被注入屬性,而spring基於方法,粒度更細,但要小心把握像在servlet控制數據一樣。spring3 mvc是方法級別的攔截,攔截到方法后根據參數上的注解,把request數據注入進去,在spring3 mvc中,一個方法對應一個request上下文。而struts2框架是類級別的攔截,每次來了請求就創建一個Action,然后調用setter getter方法把request中的數據注入;struts2實際上是通過setter getter方法與request打交道的;struts2中,一個Action對象對應一個request上下文。
3. 參數傳遞:struts是在接受參數的時候,可以用屬性來接受參數,這就說明參數是讓多個方法共享的。
4. 設計思想上:struts更加符合oop的編程思想, spring就比較謹慎,在servlet上擴展。
5. intercepter的實現機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現restful url。struts2是類級別的攔截,一個類對應一個request上下文;實現restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共享,這也就無法用注解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼,讀程序時帶來麻煩。
6. 另外,spring3 mvc的驗證也是一個亮點,支持JSR303,處理ajax的請求更是方便,只需一個注解@ResponseBody ,然后直接返回響應文本即可。
等等。。。。。。
- velocity模板
對 Java 程序員來說,最優秀的模版引擎無外乎 Velocity 和 FreeMarker 了。但是對一個尚未接觸過這兩個項目的人來說,就不知道該選擇哪個,哪個才是最適合自己的。下面的內容來自 FreeMarker 網站上一個比較中肯的比較,盡管更多的是傾向於 FreeMarker :
相比較 FreeMarker 而言,Velocity 更加簡單、輕量級,但它的功能卻沒有 FreeMarker 那么強大。
對於大部分的應用來說,使用 FreeMarker 比 Velocity 更簡單,因為 Velocity 還必須編寫一些自定義的toolbox類以及一遍遍重復的編寫一些比較通用的模版代碼,因此也就喪失了剛開始開發時更多的寶貴時間。另外使用工具類和變通的方法在模版引擎中似乎不是一個非常有效的做法。同時,Velocity 的做法使得在Velocity的模版中大量的跟 Java 對象進行交互,這違反了簡單的原則,盡管你也可以將代碼轉入控制器中實現。當然,如果你像使用 Velocity 一樣來使用 FreeMarker ,那么 FreeMarker 也可以跟 Velocity 一樣簡單。
等等。。。。。。
詳細請看 這個也不是介紹的重點。
所需要包文件
- spring mvc 只是用到mvc所以只需要那8個包;
- velocity 用到2個包。
- web.xml
<servlet> <servlet-name>mvc3</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/main-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc3</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
- main-servlet.xml
<!-- velocity模板配置 --> <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> <property name="resourceLoaderPath" value="WEB-INF/velocity/" /> <property name="velocityProperties"> <props> <prop key="input.encoding">UTF-8</prop><!-- 指定模板引擎進行模板處理的編碼 --> <prop key="output.encoding">UTF-8</prop><!-- 指定輸出流的編碼 --> <prop key="contentType">text/html;charset=UTF-8</prop><!-- contentType --> <prop key="userdirective">com.tonyplan.web.velocity.CacheDirective</prop> <!--自定義標簽 --> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"> <property name="cache" value="false"></property><!--是否緩存模板--> <property name="order" value="10" /> <property name="suffix" value=".vm"/> <property name="prefix" value="/screen/" /> <property name="layoutUrl" value="layout/default.vm" /> <property name="exposeSpringMacroHelpers" value="true" /> <property name="dateToolAttribute" value="dateTool"/> <property name="numberToolAttribute" value="numberTool"/> <property name="toolboxConfigLocation" value="WEB-INF/velocity-tools.xml" /> <property name="contentType" value="text/html;charset=UTF-8"></property> </bean>
- 自定義標簽 :com.tonyplan.web.velocity.CacheDirective
package com.tonyplan.web.velocity; import java.io.IOException; import java.io.Serializable; import java.io.StringWriter; import java.io.Writer; import java.util.Hashtable; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.util.StringUtils; import com.tonyplan.cache.CacheManager; public class CacheDirective extends Directive { final static Hashtable<String,String> body_tpls = new Hashtable<String, String>(); @Override public String getName() { return "cache"; } @Override public int getType() { return BLOCK; } @Override public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { //獲得緩存信息 Node body = node.jjtGetChild(2); StringWriter sw = new StringWriter(); body.render(context, sw); writer.write(sw.toString()); return true; //獲得緩存信息 /*SimpleNode sn_region = (SimpleNode) node.jjtGetChild(0); String region = (String)sn_region.value(context); SimpleNode sn_key = (SimpleNode) node.jjtGetChild(1); Serializable key = (Serializable)sn_key.value(context); Node body = node.jjtGetChild(2);*/ //檢查內容是否有變化 /*String tpl_key = key+"@"+region; String body_tpl = body.literal(); String old_body_tpl = body_tpls.get(tpl_key); String cache_html = null;//= CacheManager.get(String.class, region, key); if(cache_html == null || !StringUtils.equals(body_tpl, old_body_tpl)){ StringWriter sw = new StringWriter(); body.render(context, sw); cache_html = sw.toString(); CacheHelper.set(region, key, cache_html); body_tpls.put(tpl_key, body_tpl); } writer.write(cache_html); return true;*/ } }
- velocity-tools.xml
<?xml version="1.0" encoding="UTF-8"?> <toolbox> <tool> <key>newstool</key> <class>com.tonyplan.web.velocity.NewsTool</class> </tool> </toolbox>
- com.tonyplan.web.velocity.NewsTool
package com.tonyplan.web.velocity; import java.util.List; import com.tonyplan.beans.CourseBean; import com.tonyplan.dao.CourseDao; public class NewsTool { public List<CourseBean> ListTopNews(int top){ return CourseDao.getInstance().getList(1, top); } /** To test exception handling in templates. */ public boolean whine() { throw new IllegalArgumentException(); } }
- velocity 宏定義 macro
#macro (writeTable $productList) #set ($rowCount = 1) #foreach($product in $productList) #if ($rowCount % 2 == 0) #set ($bgcolor = "#FFFFFF") #else #set ($bgcolor = "#CCCCCC") #end <tr> <td bgcolor="$bgcolor">$product</td> <td bgcolor="$bgcolor">$product</td> </tr> #set ($rowCount = $rowCount + 1) #end #end
- layout.vm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <HEAD> <TITLE>$!page_title 測試layout頁面</TITLE> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Language" content="zh-CN"/> <META NAME="Generator" CONTENT="EditPlus"> <META NAME="Author" CONTENT=""> <META NAME="Keywords" CONTENT=""> <META NAME="Description" CONTENT=""> $script </HEAD> <BODY> ------------------------------------ <br> $screen_content </BODY> </HTML>
- pageFooter.vm
Copyright © 2012
- pageFooter1.vm
#set ($innerVar = "This is an inner variable") Copyright © $companyName 2012
- index.vm
#set($layout="layout/layout.vm") #set($page_title="測試首頁") #set($products = ["one", "two", "three"]) #set($companyName = "Tony Law") #parse("macro/writeTable.vm") #define($script) ## custom script here <script src="script/jquery.js" type="text/javascript"></script> #end Here we use a custom tool: $toytool.message <div> <ul> #foreach($CourseBean in $newstool.ListTopNews(10)) <li> ${CourseBean.name} </li> #end </ul> </div> #set($region = "news") #set($key = "home") #cache("CACHE_$region",$key) #end <div> #cache("News","home") ## 讀取數據庫中最新新聞並顯示 <ul> #foreach($CourseBean in $newstool.ListTopNews(10)) <li> ${CourseBean.name} </li> #end </ul> #end </div> <table> #writeTable($products) </table> <br> #parse("layout/pageFooter1.vm") <br> $innerVar <br> #include("layout/pageFooter.vm")
以上說明
- $layout 變量默認配置是<property name="layoutUrl" value="layout/default.vm" />;改變布局模板#set($layout="layout/layout.vm")
- #parse 加入動態vm
- #include 加入靜態vm
- #cache自定義標簽,配置<prop key="userdirective">com.tonyplan.web.velocity.CacheDirective</prop> <!--自定義標簽 -->
- #set設置變量
- #define
等等。。。。。。
更多參考velocity 文檔!