CMS 源碼解讀

CMS 是」Content Management System」 的縮寫,意爲」 內容管理系統」。 內容管理系統是企業信息化建設和電子政務的新寵,也是一個相對較新的市場。對於內容管理,業界尚未一個統一的定義,不一樣的機構有不一樣的理解。

· 基於 java 技術開發,繼承其強大、穩定、安全、高效、跨平臺等多方面的優勢
· 採用 SpringMVC3+Spring3+Hibernate3+Freemarker 主流技術架構
· 懂 html 就能建站,提供最便利、合理的使用方式
· 強大、靈活的標籤,用戶自定義顯示內容和顯示方式
· 在設計上自身預先作了搜索引擎優化, 加強對搜索引擎的友好性
· 徹底生成全站靜態頁面, 可自定義路徑結構,全面提升頁面訪問速度
· 輕鬆建設大規模網站,可經過次級域名創建子站羣,各子站後臺管理權限分離,全站實現單點登陸

jeeCms 源碼安裝時出現的問題及解決
裝 MySQL 數據庫裝不上
由於之前本機上裝過 MySQL, 而在卸載時有文件殘留,故 MySQL 會安裝失敗,失敗的表現有兩種:一個是安裝時未響應,一個是未彈出配置 MySQL 的界面。

解決辦法:
你能夠安裝 MySQL 的時候在這一步時它默認的服務名是 「MySQL」 只須要把這個名字改了就能夠了。
​
 卸載 MySQL
 刪除安裝目錄及數據存放目錄
 在註冊表 (regedit) 查詢 mysql,所有刪除
 在 c 盤查詢 MySQL,所有刪除
 從新安裝就行了
注意的是註冊表
cmd -> regedit,刪除如下目錄下的 MySQL 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\\Eventlog\Application\MySQL 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\Eventlog\Application\MySQL 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MySQL\www.xuanzequan.com \ 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl001t\Services\MYSQL 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl002\Services\MYSQL 目錄
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MYSQL 目錄
   刪除 C:\Documents and Settings\All Users\Application Data\MySQL 目錄

數據庫鏈接不上的問題
錯誤提示: An attempt by a client to checkout a Connection has timed out.

緣由:
 配置文件中目標數據庫的名字錯誤 (區分大小寫)
 配置文件中的目標數據庫用戶名和密碼錯誤。
 缺乏數據庫的驅動 jar 包(如 mysql-connector-5.1.8.jar 包)。缺這個包的緣由是在解瘊 MySQL 鏈接不上的問題時,會在 C 盤中查找全部 「mysql」 的文件。而你的 jeeCms 源碼包正好又放在桌面上,因而你會把全部帶 mySQL 的文件刪除,進而誤刪了源碼包中的 mySQL 鏈接包(mysql-connector-5.1.8.jar)。當你在把頁面上的源碼包放到項目中時就少了這個包,故鏈接不上。
解決辦法:刪除除 mysql 安裝殘留信息時必定要謹慎再謹慎
src 包中報錯的問題:
錯誤提示:全部帶 HttpServletRequest 或 HttpServletResponse 的類所有顯示錯誤

緣由:沒有找到 servlet 包。由於你安裝源碼包時,沒有配置 tomcat 環境。
解決辦法:
安裝源碼包時,先在 eclipse 中配置 tomcat 環境,再建動態 web 項目,而後再在 web 項目中覆蓋 src 和 webContent 文件夾。

源碼解析之一 (web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>JeeCmsV7</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            <!-- 數據庫相關配置並加載了hbm.xml文件 -->
            /WEB-INF/config/application-context.xml
            <!-- 數據緩存相關配置 -->
            /WEB-INF/config/cache-context.xml
            <!-- 驗證碼相關配置 --> 
            /WEB-INF/config/captcha-context.xml
             <!-- 圖片,密碼,文件上傳等配置 --> 
            /WEB-INF/config/jeecms/jeecore-context.xml
            <!-- spring bean相關配置,如dao層的配置、圖片處理,密碼加密 -->
            /WEB-INF/config/jeecms/jeecms-context.xml
            <!-- 配置權限管理shiro-context.xml框架 -->
            /WEB-INF/config/shiro-context.xml
            <!-- 配置其它插件文件,暫時沒有 -->
            /WEB-INF/config/plug/**/*-context.xml
            <!-- 配置定時任務 -->
            /WEB-INF/config/quartz-task.xml
        </param-value>
    </context-param>
    <!-- 打印執行時間與訪問路徑過濾器 -->
    <filter>
        <filter-name>processTime</filter-name>
        <filter-class>com.jeecms.common.web.ProcessTimeFilter</filter-class>
    </filter>
    <!-- 編碼設置 -->  
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 解決Hibernate session延遲加載的問題 --> 
    <filter>
        <filter-name>osivFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <!--@分隔-->
    <filter>
        <filter-name>XssFilter</filter-name>
        <filter-class>com.jeecms.common.web.XssFilter</filter-class>
        <init-param>
            <param-name>excludeUrls</param-name>
            <param-value>/member/contribute@/jeeadmin/jeecms@/flow_statistic</param-value>
        </init-param>
        <init-param>
            <param-name>SplitChar</param-name>
            <param-value>@</param-value>
        </init-param>
        <init-param>
            <param-name>FilterChar</param-name>
            <param-value>'@"@\@#@:@%@></param-value>
        </init-param>
        <init-param>
            <param-name>ReplaceChar</param-name>
            <param-value>‘@「@\@#@:@%@></param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>processTime</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>processTime</filter-name>
        <url-pattern>*.jspx</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.jspx</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>*.jspx</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>processTime</filter-name>
        <url-pattern>*.jhtml</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.jhtml</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>*.jhtml</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>processTime</filter-name>
        <url-pattern>*.htm</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.htm</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>*.htm</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>processTime</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
    <filter-mapping> 
       <filter-name>shiroFilter</filter-name> 
       <url-pattern>/*</url-pattern> 
     </filter-mapping>
    <filter-mapping>
        <filter-name>XssFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
            <!--  
            後臺控制  
            DispatcherServlet是前端控制器設計模式的實現,提供Spring Web MVC的集中訪問點,  
            並且負責職責的分派,並且與Spring IoC容器無縫集成,從而能夠得到Spring的全部好處  
            DispatcherServlet主要用做職責調度工做,自己主要用於控制流程,主要職責以下:  
            一、文件上傳解析,若是請求類型是multipart將經過MultipartResolver進行文件上傳解析;  
            二、經過HandlerMapping,將請求映射處處理器(返回一個HandlerExecutionChain,它包括一個處理器、多個HandlerInterceptor攔截器);  
            三、經過HandlerAdapter支持多種類型的處理器(HandlerExecutionChain中的處理器);  
            四、經過ViewResolver解析邏輯視圖名到具體視圖實現;  
            五、本地化解析;  
            六、渲染具體的視圖等;  
            七、若是執行過程當中遇到異常將交給HandlerExceptionResolver來解析。  
         --> 
    <servlet>
        <servlet-name>JeeCmsAdmin</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/config/jeecms-servlet-admin.xml
                /WEB-INF/config/plug/**/*-servlet-admin-action.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 前臺控制 --> 
    <servlet>
        <servlet-name>JeeCmsFront</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/config/jeecms-servlet-front.xml
                /WEB-INF/config/plug/**/*-servlet-front-action.xml
            </param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>Jcaptcha</servlet-name>
        <servlet-class>com.jeecms.common.captcha.JcaptchaServlet</servlet-class>
    </servlet>
    <!-- 驗證碼圖片 --> 
    <servlet-mapping>
        <servlet-name>Jcaptcha</servlet-name>
        <url-pattern>/captcha.svl</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>DbFile</servlet-name>
        <servlet-class>com.jeecms.core.action.front.DbFileServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>SnapScreen</servlet-name>
        <servlet-class>com.jeecms.core.action.front.SnapScreenServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SnapScreen</servlet-name>
        <url-pattern>/snapscreen.svl</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JeeCmsAdmin</servlet-name>
        <url-pattern>/jeeadmin/jeecms/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JeeCmsFront</servlet-name>
        <url-pattern>*.jhtml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JeeCmsFront</servlet-name>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JeeCmsFront</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JeeCmsFront</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>DbFile</servlet-name>
        <url-pattern>/dbfile.svl</url-pattern>
    </servlet-mapping>
            <!--   
            ContextLoaderListener的做用就是啓動Web容器時,自動裝配ApplicationContext的配置信息。  
            由於它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,  
            啓動容器時,就會默認執行它實現的方法。  
         -->  
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
          <!--   
            它是一個在web應用關閉的時候,清除JavaBeans Introspector的監聽器.  
            在web.xml中註冊這個listener.能夠保證在web 應用關閉的時候釋放與掉這個web 應用相關的class loader 和由它管理的類   
            防止內存泄露  
         --> 
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.shtml</welcome-file>
        <welcome-file>index.jhtml</welcome-file>
    </welcome-file-list>
    <error-page>
        <error-code>403</error-code>
        <location>/WEB-INF/error/403.html</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/404.html</location>
    </error-page>
    <error-page>
      <error-code>500</error-code>
      <location>/WEB-INF/error/500.html</location>
    </error-page>
    <mime-mapping>
        <extension>rar</extension>
        <mime-type>application/zip</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>doc</extension>
        <mime-type>application/zip</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>wps</extension>
        <mime-type>application/zip</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>et</extension>
        <mime-type>application/zip</mime-type>
    </mime-mapping>
</web-app>
源碼解析之二(application-context.xml)
<!--xml進入路徑web.xml/application-context.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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    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.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-lazy-init="true">

    <!-- 加載數據庫屬性文件,以便動態獲取 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>/WEB-INF/config/jdbc.properties</value>
            </list>
        </property>
    </bean>
    <!-- 加載其它屬性文件 -->
    <bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <!-- 其中包話數據庫鏈接,hbm文件和鏈接池信息 -->
                <value>/WEB-INF/config/jdbc.properties</value>
                <!-- 暫時未知 -->
                <value>/WEB-INF/config/jeecms/jeecms.properties</value>
                <!-- 暫時未知 -->
                <value>/WEB-INF/config/plug/**/*.properties</value>
            </list>
        </property>
        <qualifier value="main"/>
    </bean>
    <!-- 經過PropertyUtils包操做properties屬性文件中的屬性,以便動態獲取 -->
    <bean id="propertyUtils" class="com.jeecms.common.util.PropertyUtils">
        <property name="properties" ref="properties"/>
    </bean>
    <!-- 根據已加載的數據庫屬性文件,鏈接數據庫 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
         <!--鏈接關閉時默認將全部未提交的操做回滾。Default: false -->   
        <property name="autoCommitOnClose" value="true"/>
         <!--當鏈接池用完時客戶端調用getConnection()後等待獲取新鏈接的時間,  
                超時後將拋出 SQLException,如設爲0則無限期等待。單位毫秒。Default: 0 -->  
        <property name="checkoutTimeout" value="${cpool.checkoutTimeout}"/>
        <!--初始化時獲取三個鏈接,取值應在minPoolSize與maxPoolSize之間。Default: 3 --> 
        <property name="initialPoolSize" value="${cpool.minPoolSize}"/>
        <!--鏈接池中保留的最小鏈接數。-->  
        <property name="minPoolSize" value="${cpool.minPoolSize}"/>
        <!--鏈接池中保留的最大鏈接數。Default: 15 --> 
        <property name="maxPoolSize" value="${cpool.maxPoolSize}"/>
         <!--最大空閒時間,maxIdleTime秒內未使用則連 接被丟棄。若爲0則永不丟棄。Default: 0 -->
        <property name="maxIdleTime" value="${cpool.maxIdleTime}"/>
        <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 -->   
        <property name="acquireIncrement" value="${cpool.acquireIncrement}"/>
         <!--  
            default : 0 單位 s  
            這個配置主要是爲了減輕鏈接池的負載,好比鏈接池中鏈接數由於某次數據訪問高峯致使建立了不少數據鏈接  
            可是後面的時間段須要的數據庫鏈接數不多,則此時鏈接池徹底沒有必要維護那麼多的鏈接,因此有必要將  
            斷開丟棄掉一些鏈接來減輕負載,必須小於maxIdleTime。配置不爲0,則會將鏈接池中的鏈接數量保持到minPoolSize。  
            爲0則不處理。   
         -->  
        <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}"/>
    </bean>
    <!-- 設置數據庫session工廠 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 動態地經過properties文件加載映射的hbm文件 -->
        <property name="mappingLocations" value="#{propertyUtils.getList('hibernate.hbm')}"/>    
        <!-- 配置hibernate屬性 -->
        <property name="hibernateProperties">
            <value>
            <!-- 指定數據庫方言 --> 
            hibernate.dialect=${hibernate.dialect}
            <!-- 輸出全部SQL語句到控制檯 -->  
            hibernate.show_sql=false
            <!-- 格式化輸出sql語句 --> 
            hibernate.format_sql=false
             <!--   
                這個配置意思是當你在Hibernate裏面輸入true的時候,Hibernate會轉化爲0插入數據庫,  
                當你在Hibernate裏面輸入false的時候,Hibernate會轉化爲1插入數據庫,  
             --> 
            hibernate.query.substitutions=true 1, false 0
            <!-- 指定每次提交SQL的數量。參數值越大,讀數據庫的次數越少,速度越快。 --> 
            hibernate.jdbc.batch_size=20
             <!--   
                容許查詢緩存,對常用的List查詢方式,只有在使用查詢緩存時,  
                纔會從緩存中經過id去get緩存的值;查詢緩存通常緩存查詢語句和查詢結果的id --> 
            hibernate.cache.use_query_cache=true
            </value>
        </property>
        <property name="entityInterceptor">   
            <ref local="treeInterceptor"/>
        </property>
        <property name="cacheProvider">
            <ref local="cacheProvider"/>
        </property>
        <property name="lobHandler">
            <ref bean="lobHandler" />
        </property>
    </bean>
    <!-- 處理 LOB 數據,CLOB 類型,BLOB 類型 --> 
    <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true"/>
    <!-- 緩存 -->  
    <bean id="cacheProvider" class="com.jeecms.common.hibernate3.SpringEhCacheProvider">
        <property name="configLocation">
            <value>/WEB-INF/config/ehcache-hibernate.xml</value>
        </property>
        <property name="diskStoreLocation">
            <value>/WEB-INF/cache/hibernate</value>
        </property>
    </bean>
    <!-- 欄目等樹形結構 -->
    <bean id="treeInterceptor" class="com.jeecms.common.hibernate3.TreeIntercptor"/>
    <!-- 定義事務管理器(聲明式的事務) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!-- 是隱式地向 Spring 容器注入 -->  
    <context:annotation-config/>
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>
源碼解析之三(ehcache-hibernate.xml)
<!-- 其爲hibernate 二級緩存的配置 xml進入路徑web.xml/application-context.xml/ehcache-hibernate.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- 磁盤存儲:將緩存中暫時不使用的對象,轉移到硬盤,相似於Windows系統的虛擬內存 path:指定在硬盤上存儲對象的路徑 -->
    <!--<diskStore path="java.io.tmpdir/jeecms/hibernate"/> -->
    <!-- defaultCache:默認的緩存配置信息,若是不加特殊說明,則全部對象按照此配置項處理 maxElementsInMemory:設置了緩存的上限,最多存儲多少個記錄對象 
        eternal:表明對象是否永不過時 timeToIdleSeconds:最大的發呆時間 timeToLiveSeconds:最大的存活時間 overflowToDisk:是否容許對象被寫入到磁盤 
        diskSpoolBufferSizeMB:磁盤緩衝區的大小 diskExpiryThreadIntervalSeconds:清理過時緩存120秒 -->
    <defaultCache maxElementsInMemory="10000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />
    <!-- cache:爲指定名稱的對象進行緩存的特殊配置 name:指定對象的完整名 -->
    <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="org.hibernate.cache.UpdateTimestampsCache"
        maxElementsInMemory="5000" eternal="true" overflowToDisk="true" />


    <cache name="com.jeecms.core.entity.Sys" maxElementsInMemory="20"
        eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="7200"
        overflowToDisk="true" />
    <cache name="com.jeecms.core.entity.DbTpl" maxElementsInMemory="100"
        eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="7200"
        overflowToDisk="true" />
    <cache name="com.jeecms.core.entity.Ftp" maxElementsInMemory="100"
        eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="7200"
        overflowToDisk="true" />


    <cache name="com.jeecms.cms.entity.main.ContentExt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ContentType"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsUserSite"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsUserExt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ChannelTxt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ContentTag"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsUser"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ContentTxt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsRole"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsModel"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsGroup"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ContentCount"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsSite"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsSiteCompany"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ChannelExt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.ContentCheck"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsConfig"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.viewGroups"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsSite.attr"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.attr"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsGroup.contriChannels"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsRole.perms"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsUser.channels"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.pictures"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsSite.txt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.child"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsSite.cfg"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.contentCheckSet"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.users"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsUser.userExtSet"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.attr"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.attachments"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsGroup.viewChannels"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.contriGroups"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.viewGroups"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.tags"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.CmsConfig.attr"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Content.contentTxtSet"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.main.Channel.channelTxtSet"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />


    <cache name="com.jeecms.cms.entity.assist.CmsVoteTopic.items"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsKeyword"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsCommentExt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsGuestbookExt"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsSensitivity"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsVoteTopic"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsGuestbookCtg"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsVoteRecord"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsVoteItem"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsGuestbook"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsComment"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
    <cache name="com.jeecms.cms.entity.assist.CmsJobApply"
        maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600"
        timeToLiveSeconds="7200" overflowToDisk="true" />
源碼解析之四(cache-context.xml)
<pre name="code" class="java"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
    default-lazy-init="true">
    <!--緩存-->
    <bean id="cacheManager" class="com.jeecms.common.web.WebEhCacheManagerFacotryBean">
        <property name="configLocation">
            <value>/WEB-INF/config/ehcache-application.xml</value>
        </property>
        <property name="diskStoreLocation">
            <value>/WEB-INF/cache/application</value>
        </property>
    </bean>
    <!--SESSION緩存-->
    <bean id="ehSessionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.common.web.Session</value>
        </property>
        <qualifier value="session"/>
    </bean>
    <!--內容計數緩存-->
    <bean id="ehContentCountCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.ContentCount</value>
        </property>        
        <qualifier value="contentCount"/>
    </bean>
    <!--欄目計數緩存-->
    <bean id="ehChannelCountCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.ChannelCount</value>
        </property>        
        <qualifier value="channelCount"/>
    </bean>
    <!--微信token緩存-->
    <bean id="ehWeixinTokenCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.weixin.token</value>
        </property>        
        <qualifier value="tokenCache"/>
    </bean>
    
    <!--站點流量緩存-->
    <bean id="ehCmsSiteFlowCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsSiteFlow</value>
        </property>        
        <qualifier value="cmsSiteFlow"/>
    </bean>
    <!--一次會話訪問緩存-->
    <bean id="ehCmsSiteAccessCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsAccess</value>
        </property>        
        <qualifier value="cmsAccessCache"/>
    </bean>
    <!--最新會話訪問緩存-->
    <bean id="ehCmsSiteLastAccessCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsLastAccess</value>
        </property>        
        <qualifier value="cmsLastAccessCache"/>
    </bean>
    <!--每次訪問頁面緩存-->
    <bean id="ehCmsSiteAccessPagesCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsAccessPage</value>
        </property>        
        <qualifier value="cmsAccessPageCache"/>
    </bean>
    <!--pv總量計數緩存-->
    <bean id="ehPvTotalCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsSitePvTotal</value>
        </property>        
        <qualifier value="cmsPvTotalCache"/>
    </bean>
    <!--訪問者總量計數緩存-->
    <bean id="ehVisitorTotalCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsSiteVisitorTotal</value>
        </property>        
        <qualifier value="cmsVisitorTotalCache"/>
    </bean>
        
    <!--搜索詞彙緩存-->
    <bean id="ehSearchWordsCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.front.CmsSearchWords</value>
        </property>        
        <qualifier value="cmsSearchWords"/>
    </bean>
    
    <!--shiro緩存
    <bean id="ehShiroCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager">
            <ref local="cacheManager"/>
        </property>
        <property name="cacheName">
            <value>com.jeecms.cms.shiro.shiroCache</value>
        </property>        
        <qualifier value="shiroCache"/>
    </bean>
    -->
</beans>
源碼解析之五(Spring + FreeMarker 的集成)
共四步

加載屬性文件 application-context.xml 下的 jeecms.properties,會在第四步用到。
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
    <display-name>JeeCmsV7</display-name>  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>  
            <!-- 數據庫相關配置並加載了hbm.xml文件 (Spring)-->  
            /WEB-INF/config/application-context.xml  
            <!-- 數據緩存相關配置 -->  
            /WEB-INF/config/cache-context.xml  
            <!-- 驗證碼相關配置 -->   
            /WEB-INF/config/captcha-context.xml  
             <!-- 圖片,密碼,文件上傳等配置 -->   
            /WEB-INF/config/jeecms/jeecore-context.xml  
            <!-- spring bean相關配置,如dao層的配置、圖片處理,密碼加密 -->  
            /WEB-INF/config/jeecms/jeecms-context.xml  
            <!-- 配置權限管理shiro-context.xml框架 -->  
            /WEB-INF/config/shiro-context.xml  
            <!-- 配置其它插件文件,暫時沒有 -->  
            /WEB-INF/config/plug/**/*-context.xml  
            <!-- 配置定時任務 -->  
            /WEB-INF/config/quartz-task.xml  
        </param-value>  
    </context-param>  
...  
</web-app>
前臺配置:
配置 FreeMarkerConfigurer
<!-- 配置freemaker -->  
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
        <!--獲取標籤配置-->  
        <property name="freemarkerVariables" value="#{propertyUtils.getBeanMap('directive.')}"/>  
        <property name="templateLoaderPath" value=""/>  
        <property name="freemarkerSettings">  
            <props>  
                <prop key="tag_syntax">auto_detect</prop>  
                <prop key="template_update_delay">5</prop>  
                <prop key="defaultEncoding">UTF-8</prop>  
                <prop key="url_escaping_charset">UTF-8</prop>  
                <prop key="locale">zh_CN</prop>  
                <prop key="boolean_format">true,false</prop>  
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>  
                <prop key="date_format">yyyy-MM-dd</prop>  
                <prop key="time_format">HH:mm:ss</prop>  
                <prop key="number_format">0.######</prop>  
                <prop key="whitespace_stripping">true</prop>  
                <!--空值處理<prop key="classic_compatible">true</prop>-->  
                <!--定義FreeMaker引入文件,index.ftl前綴爲p,spring.ftl的前綴爲s,這樣在飲用ftl模版的宏定義時,能夠簡略使用-->  
                <prop key="auto_import">/WEB-INF/ftl/jeecms/index.ftl as p,/WEB-INF/ftl/spring.ftl as s</prop>  
            </props>  
        </property>  
    </bean>
解析 FreeMarker 視圖
<!-- 解析freemaker視圖 -->  
    <bean id="freemarkerViewResolver" class="com.jeecms.common.web.springmvc.SimpleFreeMarkerViewResolver">  
        <property name="contentType" value="text/html; charset=UTF-8"/>  
        <!-- 請求屬性不暴露給freemaker使用 -->  
        <property name="exposeRequestAttributes" value="false"/>  
        <!-- 會話屬性不暴露給freemaker使用 -->  
        <property name="exposeSessionAttributes" value="false"/>  
        <!-- 使用宏 -->  
        <property name="exposeSpringMacroHelpers" value="true"/>  
    </bean>
後臺配置
配置 FreeMarkerConfigurer
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
        <property name="templateLoaderPath" value="/WEB-INF"/>  
        <property name="freemarkerVariables">  
            <map>  
                <!--在FCK編輯器中須要用到appBase,以肯定connector路徑。-->  
                <entry key="appBase" value="/jeeadmin/jeecms"/>  
                <!--後臺管理權限控制-->  
                <entry key="cms_perm" value-ref="cms_perm"/>  
                <entry key="text_cut" value-ref="text_cut"/>  
                <entry key="html_cut" value-ref="html_cut"/>  
                <entry key="cms_content_list" value-ref="cms_content_list"/>  
                <entry key="cms_content_page" value-ref="cms_content_page"/>  
            </map>  
        </property>  
        <property name="freemarkerSettings">  
            <props>  
                <prop key="template_update_delay">0</prop>  
                <prop key="defaultEncoding">UTF-8</prop>  
                <prop key="url_escaping_charset">UTF-8</prop>  
                <prop key="locale">zh_CN</prop>  
                <prop key="boolean_format">true,false</prop>  
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>  
                <prop key="date_format">yyyy-MM-dd</prop>  
                <prop key="time_format">HH:mm:ss</prop>  
                <prop key="number_format">0.######</prop>  
                <prop key="whitespace_stripping">true</prop>  
                <!--定義FreeMaker引入文件,index.ftl前綴爲p,spring.ftl的前綴爲s,這樣在飲用ftl模版的宏定義時,能夠簡略使用-->  
                <prop key="auto_import">/ftl/jeecms/index.ftl as p,/ftl/spring.ftl as s</prop>  
            </props>  
        </property>  
    </bean>
解析 FreeMarker 視圖
<!-- 視圖解析器 -->  
    <bean id="freemarkerViewResolver" class="com.jeecms.common.web.springmvc.RichFreeMarkerViewResolver">  
        <!-- 前綴 -->  
        <property name="prefix" value="/jeecms_sys/"/>  
        <!-- 後綴 -->  
        <property name="suffix" value=".html"/>  
        <property name="contentType" value="text/html; charset=UTF-8"/>  
        <!-- 請求屬性不暴露給freemaker使用 -->  
        <property name="exposeRequestAttributes" value="false"/>  
        <!-- 會話屬性不暴露給freemaker使用 -->  
        <property name="exposeSessionAttributes" value="false"/>  
        <!-- 使用宏 -->  
        <property name="exposeSpringMacroHelpers" value="true"/>  
    </bean>
注入 freeMarkerConfigurer(jeecms-context.xml)
<bean id="staticPageSvc" class="com.jeecms.cms.staticpage.StaticPageSvcImpl">  
        <property name="tplMessageSource" ref="tplMessageSource"/>  
        <property name="freeMarkerConfigurer">  
            <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
                <!-- 從jeecms.properties中獲取標籤:directive.前綴的 -->  
                <property name="freemarkerVariables" value="#{propertyUtils.getBeanMap('directive.')}"/>  
                <property name="templateLoaderPath" value=""/>  
                <property name="freemarkerSettings">  
                    <props>  
                        <prop key="tag_syntax">auto_detect</prop>  
                        <prop key="template_update_delay">5</prop>  
                        <prop key="defaultEncoding">UTF-8</prop>  
                        <prop key="url_escaping_charset">UTF-8</prop>  
                        <prop key="locale">zh_CN</prop>  
                        <prop key="boolean_format">true,false</prop>  
                        <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>  
                        <prop key="date_format">yyyy-MM-dd</prop>  
                        <prop key="time_format">HH:mm:ss</prop>  
                        <prop key="number_format">0.######</prop>  
                        <prop key="whitespace_stripping">true</prop>  
                        <prop key="auto_import">/WEB-INF/ftl/jeecms/index.ftl as p,/WEB-INF/ftl/spring.ftl as s</prop>  
                    </props>  
                </property>  
            </bean>  
        </property>  
    </bean>
源碼解析之六(前臺頁面初始化)
項目啓動,初始化配置文件
<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>  
            <!-- 數據庫相關配置並加載了hbm.xml文件 (Spring)-->  
            /WEB-INF/config/application-context.xml  
            <!-- 數據緩存相關配置 -->  
            /WEB-INF/config/cache-context.xml  
            <!-- 驗證碼相關配置 -->   
            /WEB-INF/config/captcha-context.xml  
             <!-- 圖片,密碼,文件上傳等配置 -->   
            /WEB-INF/config/jeecms/jeecore-context.xml  
            <!-- spring bean相關配置,如dao層的配置、圖片處理,密碼加密 ,freemaker的使用-->  
            /WEB-INF/config/jeecms/jeecms-context.xml  
            <!-- 配置權限管理shiro-context.xml框架 -->  
            /WEB-INF/config/shiro-context.xml  
            <!-- 配置其它插件文件,暫時沒有 -->  
            /WEB-INF/config/plug/**/*-context.xml  
            <!-- 配置定時任務 -->  
            /WEB-INF/config/quartz-task.xml  
        </param-value>  
    </context-param>
瀏覽器輸入 http://localhost:8070/jeeCms/
<bean id="dynamicAct" class="com.jeecms.cms.action.front.DynamicPageAct"/>
經過過濾器進入
/**  
 * TOMCAT的默認路徑  
 *   
 * @param request  
 * @param model  
 * @return  
 */  
@RequestMapping(value = "/", method = RequestMethod.GET)  
public String index(HttpServletRequest request,HttpServletResponse response, ModelMap model) {  
    CmsSite site = CmsUtils.getSite(request);  
    FrontUtils.frontData(request, model, site);  
    //帶有其餘路徑則是非法請求  
    String uri=URLHelper.getURI(request);  
    if(StringUtils.isNotBlank(uri)&&!uri.equals("/")){  
        return FrontUtils.pageNotFound(request, response, model);  
    }  
    //使用靜態首頁並且靜態首頁存在  
    if(site.getStaticIndex()&&new File(realPathResolver.get(site.getStaticDir()+INDEX)).exists()){  
        return FrontUtils.getTplPath("", site.getStaticDir(), INDEX);  
    }else{  
        return site.getTplIndexOrDef();  
    }  
}
返回一個 url 並 進入主頁。
<!-- 當輸入localhost:8080/jeeCms時,會先找第一個歡迎頁,沒有的話找第二個,依次類推,若是存在,就不找了 -->  
    <welcome-file-list>  
        <welcome-file>index.html</welcome-file>  
        <welcome-file>index.shtml</welcome-file>  
        <welcome-file>index.jhtml</welcome-file>  
    </welcome-file-list>
經過標籤進入指定的類,並調用期 execute() 方法(之前臺 @cms_content_list 爲例)
前臺標籤:
<div class="cl">  
     <ul class="slideshow" id="slidesImgs">  
         [@<strong>cms_content_list</strong> count='5' orderBy='4' typeId='3' titLen='18' channelOption='1' channelId='1']  [#list tag_list as a]  
              <li>  
                                        <a href="${a.url}" target="_blank">  
                                        <img src="${a.typeImg!site.defImg}" alt="${a.title}" width="100%" />  
                                        </a>  
                                        <span class="title">  
                                        [@text_cut s=a.title len=titLen /]  
                                        </span>  
                                    </li>  
                                    [/#list]  
                                    [/@cms_content_list]  
                                    </ul>  
                                </div>
在 web.xml—>jeecms-contextxml 配置中找到相關的處理類
<bean id="cms_content_list" class="com.jeecms.cms.action.directive.ContentListDirective"/>
調用其 execute()方法對其進行處理
/*   
    *  模板名稱  
     */  
    public static final String TPL_NAME = "content_list";  
  
    /** 
     * 輸入參數,文章ID。容許多個文章ID,用","分開。排斥其餘全部篩選參數。 
     */  
    public static final String PARAM_IDS = "ids";  
  
    @SuppressWarnings("unchecked")  
    public void execute(Environment env, Map params, TemplateModel[] loopVars,  
            TemplateDirectiveBody body) throws TemplateException, IOException {  
        //獲取站點  
        CmsSite site = FrontUtils.getSite(env);  
        //獲取內容列表,可經過此處進行更改,獲取本身數據庫中的數據  
        List<Content> list = getList(params, env);  
          
        Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(params);  
        //OUT_LIST 的值是tag_list,在DirectiveUtils中聲名,將內容列表放入其中  
        paramWrap.put(OUT_LIST, DEFAULT_WRAPPER.wrap(list));  
        //將params的值複製上到ariable中  
        Map<String, TemplateModel> origMap = DirectiveUtils.addParamsToVariable(env, paramWrap);  
        //獲取的是參數PARAM_TPL,是否調用模板及調用的模板類型  
        InvokeType type = DirectiveUtils.getInvokeType(params);  
        //獲取模板的傳入參數,列表樣式,根據不兩隻的參數獲取不一樣的樣式列表  
        String listStyle = DirectiveUtils.getString(PARAM_STYLE_LIST, params);  
        if (InvokeType.sysDefined == type) {  
            if (StringUtils.isBlank(listStyle)) {  
                throw new ParamsRequiredException(PARAM_STYLE_LIST);  
            }  
            //列表樣式模板  
            env.include(TPL_STYLE_LIST + listStyle + TPL_SUFFIX, UTF8, true);  
        } else if (InvokeType.userDefined == type) {  
            if (StringUtils.isBlank(listStyle)) {  
                throw new ParamsRequiredException(PARAM_STYLE_LIST);  
            }  
            //列表樣式模板的路徑  
            FrontUtils.includeTpl(TPL_STYLE_LIST, site, env);  
        } else if (InvokeType.custom == type) {  
            //這個模板是本身聲明的,即content_list.html,若是採用自定義模板的話,頁面中能夠只寫上標籤,並添加上標籤內須要的幾個參數不須要寫標籤的內容,會去自動調用模板中的標籤體。  
            FrontUtils.includeTpl(TPL_NAME, site, params, env);  
        } else if (InvokeType.body == type) {  
            body.render(env.getOut());  
        } else {  
            throw new RuntimeException("invoke type not handled: " + type);  
        }  
        //將variable中的params值移除  
        DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);  
    }  
  
    @SuppressWarnings("unchecked")  
    protected List<Content> getList(Map<String, TemplateModel> params,  
            Environment env) throws TemplateException {  
        Integer[] ids = DirectiveUtils.getIntArray(PARAM_IDS, params);  
        if (ids != ) {  
            //根據ID數組獲取文章列表  
            return contentMng.getListByIdsForTag(ids, getOrderBy(params));  
        } else {  
            return (List<Content>) super.getData(params, env);  
        }  
    }
前臺經過標籤循環取出數據
<ul class="slideshow" id="slidesImgs">  
                                    [@cms_content_list count='5' orderBy='4' typeId='3' titLen='18' channelOption='1' channelId='1']  
                                    <!-- 將OUT_LIST 即tag_list中的值遍歷出來 -->  
                                    [#list tag_list as a]  
                                    <li>  
                                        <a href="${a.url}" target="_blank">  
                                        <img src="${a.typeImg!site.defImg}" alt="${a.title}" width="100%" />  
                                        </a>  
                                        <span class="title">  
                                        [@text_cut s=a.title len=titLen /]  
                                        </span>  
                                    </li>  
                                    [/#list]  
                                    [/@cms_content_list]  
                                 </ul>
源碼解析之七(前臺頁面初始化是 request 賦值)
問題:
當輸入 http://localhost:8070/jeeCms / 時,經過攔截器 「/」 後臺時,request 中包含了不少值是哪裏來的?

回答:
加載 web.xml
<!-- 前臺控制 -->   
    <servlet>  
        <servlet-name>JeeCmsFront</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>  
                /WEB-INF/config/jeecms-servlet-front.xml  
                /WEB-INF/config/plug/**/*-servlet-front-action.xml  
            </param-value>  
        </init-param>  
        <load-on-startup>2</load-on-startup>  
    </servlet>
其初使化方法中 進入 jeecms-servlet-front.xml,初使化:
<bean id="frontContextInterceptor" class="com.jeecms.cms.web.FrontContextInterceptor"/>
爲 reques 和中放入值
/** 
 * CMS上下文信息攔截器 
 *  
 * 包括登陸信息、權限信息、站點信息 
 */  
public class FrontContextInterceptor extends HandlerInterceptorAdapter {  
    public static final String SITE_COOKIE = "_site_id_cookie";  
    @Override  
    public boolean preHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler)  
            throws ServletException {  
        CmsSite site = ;  
        List<CmsSite> list = cmsSiteMng.getListFromCache();  
        int size = list.size();  
        if (size == 0) {  
            throw new RuntimeException("no site record in database!");  
        } else if (size == 1) {  
            site = list.get(0);  
        } else {  
            String server = request.getServerName();  
            String alias, redirect;  
            for (CmsSite s : list) {  
                // 檢查域名  
                if (s.getDomain().equals(server)) {  
                    site = s;  
                    break;  
                }  
                // 檢查域名別名  
                alias = s.getDomainAlias();  
                if (!StringUtils.isBlank(alias)) {  
                    for (String a : StringUtils.split(alias, ',')) {  
                        if (a.equals(server)) {  
                            site = s;  
                            break;  
                        }  
                    }  
                }  
                // 檢查重定向  
                redirect = s.getDomainRedirect();  
                if (!StringUtils.isBlank(redirect)) {  
                    for (String r : StringUtils.split(redirect, ',')) {  
                        if (r.equals(server)) {  
                            try {  
                                response.sendRedirect(s.getUrl());  
                            } catch (IOException e) {  
                                throw new RuntimeException(e);  
                            }  
                            return false;  
                        }  
                    }  
                }  
            }  
            if (site == ) {  
                throw new SiteNotFoundException(server);  
            }  
        }  
          
        <span style="background-color: rgb(204, 153, 51);">CmsUtils.setSite(request, site);</span>  
        CmsThreadVariable.setSite(site);  
        Subject subject = SecurityUtils.getSubject();  
        if (subject.isAuthenticated()|| subject.isRemembered()) {  
            String username =  (String) subject.getPrincipal();  
            CmsUser user = cmsUserMng.findByUsername(username);  
            CmsUtils.setUser(request, user);  
            // Site加入線程變量  
            CmsThreadVariable.setUser(user);  
        }  
        createJsessionId(request, response, site);  
        return true;  
    }
源碼解析之八(jeeCms 整合 webservice)
第一步:在 jeeCms . 添加 jar 包
第二步:增長 webservice 相關配置。
web.xml

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>  
        <!-- 數據庫相關配置並加載了hbm.xml文件 (Spring)-->  
        /WEB-INF/config/application-context.xml  
        <!-- 數據緩存相關配置 -->  
        /WEB-INF/config/cache-context.xml  
        <!-- 驗證碼相關配置 -->   
        /WEB-INF/config/captcha-context.xml  
         <!-- 圖片,密碼,文件上傳等配置 -->   
        /WEB-INF/config/jeecms/jeecore-context.xml  
        <!-- spring bean相關配置,如dao層的配置、圖片處理,密碼加密 ,freemaker的使用-->  
        /WEB-INF/config/jeecms/jeecms-context.xml  
        <!-- 配置權限管理shiro-context.xml框架 -->  
        /WEB-INF/config/shiro-context.xml  
        <!-- 配置其它插件文件,暫時沒有 -->  
        /WEB-INF/config/plug/**/*-context.xml  
        <!-- 配置定時任務 -->  
        /WEB-INF/config/quartz-task.xml  
        <!-- 配置webservice -->  
      <span style="color:#ff6666;">      /WEB-INF/config/webservice/cxf-service.xml</span>  
    </param-value>  
</context-param>
<!-- CXF webservice -->  
   <servlet>    
    <servlet-name>CXFServlet</servlet-name>    
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>    
<load-on-startup>2</load-on-startup>    
    </servlet>  
    <servlet-mapping>    
    <servlet-name>CXFServlet</servlet-name>    
    <url-pattern>/ws/*</url-pattern>    
    </servlet-mapping>
cxf-service.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:tx="http://www.springframework.org/schema/tx"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:jaxws="http://cxf.apache.org/jaxws"  
    xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"  
    xsi:schemaLocation="  
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd  
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd  
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd  
    http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">      
      
    <http-conf:conduit name="*.http-conduit">       
        <http-conf:client ConnectionTimeout="60000" ReceiveTimeout="60000"/>      
    </http-conf:conduit>  
    <!-- 這兩個xml文件來源cxf jar包 -->  
    <import resource="classpath:META-INF/cxf/cxf.xml" />  
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  
      
    <!-- 這個文件中用來配置webservice服務器 -->  
    <import resource="action-cxf.xml" />  
  
</beans>
action-cxf.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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
    http://cxf.apache.org/jaxws      
    http://cxf.apache.org/schemas/jaxws.xsd">
    <!-- 
    <jaxws:endpoint id="ActPromWebService" implementor="#bizActPromWebService" address="/ActPromWebService" />
     -->
</beans>
第三步 建立 webService 接口類,用來存放調用 webService 的方法
package com.jeecms.cms.action.directive;  
  
import javax.jws.WebMethod;  
import javax.jws.WebParam;  
import javax.jws.WebService;  
  
@WebService(targetNamespace="http://webservice.cus.biz.cbp.cj.com/")  
public interface countInfoInterfaceNpl {  
      
    public static final String SERVICE_NAME = "FindAllCustWebSerrvice";  
  
    /** 
     * 根據客戶ID查詢客戶的詳細信息 
     *  
     * @param traT 
     * @param custB 
     * @return 
     */  
    @WebMethod  
    String findByIdCustB(@WebParam(name = "partnerId") String partnerId, @WebParam(name = "traT") String traT, @WebParam(name = "custB") String custB,  
            @WebParam(name = "orderId") String orderId,@WebParam(name = "verifyCode") String verifyCode);  
  
}
第四步 java 類中調用 webservice
package com.jeecms.cms.action.directive;  
  
import static com.jeecms.common.web.freemarker.DirectiveUtils.OUT_BEAN;  
import static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;  
  
import java.io.IOException;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
import java.util.HashMap;  
import java.util.Map;  
  
import javax.jws.WebService;  
  
import org.apache.cxf.interceptor.LoggingInInterceptor;  
import org.apache.cxf.interceptor.LoggingOutInterceptor;  
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  
import com.jeecms.common.web.freemarker.DirectiveUtils;  
  
import freemarker.core.Environment;  
import freemarker.template.TemplateDirectiveBody;  
import freemarker.template.TemplateDirectiveModel;  
import freemarker.template.TemplateException;  
import freemarker.template.TemplateModel;  
   
/** 
 * 總計信息 
 */  
public class CountInfoNpl implements TemplateDirectiveModel {  
  
    @SuppressWarnings("unchecked")  
    public void execute(Environment env, Map params, TemplateModel[] loopVars,  
            TemplateDirectiveBody body) throws TemplateException, IOException {  
        try {  
        int i=1;  
        if(i==1){  
             JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  
             factory.getInInterceptors().add(new LoggingInInterceptor());  
             factory.getOutInterceptors().add(new LoggingOutInterceptor());  
             factory.setServiceClass(countInfoInterfaceNpl.class);//調用的接口類  
             factory.setAddress("http://127.0.0.1:8060/ws/FindAllCustWebSerrvice");  
             Object cInstance = factory.create();  
             Method invokeMethod = ;  
            //循環接口類的全部方法,並與實際調用的方法比較,若不存在,則給出錯誤信息  
             for(Method m : (countInfoInterfaceNpl.class).getDeclaredMethods()){  
                 if(!m.getName().equalsIgnoreCase("")){  
                     invokeMethod = m;  
                     break;  
                 }  
             }  
             if(invokeMethod == )  
                 throw new Exception("ERROR:method not found");  
            //爲webService添加參數  
            Object[] params1 = new Object[5];  
            params1[0] = ;  
            params1[1] = "aaaa";  
            params1[2] = "bbnn";  
            params1[3] = ;  
            params1[4] = ;  
            //調用webService接口,並用CustNpl接收返回值  
            CustBNpl res = (CustBNpl) invokeMethod.invoke(cInstance, params1);  
            System.out.println("aaa");  
        }else{  
            Map<String,String> cmsVoteInfo=new HashMap<String,String>();  
            cmsVoteInfo.put("publicInfo", "加薪寶漲息");  
            cmsVoteInfo.put("totalCaptial","20000001");  
            cmsVoteInfo.put("goldCaptial","5555555");  
            cmsVoteInfo.put("getMoney","6666666");  
              
            Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(  
                    params);  
            paramWrap.put(OUT_BEAN, DEFAULT_WRAPPER.wrap(cmsVoteInfo));  
            Map<String, TemplateModel> origMap = DirectiveUtils.addParamsToVariable(env, paramWrap);  
            body.render(env.getOut());  
            DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);  
        }  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
          
    }  
}

打賞
本文做者: IIsKei
本文連接: http://www.iskei.cn/posts/63673.html
版權聲明: 本博客全部文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明出處!
相關文章
相關標籤/搜索