mvc 架構

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            74 Posts :: 60 Stories :: 5 Comments :: 0 Trackbacks
          posted on 2007-09-12 13:57 e全 閱讀(3094) 評論(0)  編輯  收藏

          [1]

          1. 前言

          此文檔講述的內容適合于對 Spring MVC 和數據持久層 ORM 概念有一定基礎的開發者,著重于講述基于 Spring 框架基礎之上進行 Java 開發的其中一種技術解決方案,而不是講述相關技術的原理,想要了解技術原理內容請參考相關文檔資料。
          ?
            現在,網絡上流傳的Spring+Struts+Hibernate用得非常火,幾乎成為很多對技術癡迷的人的技術架構標準,可是在我看來,也許是因為項目都不算大,人力也不夠多,這個技術架構太復雜了。從Spring本身來講,從MVC到數據操作,都可以不需要其他附加組件即可實現,并且結構清晰,使用簡單,功能還更加強大,本文講述的重點就是單獨使用Spring來建立一個簡易的開發框架。
          ?
            首先說,為什么選擇Spring呢?大概在2003年的時候,Struts已經開始流行了,但是在學習Struts的時候感覺這個技術框架比原始的JSP+JavaBean的方式復雜了很多,后來2004年做新項目時在論壇上看到推薦Spring,下載一試,上手非常的容易,結構也很清晰,支持的功能也非常多,所以決定用它了(其實那時候對于依賴注入和AOP代理還不甚了解,也很少用到接口)。

            在
          2001-2003年的時候都是自己封裝了JavaBean做為公共模塊來訪問數據庫的,后來ORM興起了,先是看了Hibernate的,3.0版還沒用出,還不支持存儲過程,因為那時候也做Delphi相關開發,用慣了SQL語句,始終覺得HQL這樣的東東增加了開發的復雜度和不可控制性,原生的復雜SQL語句無法使用,不喜歡。后來看到了iBATIS,經過試用,正是我所需要的,SQL語句配置簡單,基本不會破壞SQL語句的結構,這樣將SQL語句Copy到外部數據庫工具中進行調試也非常的方便,加上SQL語句可以使用很多的特定數據庫的函數,執行效率和簡潔性也非常好,修改了SQL又不需要重新編譯程序。

            
          有網友說Hibernate支持多個數據庫移值啊,我認為這個就不僅僅是SQL語句的問題了,還有很多其他方面的因素,大多數項目都可以不用考慮。又有網友說Hibernate對于數據庫結構修改的影響比較小,這種情況影響的也不僅僅是幾句代碼的問題,涉及到界面表現、業務流程等很多重要方面,相對說來修改代碼倒是小Case了。


            說完了上面的
          ORM 組件,再說說 JDBC Spring JdbcTemplate 將我們常用的 JDBC 流程封裝起來,使用非常簡單,一般執行的 SQL 就是一句話,構造 SQL 隨著業務的復雜而復雜,并且也支持 PrepareStatement 的執行模式避免 SQL 注入漏洞發生,同樣具備完整的數據操作功能如查詢、更新、存儲過程、異常捕捉等等,經過幾年的使用比較,我認為輕型的項目使用 JdbcTemplate 是非常不錯的選擇。

            由于能力所限,其中細節如有欠缺之處,請多多批評指正。

          2. 參考資料

          2 ? Spring 官方網站: http://www.springframework.org/

          2 ? Spring 2.0 中文參考手冊: http://spring.jactiongroup.net/

          2 ? Apache Jakarta 官方網站: http://jakarta.apache.org/

          2 ? JSTL 官方網站: http://java.sun.com/products/jsp/jstl/

          2 ? Intellij IDEA 官方網站: http://www.jetbrains.com/

          3. 架構概覽

          MVC 層在 Spring AbstractController 類基礎上進行了繼承和重構,使整個框架僅使用單一的公共控制器,數據操作采用 Spring JdbcTemplate ,在邏輯層中直接集成了 Spring Jdbc 能力,可直接操作數據,表現層 Jstl ,除此之外,未定義任何的表單對象、數據庫表映射對象和其他 ORM 的配置文件,在保留對關鍵功能的集成度的基礎上技術入門度極低,重點關注業務功能和優化 SQL 語句

          請求處理流傳如圖所示:



          1)????? 用戶訪問 http://www.fyyk.com/a.do

          2)????? Web 應用服務器(如 tomcat )解析擴展名為 *.do 的請求,通過 Spring 分發器 org.springframework.web.servlet.DispatcherServlet 讀取 servlet-do.xml 中的配置,將請求轉發給公共控制器類 LogicController.java

          3)????? 公共控制器類 LogicController.java 根據 servlet-do.xml 文件中的配置信息調用 DoLogicImpl.java 類中相對應名稱的方法;

          4)????? DoLogicImpl.java 類中的方法在處理完成業務邏輯后,將數據內容 ModelAndView 返回給公共控制器類 LogicController.java

          5)????? 公共控制器類 LogicController.java 處理 ModelAndView 信息,執行 b.jsp 將結果數據顯示出來;

          3.1. 控制器 Controller




            控制器類配置在

          servlet-xxx.xml 文件中,封裝后的 Controller 特點如下:

          1)??? 繼承 AbstractController 類,便于調用應用環境的 Web 特性;

          2)?? 只用控制器做請求的轉發,業務實現全部在邏輯層;

          3)????? 采用反映射機制( reflect ),運行期調用邏輯類中的方法,而請求 URI 、邏輯類和方法名之間的對應關系只需要在 servlet-xxx.xml 中配置,這樣,控制器實現就只有唯一的一個類文件;

          3.2. 邏輯層 Logic




            邏輯層類在

          applicationContext-xxx.xml 文件配置 Bean 定義中,主要實現兩項功能:一是處理業務邏輯,二是操作數據庫;

          邏輯層類首先需要定義一個接口類,統一以 xxxLogic.java 命名,實現類命名為 xxxLogicImpl.java ,并繼承 JdbcDaoSupport 類,這樣邏輯類便具有了數據庫訪問能力。

          邏輯類的方法如果被公共控制器類 LogicController.java 的反映射機制直接調用,則其接口類需要繼承空的公共接口類 BasicLogic ,定義方法時參數和返回值是固定的,如果是被其他邏輯類調用則不需要。

          public ModelAndView initLogin(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext);

          控制器層直接將請求的 request response servletContext 全部傳遞過來交由邏輯層自由控制,對于 request 中的表單數據,未采用 SimpleFormController 的模式定義表單對象,建議手工獲取,從代碼量本身來將并不復雜,反而更加靈活。在業務處理完成后,必須構造一個 ModelAndView 對象,作為方法返回值回傳給控制器。

          范例代碼如下:

          public class AdminLogicImpl extends JdbcDaoSupport implements AdminLogic

          {

          ?

          public ModelAndView insertUser(HttpServletRequest request, HttpServletResponse response,

          ??? ServletContext servletContext) throws DataAccessException

          ??? {

          ? ???? ??String userId = request.getParameter("userId");

          ? ???? ??String userName = request.getParameter("userName");

          ? ???? ??int age = Integer.parseInt(request.getParameter("age"));

          ? ???? ??double weight = Double.parseDouble(request.getParameter("weight"));

          ?

          ? ???? ??String sqlStr = "insert into testuser (userId,username,age,weight,updatetime) values (?,?,?,?,?)";

          ?? ???? ?Object[] object = new Object[]{userId, userName, age, weight, new Date()};

          ?? ???? ?getJdbcTemplate().update(sqlStr, object);

          ?

          ? ???? ?Map<String, Object> model = new HashMap<String, Object>();

          ?? ???? ?model.put("msg", " 插入用戶成功! ");

          ??? ????model.put("url", "pageForm.user");

          ?? ???? ?String view = "admin/message.jsp";

          ?? ???? ?return new ModelAndView(view, model);

          ??? }

          }

          3.3. 表現層 Jstl

          表現層采用 Jstl taglib 1.2 ,在 *.jsp 頁面中加入 taglib 引用即可使用 Jstl 標簽的大部分功能了,標簽的具體使用方法請參考相關文檔。

          <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

          <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

          <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>


          4. 開發準備

          4.1. 開發工具

          ?? Java 編輯器 Intellij IDEA 6.0.5 Eclipse WTP 3.2

          ?? JDK5.0 Update 11

          ?? Web 服務器 Tomcat 5.5.20

          ?? 數據庫 Oracle10g

          4.2. 支撐庫文件

          spring.jar

          spring 2.0.3

          jstl.jar

          standard.jar

          Jstl 1.2

          commons-io-1.3.1.jar

          commons-fileupload-1.2.jar

          文件上傳組件

          commons-logging-1.1.jar

          log4j-1.2.14.jar

          日志組件

          mail.jar

          activation.jar

          郵件組件

          quartz-1.5.2.jar

          時序調度組件

          aspectjweaver.jar

          AOP 組件

          commons-lang-2.3.jar

          Apache 公共包

          commons-codec-1.3.jar

          commons-collections-3.2.jar

          commons-httpclient-3.0.1.jar

          Httpclient 組件

          4.3. 系統目錄結構

          s004.gif

          ?

          ?

          /

          工程根目錄

          /lib

          工程所用的庫文件目錄

          /src

          源代碼目錄

          /webapp

          站點根目錄

          /webapp/css

          樣式表目錄

          /webapp/images

          圖片目錄

          /webapp/js

          Js 腳本目錄

          /webapp/WEB-INF

          web.xml 等配置文件所在目錄

          /webapp/WEB-INF/classes

          Class 所在目錄

          /webapp/WEB-INF/jsp

          Jsp 文件存放目錄

          /webapp/WEB-INF/lib

          jar 包目錄

          /webapp/WEB-INF/logs

          程序日志目錄

          /webapp/WEB-INF/temp

          臨時文件保存目錄

          4.4. 配置開發環境

          4.4.1 設置字符集

          程序文件全部為 UTF-8 字符集,使用開發工具建立工程時需要修改工程的默認字符集。


            在
          IDEA 中通過 Ctrl+Alt+S 快捷鍵打開設置窗口,選擇 IDE Settings 下面的 General 打開通用設置窗口,修改 File Encoding 下面的 Default encoding UTF-8 ,同時修改 Properties Files 下面的 Default encoding UTF-8


           在
          Eclipse 中點擊菜單 Window-Preferences 打開參數設置窗口,選擇左側樹形節點 General-Workspace ,修改 Text File Encoding UTF-8


            如果需要使用已經存在的源文件,使用
          IDEA 建立同名新文件,然后 copy 原始文件內容到新文件中,注意不要直接使用源文件,可能會產生亂碼問題。

          4.4.2 配置數據庫驅動

            由于數據庫連接池組件包使用的是 Tomcat 自帶,所以數據庫驅動程序包需要放在 Tomcat 可以訪問的位置, Oracle 驅動 ojdbc14.jar 文件必須 Copy tomcat/common/lib 這樣的目錄下,而不能放在開發工具工程 lib 目錄下。

          5. web.xml 配置

          5.1. 基本配置

             web.xml 采用 servlet2.4 規范,默認配置了會話過期時間和網站首頁文件。

          <?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">

          ?

          ??? <!-- 會話的時間 -->

          ? ??<session-config>

          ????????????? <session-timeout>30</session-timeout>

          ?????? </session-config>

          ?

          ?????? <!-- 歡迎頁面 -->

          ?????? <welcome-file-list>

          ????????????? <welcome-file>index.jsp</welcome-file>

          ?????? </welcome-file-list>

          ??????

          </web-app>

          5.2. 加載 spring 監聽

             在 web.xml 文件中加入如下配置:

          <!-- 設置環境變量,將 web 應用根目錄存儲到環境變量中 -->

          <context-param>

          ??? <param-name>webAppRootKey</param-name>

          ??? <param-value>webapp.root</param-value>

          </context-param>?

          ?

          <!-- 設置環境變量指定 applicationContext.xml 配置文件 -->

          <context-param>

          ??? <param-name>contextConfigLocation</param-name>

          ??? <param-value>

          ??????? /WEB-INF/applicationContext.xml

          ??????? /WEB-INF/applicationContext-admin.xml

          ??????? /WEB-INF/applicationContext-quartz.xml

          ??? </param-value>

          </context-param>???

          ?

          <!-- 設置 context 的監聽,啟動時加載 applicationContext.xml 文件,初始化 applicationContext 實例 -->

          <listener>

          ??? <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

          </listener>

          5.3. Log4j 日志

             首先,在 web.xml 文件中加入如下配置:

          <!-- 設置環境變量指定 log4j 的配置文件 -->

          <context-param>

          ??? <param-name>log4jConfigLocation</param-name>

          ??? <param-value>/WEB-INF/log4j.properties</param-value>

          </context-param>

          ?

          <!-- 設置 log4j 的監聽,使日志組件能夠使用,調用 log4jConfigLocation 中設置的環境變量 -->

          <listener>

          ??? <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

          </listener>

           log4j.properties 文件放在 /WEB-INF/ 目錄下, 文件內容如下例,其中根日志級別為 warn ,而在包 cn.idtag 中的類的日志級別為 info

          # 定義根日志的級別和輸出路徑 fatal, error, warn, info, debug

          log4j.rootCategory=warn, stdout, logfile

          ?

          # 在包 cn.idtag 中的類的日志級別

          log4j.logger.cn.idtag=info

          ?

          # 日志輸出參數

          #%c: 日志信息所在類名

          #%d: 日志信息產生時間

          #%p: 日志信息級別

          #%m: 產生的日志具體信息

          #%n: 輸出日志信息換行

          log4j.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] %c%n%m%n%n

          ?

          # 控制臺輸出

          log4j.appender.stdout=org.apache.log4j.ConsoleAppender

          log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

          log4j.appender.stdout.layout.ConversionPattern=${log4j.ConversionPattern}

          ?

          # 日志文件輸出

          log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender

          log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/log.txt

          log4j.appender.logfile.Append = true

          log4j.appender.logfile.layout=org.apache.log4j.PatternLayout

          log4j.appender.logfile.layout.ConversionPattern=${log4j.ConversionPattern}

          5.4. 解決中文亂碼

           在 web.xml 文件中加入如下配置,可以解決表單提交的編碼,不需要在每個 *.jsp *.htm 等頁面上編寫代碼“ <%@ page contentType="text/html; charset=gbk" language="java"%> ”了,并且為瀏覽器端設置的“ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ”代碼也不需要寫了,瀏覽器會自動識別,注意建立文件時一定要使用 UTF-8 字符集。

          <!-- 設置字符串過濾器,解決表單 Post 提交中的亂碼問題 -->

          <filter>

          ??? <filter-name>characterEncoding</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>

          ??? <init-param>

          ??????? <param-name>forceEncoding</param-name>

          ??????? <param-value>true</param-value>

          ??? </init-param>

          </filter>

          <filter-mapping>

          ??? <filter-name>characterEncoding</filter-name>

          ??? <url-pattern>/*</url-pattern>

          </filter-mapping>

          ?

          <!-- 設置 jsp,htm,html 頁面的字符集,是否使用標簽,是否使用 jsp 腳本等,頭尾載入頁面等 -->

          <jsp-config>

          ??? <jsp-property-group>

          ??????? <description> 指定 JSP 文件的配置屬性 </description>

          ??????? <display-name>jspConfiguration</display-name>

          ??????? <url-pattern>*.jsp</url-pattern>

          ??????? <el-ignored>false</el-ignored>

          ??????? <page-encoding>utf-8</page-encoding>

          ??????? <scripting-invalid>false</scripting-invalid>

          ??????? <include-prelude></include-prelude>

          ??????? <include-coda></include-coda>

          ??? </jsp-property-group>

          ?

          ??? <jsp-property-group>

          ??????? <description> 指定 htm 文件的配置屬性 </description>

          ??????? <display-name>jspConfiguration</display-name>

          ??????? <url-pattern>*.htm</url-pattern>

          ??????? <el-ignored>false</el-ignored>

          ??????? <page-encoding>utf-8</page-encoding>

          ??????? <scripting-invalid>false</scripting-invalid>

          ??????? <include-prelude></include-prelude>

          ??????? <include-coda></include-coda>

          ??? </jsp-property-group>

          ?

          ??? <jsp-property-group>

          ??????? <description> 指定 html 文件的配置屬性 </description>

          ??????? <display-name>jspConfiguration</display-name>

          ??????? <url-pattern>*.html</url-pattern>

          ??????? <el-ignored>false</el-ignored>

          ??????? <page-encoding>utf-8</page-encoding>

          ??????? <scripting-invalid>false</scripting-invalid>

          ??????? <include-prelude></include-prelude>

          ??????? <include-coda></include-coda>

          ??? </jsp-property-group>

          ?

          </jsp-config>

           如果應用服務器是 Tomcat ,編輯 Tomcat 根目錄下的“ /conf/server.xml ”文件,找到 Connector 配置部分,在配置結尾加入“ URIEncoding="utf-8" ”:

          <Connector port="8080" maxThreads="150" …… disableUploadTimeout="true"/>

          改為:

          <Connector port="8080" maxThreads="150" …… disableUploadTimeout="true" URIEncoding="UTF-8"/>

           可解決系統內部 GET 方法傳遞中文字符參數的亂碼問題,但是在外部 URL 請求中參數值帶有中文的,必須使用 URLEncode 編碼。

          5.5. 配置 servlet

           在 web.xml 文件中配置 servlet 請求路徑和實現類:

          <servlet>

          ??? <servlet-name>sendSms</servlet-name>

          ??? <servlet-class>cn.idtag.test.servlet.SendSmsServlet</servlet-class>

          </servlet>

          <servlet-mapping>

          ??? <servlet-name>sendSms</servlet-name>

          ??? <url-pattern>/servlet/sendsms</url-pattern>

          </servlet-mapping>

           而 SendSmsServlet.java 文件需要繼承 HttpServlet 類,如果 response 要輸出內容并包含非英文字符,要設置輸出的字符集為 UTF-8

          package cn.idtag.test.servlet;

          ?

          import javax.servlet.http.HttpServletRequest;

          import javax.servlet.http.HttpServletResponse;

          import javax.servlet.http.HttpServlet;

          import javax.servlet.ServletException;

          import java.io.IOException;

          ?

          public class SendSmsServlet extends HttpServlet

          {

          ??? public void doGet(HttpServletRequest request, HttpServletResponse response)

          ??????????? throws ServletException, IOException

          {

          ??????? response.setContentType("text/html;charset=utf-8");

          ??????? PrintWriter out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "utf-8"));

          ??????? try

          ??????? {

          ??????? //do something…

          ??????? } finally

          ??????? {

          ??????????? out.close();

          ??????? }

          ??? }

          ?

          ??? public void doPost(HttpServletRequest request, HttpServletResponse response)

          ??????????? throws ServletException, IOException

          ?? ?{

          ??????? doGet(request, response);

          ??? }

          }


          6. Spring 配置

          6.1. 視圖配置

          配置 Spring 環境公共設置的 applicationContext.xml 文件放在 /WEB-INF/ 目錄下, 首先定義視圖類型為 Jstl ,并約定 JSP 文件的默認保存路徑,配置異常捕獲處理 Bean ,當系統發生異常時,自動重新定向到 error.jsp 文件顯示異常內容。

          <?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:aop="http://www.springframework.org/schema/aop"

          ?????? xmlns:tx="http://www.springframework.org/schema/tx"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

          ?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

          ?????????? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

          ?

          ??? <!-- 返回的視圖資源的前綴和后綴,基于 Jstl 模板 -->

          ??? <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

          ??????? <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

          ?????? ?<property name="prefix" value="/WEB-INF/jsp/"/>

          ??? </bean>

          ?

          ??? <!-- 啟動加載異常處理的類,用于監聽各模塊中觸發的異常 -->

          ??? <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

          ??????? <property name="defaultErrorView" value="error.jsp"/>

          ??? </bean>

          </beans>

          6.2. 數據庫連接

          applicationContext.xml 文件中加入下面配置,首先加載數據庫配置文件 jdbc.properties ,然后配置數據源,此處使用的是 TOMCAT 自帶的數據庫連接池實現,其實就是 Apache DBCP 連接池的重新封裝。

          <!-- 加載 properties 配置文件 -->

          <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

          ??? <property name="locations">

          ??????? <list>

          ??????????? <value>/WEB-INF/jdbc.properties</value>

          ??????? </list>

          ??? </property>

          </bean>

          ?

          <!-- 數據源 -->

          <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close">

          ??? <property name="driverClassName" value="${jdbc.driverClassName}"/>

          ??? <property name="url" value="${jdbc.url}"/>

          ??? <property name="username" value="${jdbc.username}"/>

          ??? <property name="password" value="${jdbc.password}"/>

          </bean>

            jdbc.properties 文件在 /WEB-INF/ 目錄下:

          jdbc.driverClassName=oracle.jdbc.OracleDriver

          jdbc.url=jdbc:oracle:thin:@localhost:1521:oradb

          jdbc.username=demo

          jdbc.password=123456

          6.3. 數據庫事務

          applicationContext.xml 文件中加入下面配置,數據庫事務管理,采用的是 AOP 代理,對所有文件名稱以 Logic 結尾的接口類進行事務代理。在接口類中,方法名稱以 insert update 等開頭的采用事務管理,設置 Propagation REQUIRED 表示支持當前事務,如果當前沒有事務,就新建一個事務;而其他的方法以 * 表示,設置 Propagation SUPPORTS 表示支持當前事務,如果當前沒有事務就以非事務方式執行, read-Only true 表示對應事務被最優化為只讀事務。

          <!-- 事務管理器 -->

          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

          ??? <property name="dataSource" ref="dataSource"/>

          </bean>

          ?

          <!--aop 代理,對所有以 Logic 為后綴文件名的接口類進行代理 -->

          <aop:config>

          ??? <aop:advisor pointcut="execution(* *..*Logic.*(..))" advice-ref="txAdvice"/>

          </aop:config>

          ?

          <!-- 數據庫事務代理,對類中的指定前綴的方法進行事務控制 -->

          <tx:advice id="txAdvice">

          ??? <tx:attributes>

          ??????? <tx:method name="insert*" propagation="REQUIRED"/>

          ??????? <tx:method name="update*" propagation="REQUIRED"/>

          ??????? <tx:method name="delete*" propagation="REQUIRED"/>

          ??????? <tx:method name="upload*" propagation="REQUIRED"/>

          ??????? <tx:method name="*" propagation="SUPPORTS" read-only="true"/>

          ??? </tx:attributes>

          </tx:advice>


          pointcut 的語法說明如下:

          execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

          ?? 除了返回類型模式、名字模式和參數模式以外,所有的部分都是可選的;

          ?? 返回類型模式( ret-type-pattern )決定了方法的返回類型必須依次匹配一個連接點,返回類型模式 * 代表了匹配任意的返回類型;

          ?? 名字模式( name-pattern )匹配的是方法名,可以使用 * 通配符作為所有或者部分命名模式;

          ?? 參數模式( param-pattern )稍微有點復雜, () 匹配了一個不接受任何參數的方法,而 (..) 匹配了一個接受任意數量參數的方法(零或者更多),模式 (*) 匹配了一個接受一個任何類型的參數的方法,模式 (*,String) 匹配了一個接受兩個參數的方法,第一個可以是任意類型,第二個則必須是 String 類型。

          ?

          下面給出一些常見切入點表達式的例子。

          ?? 任意公共方法的執行: execution(public * *(..))

          ?? 任何一個以“ set ”開始的方法的執行: execution(* set*(..))

          ?? AccountService 接口的任意方法的執行: execution(* com.xyz.service.AccountService.*(..))

          ?? 定義在 service 包里的任意方法的執行: execution(* com.xyz.service.*.*(..))

          ?? 定義在 service 包或者子包里的任意方法的執行: execution(* com.xyz.service..*.*(..))

          ?

          表達式 execution(* *..BookManager.save(..)) 的解讀:

          ?? 第一顆 * 代表 ret-type-pattern 返回值可任意;

          ?? *..BookManager 代表任意 Pacakge 里的 BookManager 類,如果寫成 com.xyz.service.* 則代表 com.xyz.service 下的任意類, com.xyz.service..* com.xyz.service 則代表 com.xyz.service 及其子 package 下的任意類;

          ?? save 代表 save 方法,也可以寫 save* 代表 saveBook() 等方法;

          ?? (..) 匹配 0 個參數或者多個參數的,任意類型, (x,..) 第一個參數的類型必須是 X (x,,,s,..) 匹配至少 4 個參數,第一個參數必須是 x 類型,第二個和第三個參數可以任意,第四個必須是 s 類型。

          6.4. 控制器配置

          控制器的配置文件為 servlet-xxx.xml xxx URI 請求的擴展名,此文件可以在 web.xml 中配置,如果不配置, spring 默認查找的是 xxx-servlet.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"

          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

          ?

          ??? <import resource="applicationContext.xml"/>

          ?

          ??? <bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

          ?

          ??? <bean name="/mainpage.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">

          ??????? <property name="viewName" value="mainpage.jsp"/>

          ??? </bean>

          ?

          ??? <!-- 無攔截請求 -->

          ??? <bean id="noInterceptors" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

          ??????? <property name="mappings">

          ??????????? <props>

          ??????????????? <prop key="login.do">doController</prop>

          ??????????? </props>

          ??????? </property>

          ??? </bean>

          ?

          ??? <!-- 有攔截請求 -->

          ??? <bean id="hasInterceptors" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

          ??????? <property name="interceptors">

          ??????????? <list>

          ??????????????? <ref bean="authInterceptor"/>

          ??????????? </list>

          ??????? </property>

          ??????? <property name="mappings">

          ??????????? <props>

          ??????????????? <prop key="enter.do">doController</prop>

          ??????????????? <prop key="logout.do">doController</prop>

          ??????????? </props>

          ??????? </property>

          ??? </bean>

          ?

          ??? <!-- 請求與方法映射控制器 -->

          ??? <bean id="doController" class="com.fyyk.core.LogicController">

          ??????? <property name="logicClass" ref="doLogic"/>

          ??????? <property name="uriMethodMapping">

          ??????????? <props>

          ??????????????? <prop key="login">login</prop>

          ??????????????? <prop key="enter">enter</prop>

          ??????????????? <prop key="logout">logout</prop>

          ??????????? </props>

          ??????? </property>

          ??? </bean>

          ?

          </beans>

          6.5. 邏輯類配置

          邏輯類的配置文件為 applicationContext-xxx.xml ,此文件可以在 web.xml 中配置,如 applicationContext-admin.xml 文件,也可以配置合并在 applicationContext.xml 中:

          ??? <bean id="authInterceptor" class="com.fyyk.interceptor.AuthInterceptor">

          ??????? <property name="noLoginRedirect" value="/WEB-INF/jsp/noLogin.jsp"/>

          ??? </bean>

          ?

          ??? <bean id="doLogic" class="com.fyyk.logic.DoLogicImpl">

          ??????? <property name="dataSource" ref="dataSource"/>

          ??? </bean>

          7. 開發工作要做什么

          一般說來,完成一個操作流程的全部開發需要完成以下工作:


          1.??
          配置 servlet-xxx.xml 文件,加入 URI 請求的控制器 Bean 、邏輯類及方法;


          2.??
          配置 applicaionContext-xxx.xml 文件,加入響應 URI 請求的邏輯類 Bean 定義;


          3.??
          建立邏輯類文件接口類文件,加入響應 URI 請求的方法,并實現該類和方法,在方法體中完成具體的業務代碼,如果需要操作數據庫,則實現類需要繼承 JdbcDaoSupport 類;


          4.??
          建立 .jsp 文件,輸出請求結果;



            點此下載演示代碼


            接下來會有一些應用范例程序介紹給大家。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 石屏县| 德惠市| 抚州市| 安福县| 天津市| 多伦县| 鄱阳县| 韶关市| 陕西省| 台北县| 二连浩特市| 潢川县| 宁河县| 北京市| 防城港市| 名山县| 广宗县| 仁化县| 肃南| 莲花县| 攀枝花市| 启东市| 腾冲县| 三门县| 页游| 砀山县| 宜良县| 田林县| 台南县| 杭锦后旗| 鲁山县| 博罗县| 红原县| 瑞丽市| 罗江县| 龙胜| 靖边县| 兴业县| 北碚区| 滕州市| 阳曲县|