使用 Commons-attributes-compiler一定要注意其中 在Meta-Info中的數據,因此,要注意他的版本
posted @
2007-09-07 13:53 華夢行 閱讀(142) |
評論 (0) |
編輯 收藏
文章: 49 積分: 89 來自: 浙江杭州

|
?????? 時間: 2007-02-09 14:38 ?? 關鍵字: ? Spring?spring
|
??? ??? |
|
1、使用JdbcTemplate的execute()方法執行SQL語句
代碼
-
jdbcTemplate.execute(
"CREATE?TABLE?USER?(user_id?integer,?name?varchar(100))"
);??
2、如果是UPDATE或INSERT,可以用update()方法。
代碼 - jdbcTemplate.update("INSERT?INTO?USER?VALUES('"??
- ???????????+?user.getId()?+?"',?'"??
- ???????????+?user.getName()?+?"',?'"??
- ???????????+?user.getSex()?+?"',?'"??
- ???????????+?user.getAge()?+?"')"); ??
3、帶參數的更新
代碼 - jdbcTemplate.update("UPDATE?USER?SET?name?=???WHERE?user_id?=??",?new?Object[]?{name,?id});??
代碼 - jdbcTemplate.update("INSERT?INTO?USER?VALUES(?,??,??,??)",?new?Object[]?{user.getId(),?user.getName(),?user.getSex(),?user.getAge()}); ??
4、使用JdbcTemplate進行查詢時,使用queryForXXX()等方法
代碼 - int?count?=?jdbcTemplate.queryForInt("SELECT?COUNT(*)?FROM?USER");??
代碼 - String?name?=?(String)?jdbcTemplate.queryForObject("SELECT?name?FROM?USER?WHERE?user_id?=??",?new?Object[]?{id},?java.lang.String.class);??
代碼 - List?rows?=?jdbcTemplate.queryForList("SELECT?*?FROM?USER");??
代碼 - List?rows?=?jdbcTemplate.queryForList("SELECT?*?FROM?USER"); ??
- Iterator?it?=?rows.iterator(); ??
- while(it.hasNext())?{ ??
- ????Map?userMap?=?(Map)?it.next(); ??
- ????System.out.print(userMap.get("user_id")?+?"\t"); ??
- ????System.out.print(userMap.get("name")?+?"\t"); ??
- ????System.out.print(userMap.get("sex")?+?"\t"); ??
- ????System.out.println(userMap.get("age")?+?"\t"); ??
- } ??
JdbcTemplate將我們使用的JDBC的流程封裝起來,包括了異常的捕捉、SQL的執行、查詢結果的轉換等等。spring大量使用Template Method模式來封裝固定流程的動作,XXXTemplate等類別都是基于這種方式的實現。 除了大量使用Template Method來封裝一些底層的操作細節,spring也大量使用callback方式類回調相關類別的方法以提供JDBC相關類別的功能,使傳統的JDBC的使用者也能清楚了解spring所提供的相關封裝類別方法的使用。 JDBC的PreparedStatement
代碼 - final?String?id?=?user.getId(); ??
- final?String?name?=?user.getName(); ??
- final?String?sex?=?user.getSex()?+?""; ??
- final?int?age?=?user.getAge(); ??
- ??
- jdbcTemplate.update("INSERT?INTO?USER?VALUES(?,??,??,??)", ??
- ?????????????????????new?PreparedStatementSetter()?{ ??
- ?????????????????????????public?void?setValues(PreparedStatement?ps)?throws?SQLException?{ ??
- ?????????????????????????????ps.setString(1,?id); ??
- ?????????????????????????????ps.setString(2,?name);?????????? ??
- ?????????????????????????????ps.setString(3,?sex); ??
- ?????????????????????????????ps.setInt(4,?age); ??
- ?????????????????????????} ??
- ?????????????????????}); ??
- ??
代碼 - final?User?user?=?new?User(); ??
- jdbcTemplate.query("SELECT?*?FROM?USER?WHERE?user_id?=??", ??
- ????????????????????new?Object[]?{id}, ??
- ????????????????????new?RowCallbackHandler()?{ ??
- ????????????????????????public?void?processRow(ResultSet?rs)?throws?SQLException?{ ??
- ????????????????????????????user.setId(rs.getString("user_id")); ??
- ????????????????????????????user.setName(rs.getString("name")); ??
- ????????????????????????????user.setSex(rs.getString("sex").charAt(0)); ??
- ????????????????????????????user.setAge(rs.getInt("age")); ??
- ????????????????????????} ??
- ????????????????????}); ??
- ??
代碼 - class?UserRowMapper?implements?RowMapper?{ ??
- ????public?Object?mapRow(ResultSet?rs,?int?index)?throws?SQLException?{ ??
- ????????User?user?=?new?User(); ??
- ??
- ????????user.setId(rs.getString("user_id")); ??
- ????????user.setName(rs.getString("name")); ??
- ????????user.setSex(rs.getString("sex").charAt(0)); ??
- ????????user.setAge(rs.getInt("age")); ??
- ??
- ????????return?user; ??
- ????} ??
- } ??
- ??
- public?List?findAllByRowMapperResultReader()?{ ??
- ????String?sql?=?"SELECT?*?FROM?USER"; ??
- ????return?jdbcTemplate.query(sql,?new?RowMapperResultReader(new?UserRowMapper())); ??
- } ??
- ??
在getUser(id)里面使用UserRowMapper
代碼 - public?User?getUser(final?String?id)?throws?DataAccessException?{ ??
- ????String?sql?=?"SELECT?*?FROM?USER?WHERE?user_id=?"; ??
- ????final?Object[]?params?=?new?Object[]?{?id?}; ??
- ????List?list?=?jdbcTemplate.query(sql,?params,?new?RowMapperResultReader(new?UserRowMapper())); ??
- ??
- ????return?(User)?list.get(0); ??
- } ??
網上收集 org.springframework.jdbc.core.PreparedStatementCreator 返回預編譯SQL 不能于Object[]一起用
代碼 - public?PreparedStatement?createPreparedStatement(Connection?con)?throws?SQLException?{ ??
- ?return?con.prepareStatement(sql); ??
- } ??
1.增刪改 org.springframework.jdbc.core.JdbcTemplate 類(必須指定數據源dataSource)
代碼 - template.update("insert?into?web_person?values(?,?,?)",Object[]); ??
或
代碼 - template.update("insert?into?web_person?values(?,?,?)",new?PreparedStatementSetter(){?匿名內部類?只能訪問外部最終局部變量 ??
- ??
- ?public?void?setValues(PreparedStatement?ps)?throws?SQLException?{ ??
- ??ps.setInt(index++,3); ??
- }); ??
org.springframework.jdbc.core.PreparedStatementSetter 接口 處理預編譯SQL
代碼 - public?void?setValues(PreparedStatement?ps)?throws?SQLException?{ ??
- ?ps.setInt(index++,3); ??
- } ??
2.查詢JdbcTemplate.query(String,[Object[]/PreparedStatementSetter],RowMapper/RowCallbackHandler) org.springframework.jdbc.core.RowMapper 記錄映射接口 處理結果集
代碼 - public?Object?mapRow(ResultSet?rs,?int?arg1)?throws?SQLException?{???int表當前行數 ??
- ??person.setId(rs.getInt("id")); ??
- } ??
- List?template.query("select?*?from?web_person?where?id=?",Object[],RowMapper); ??
org.springframework.jdbc.core.RowCallbackHandler 記錄回調管理器接口 處理結果集
代碼 - template.query("select?*?from?web_person?where?id=?",Object[],new?RowCallbackHandler(){ ??
- ?public?void?processRow(ResultSet?rs)?throws?SQLException?{ ??
- ??person.setId(rs.getInt("id")); ??
- }); ??
|
|
|
posted @
2007-09-06 18:04 華夢行 閱讀(158) |
評論 (0) |
編輯 收藏
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
??<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
??<property name="username" value="sa" />
??<property name="password" value="" />
??<property name="url" value="jdbc:hsqldb:hsql://localhost:9001" />
?</bean>
?
?<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
??<property name="dataSource" ref="dataSource"></property>
?</bean>
ListableBeanFactory cbf = new ClassPathXmlApplicationContext("ac1.xml");
??JdbcTemplate jt = (JdbcTemplate) cbf.getBean("jdbcTemplate");??
??List rsList = jt.queryForList("select * from pets");
??//////////////////// 首先取得list
??for(Iterator iterator = rsList.iterator();iterator.hasNext() ;){
//////////////////////////////將所有的list迭代出來
???System.out.println(iterator.next());
??}??
- List?rows?=?jdbcTemplate.queryForList("SELECT?*?FROM?USER"); ??
- Iterator?it?=?rows.iterator(); ??
- while(it.hasNext())?{ ??
- ????Map?userMap?=?(Map)?it.next(); ??
- ????System.out.print(userMap.get("user_id")?+?"\t"); ??
- ????System.out.print(userMap.get("name")?+?"\t"); ??
- ????System.out.print(userMap.get("sex")?+?"\t"); ??
- ????System.out.println(userMap.get("age")?+?"\t"); ??
- }
posted @
2007-09-06 17:50 華夢行 閱讀(435) |
評論 (0) |
編輯 收藏
select? getdate()? 返回當前時間
Oracle????? 所有的日期函數都沒有()
select Sysdate from dual
2007-9-6 11:27:25
?select sessiontimezone,current_timestamp from dual;
?+08:00
?? 2007-9-6 11:27:25.234000 +08:00
?select sessiontimezone,current_timestamp? ,current_date ,sysdate from dual;
posted @
2007-09-06 11:36 華夢行 閱讀(203) |
評論 (0) |
編輯 收藏
昨天在論壇看到一篇討論嵌入式數據庫HSQLDB(http://www.javaeye.com/topic/79802)的帖子,想到自己曾經讀過部分它的源碼,有一種對某些技術豁然開朗的感覺。所以,也希望和朋友們一起分享,大家有什么好的感受,不如也分享一下吧。下面是我對那個帖子的冗余回復,我覺得有必要專門發一篇帖子重復一下:
說點題外話,建議大家讀讀HSQLDB的源碼,特別是jdbc driver(org/hsqldb/jdbc包)那部分,寫得清晰易懂。讀了它的部分源碼,我自認為對下面一些問題理解深入了:
1、JDBC規范和JDBC實現的關系:怎么自己去設計一個規范,一種架構?我是否自己可以為某種數據設計jdbc driver,如何設計?想想php里面各數據庫的函數庫各自為政對程序移植性的影響,就知道jdbc規范有多么重要了。
2、JDBC協議:JDBC是基于socket之上的,數據包格式(org.hsqldb.Result)(mysql數據包格式公開了)?那么JMS數據包呢?其實,這也可以延伸到分布式協議的設計原理,如RMI、SOAP。其實,這些數據包格式和JSON、YAML這些message格式沒有本質的區別,只不過應用范圍不一樣。任何分布式協議,肯定有一種message格式。
3、JDBC over HTTP:這樣我們對RMI over IIOP, soap over HTTP, http tunnel原理有更深入的理解。
4、什么是long connection(jdbc的socket),什么是short connection(http),具體怎么實現?
3和4這些在HSQLDB的org.hsqldb.HTTPClientConnection類里有實現。
5、Java客戶端和服務器端的通訊實現:jdbc driver就可以認為是一個java客戶端類庫。那么JMS client呢?還有,像mysql有各種語言的driver,原理是什么。
6、sql這種command、描述型語言究竟在數據庫里面是個什么地位:sql是怎么傳入jdbc driver,最終和database交互的?我們是否可以設計出另外一種command,形成一種行業標準,它在服務器和客戶端怎么實現的。
以上我的表達可能有些晦澀,我只想表達一點:大家有興趣就多讀讀經典的源碼,擴展一下自己的設計思路??赡芎芏嗳讼笪乙粯?,總有忙不完的項目,那么抽幾個小時就夠了,不必深入。
有很多技術我們理解總是很模糊,當你深入到內部,忽然發現原來就這么回事。我們總覺得IoC很神秘,其實最簡單的IoC容器,也許一個HashMap就夠了。
引用的http://www.javaeye.com/topic/80532
posted @
2007-09-06 10:21 華夢行 閱讀(668) |
評論 (0) |
編輯 收藏
//通過MessageSourceResolvable接口獲得message_zh_CN.properties中的消息
??MessageSourceResolvable msr = new DefaultMessageSourceResolvable(new String[]{"welcome"},
????new Object[]{"默認MessageSourceResolvable實現"});
??System.out.println(aac.getMessage(msr, Locale.CHINA));
?
posted @
2007-09-05 16:43 華夢行 閱讀(446) |
評論 (0) |
編輯 收藏
? Sql 語法規則
@intCount??INT Output??,
@chvKeywords??????????? VARCHAR(100),??????????? --關鍵字
?@dtmdatelowerlimit?????????????? DATETIME ,
@dtmdateupperlimit????????????? DATETIME ,
@bitViewPersonalLimit??BIT,??--瀏覽個人
ORACLE 語法規則
chvOrgTypeID ?IN VARCHAR2? DEFAULT NULL,
chCreatorName ?IN VARCHAR2? DEFAULT NULL,
tempCount??? in out????????? integer,---輸入輸出
posted @
2007-09-03 16:48 華夢行 閱讀(185) |
評論 (0) |
編輯 收藏
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS OFF
GO
?
ALTER???????????? PROCEDURE spITM_CheckPaperList(
@intCount??INT Output??,
@chvKeywords??????????? VARCHAR(100),??????????? --關鍵字
@chvinterunittypeid???????????? varchar(100),
?@dtmdatelowerlimit?????????????? DATETIME ,
@dtmdateupperlimit????????????? DATETIME ,
@isspecialbuy???????????? int,
@checkresultid??????????? int,
? @intAudit???????????????????????? INT,??????????????????????????????? --審批狀態
@chvEmployeeTypeID?VARCHAR(100)?,??--職員id
@bitViewPersonalLimit??BIT,??--瀏覽個人
@bitViewDepartmentLimit?BIT,??--瀏覽部門
@bitEmployeeIsManager??BIT,??--瀏覽全部
?? @chvOrgTypeID??????????? VARCHAR(100),?
@intPageSize??INT??,
@intPageNo??INT??
)
AS
--權限控制條件開始
DECLARE @chvEmployeeDepartment??VARCHAR(36)
DECLARE @bitEmployeeIsAdmin??BIT
SELECT @chvEmployeeDepartment = '000'
IF EXISTS(SELECT TypeID FROM CRM_Employee WHERE TypeID = @chvEmployeeTypeID)
?AND
?EXISTS(SELECT Count(*) FROM CRM_LoginUser WHERE InnerObject = 'Employee' AND InnerObjectTypeID = @chvEmployeeTypeID)
BEGIN
?--SELECT @chvEmployeeDepartment = [Department] FROM [CRM_Employee] WHERE [TypeID] = @chvEmployeeTypeID
?SELECT @bitEmployeeIsAdmin = IsAdmin FROM CRM_LoginUser WHERE InnerObject = 'Employee' AND InnerObjectTypeID = @chvEmployeeTypeID
?--deal? empty 2007/1/22
?SELECT @chvEmployeeDepartment = case @chvEmployeeDepartment when ' ' then? '000' else? @chvEmployeeDepartment end
END
ELSE
BEGIN
?SELECT * FROM ITM_CheckPaper? WHERE TypeID = '0'?--返回一個空的記錄集
?RETURN
END
--權限控制條件結束--
select a.*? ,b.Name VendorName,? ww.Name CheckPaperName,
w.Name CreatorName
??INTO #ITM_CheckPaperListPageTable
?? from ITM_CheckPaper as? a?
???????????? left JOIN CRM_Employee w????? ON a.CreatorTypeID = w.TypeID
?????? left join CRM_Employee ww on a.CHECKERTYPEID=ww.Typeid
??LEFT JOIN scm_Vendor b ON a.VendorTypeID = b.TypeID
WHERE
?a.OrgTypeID = @chvOrgTypeID and
(
?a.SERIALNUMBER???? like '%'+@chvKeywords+'%' or
?a.ContractNo???????????????? like '%'+@chvKeywords+'%' or
b.Name???????????????? like '%'+@chvKeywords+'%' or
?a.CheckSite???? like '%'+@chvKeywords+'%'
)
--and
--a.AuditFlag = case @intAudit
? ---??????????????????????? when 0 then a.AuditFlag
? --?????????????????????? else @intAudit
? --??????????????????? end
--權限控制條件開始--
AND
(
?@bitViewDepartmentLimit = 1
?AND
?(
?ISNULL(w.[Department],'001') LIKE ISNULL(@chvEmployeeDepartment,'not the same') + '%'
?OR
?ISNULL(w.[Department2],'001') LIKE ISNULL(@chvEmployeeDepartment,'not the same') + '%'
?OR
?ISNULL(w.[Department3],'001') LIKE? ISNULL(@chvEmployeeDepartment,'not the same') + '%'
?)
?OR
?a.[CreatorTypeID] = @chvEmployeeTypeID? AND? @bitViewPersonalLimit = 1
?OR
?@bitEmployeeIsAdmin = 1
?OR
?@bitEmployeeIsManager = 1
?OR
?a.[EmployeeRange] LIKE '%' +@chvEmployeeTypeID +'%'
)
--權限控制條件結束--
--Order by a.CreateDate desc
---------------判斷是否取記錄數
if @intCount = 1
Begin
?SELECT @intCount=Count(0)
?FROM #ITM_CheckPaperListPageTable;
End
--------------------------取記錄數完成
DECLARE @chvSql??VARCHAR(1000)
--處理大于總頁數時的請求頁數
DECLARE @intPageCount?INT
SELECT @intPageCount = (@intCount + @intPageSize-1) / @intPageSize;
IF @intPageNo > 1 AND @intPageNo > @intPageCount
?SELECT @intPageNo = @intPageCount
ELSE IF @intPageNo > @intPageCount
?SELECT @intPageNo = 1
--處理大于總頁數時的請求頁數結束
Select @chvSql = 'SELECT TOP ' + Str(@intPageSize) + '? *? ' +
' FROM #ITM_CheckPaperListPageTable a ' +
' WHERE a.TypeID not in ' +
' (select top ' + Str((@intPageNo - 1) * @intPageSize) + ' TypeID from #ITM_CheckPaperListPageTable )'
Exec(@chvSql)
Drop Table #ITM_CheckPaperListPageTable
?
?
?
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
?
posted @
2007-09-03 14:39 華夢行 閱讀(199) |
評論 (0) |
編輯 收藏
http://www.mediafire.com/index.php
posted @
2007-08-31 13:56 華夢行 閱讀(86) |
評論 (0) |
編輯 收藏
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "
<!--
? - DispatcherServlet application context for the Countries web tier.
? -->
<beans>
?<!-- ========================= MAPPING DEFINITIONS ========================= -->
?<!--
??- Explicit view mappings in bundle instead of default InternalResourceViewResolver.
?? - Fetches the view mappings from localized "views_xx" classpath files, i.e.
?? - "/WEB-INF/classes/views-countries.properties" or "/WEB-INF/classes/views-countries_fr.properties".
?? -
?? - Symbolic view names returned by controllers will be resolved in the respective
?? - properties file, allowing for arbitrary mappings between names and resources.
?? -
?? - We use the "defaultParentView" property. All views defined will by default inherit
??- the properties defined in the "modelView" view.
?? -->
?<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
??<property name="basename" value="views-countries"/>
??<property name="defaultParentView" value="modelView"/>
?</bean>
?<!--
??- We specify here that Locale and theme are stored in cookies.
?? - They could be stored in a Session. Default resolvers don't allow changing them on the fly.
??-->
?<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
?<bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
??<property name="defaultThemeName" value="spring"/>
?</bean>
?<!--
??????? 路徑映射
? - Explicit URL handler mapping instead of default BeanNameUrlHandlerMapping.
? -->
?<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
??<property name="interceptors">
???<list>
????<ref bean="localeChangeInterceptor"/>
????<ref bean="themeChangeInterceptor"/>
???</list>
??</property>
??<property name="mappings">
???<props><--? 當請求發送過來時,自動交給相應的控制器,讓控制器來處理相應的邏輯和渲染相應的視圖? -->
????<prop key="/home.htm">countriesController</prop>
????<prop key="/config.htm">countriesController</prop>
????<prop key="/copy.htm">countriesController</prop>
????<prop key="/main/home.htm">countriesController</prop>
????<prop key="/main/detail.htm">countriesController</prop>
????<prop key="/main/countries.xls">countriesController</prop>
????<prop key="/main/countries.pdf">countriesController</prop>
????<prop key="/notfound.htm">errorsController</prop>
???</props>
??</property>
?</bean>
?<!-- ========================= CONTROLLER DEFINITIONS ========================= -->
?<!--
??- Interceptors will pre-handle any request in this servlet, no matter which controller
??- is mapped for a request.
??-
??- We use two built-in interceptors to detect user locale or theme change requests.
??- The third interceptor is specific to this Demo. It allows views to easily be aware
??- about the configuration detected. Precisely to know if a copy data to database can be
??- proposed to the user.
?-->
?<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
?<bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
?<!-- General use multi-action controller for errors -->
?<bean id="errorsController" class="org.springframework.samples.countries.web.ErrorsController">
??<property name="methodNameResolver">
???<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
????<property name="mappings">
?????<props>
??????<prop key="/notfound.htm">handleHttp404</prop>
?????</props>
????</property>
???</bean>
??</property>
?</bean>
?<!-- Application specific multi-action controller??? 由于好多頁面調用同一個控制器,因此要區分不同的頁面,以調用繼承multi-action 的不同的方法
???????? 而這個任務就交給MethodNameResulver來解決-->
?<bean id="countriesController" class="org.springframework.samples.countries.web.CountriesController">
??<property name="methodNameResolver">
???<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
????<property name="mappings">
?????<props>
??????<prop key="/home.htm">handleHome</prop>
??????<prop key="/config.htm">handleConfig</prop>
??????<prop key="/copy.htm">handleCopy</prop>
??????<prop key="/main/home.htm">handleMain</prop>
??????<prop key="/main/detail.htm">handleDetail</prop>
??????<prop key="/main/countries.xls">handleExcel</prop>
??????<prop key="/main/countries.pdf">handlePdf</prop>
?????</props>
????</property>
???</bean>
??</property>
??<property name="countryService" ref="countryService"/>
?</bean>
</beans>
posted @
2007-08-30 18:34 華夢行 閱讀(480) |
評論 (0) |
編輯 收藏
數組只有length屬性
Locale.getAvailableLocales().length
posted @
2007-08-30 18:18 華夢行 閱讀(201) |
評論 (0) |
編輯 收藏
Spring提供了MethodNameResolver的三種方式:
1 : ParameterMethodNameResolver,這個可以根據請求的參數來確定一個需要調用的方法。
例如,http://www.sf.net/index.view?testParam=testIt,這個請求會調用名稱為testIt的處理方法。
2 : InternalPathMethodNameResolver,這個可以根據請求的路徑名稱來調用相應的方法。
例如,http://www.sf.net/testing.view,這個請求會調用testing方法。
3 : PropertiesMethodNameResolver,這個可以根據一個URLs 映射列表來調用相應的方法。
例如,如果定義了/index/welcome.html=doIt,那么當請求為/index/welcome.html時,會調用doIt方法。在定義URLs時可以使用通配符。/**/welcom?.html
posted @
2007-08-30 15:21 華夢行 閱讀(1941) |
評論 (0) |
編輯 收藏
控制器的概念是MVC設計模式的一部分(確切地說,是MVC中的C)。應用程序的行為通常被定義為服務接口,而控制器使得用戶可以訪問應用所提供的服務??刂破鹘馕鲇脩糨斎耄⑵滢D換成合理的模型數據,從而可以進一步由視圖展示給用戶。Spring以一種抽象的方式實現了控制器概念,這樣使得不同類型的控制器可以被創建。Spring本身包含表單控制器、命令控制器、向導型控制器等多種多樣的控制器。
Spring控制器架構的基礎是org.springframework.mvc.Controller
接口,其代碼如下:
public interface Controller {
/**
* Process the request and return a ModelAndView object which the DispatcherServlet
* will render.
*/
ModelAndView handleRequest(
HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
你可以發現Controller
接口僅僅聲明了一個方法,它負責處理請求并返回合適的模型和視圖。Spring MVC實現的基礎就是這三個概念:Mdel、View(ModelAndView
)以及 Controller
。雖然Controller
接口是完全抽象的,但Spring也提供了許多你可能會用到的控制器。Controller接口僅僅定義了每個控制器都必須提供的基本功能:處理請求并返回一個模型和一個視圖。
13.3.1.?AbstractController
和 WebContentGenerator
為了提供一套基礎設施,所有的Spring控制器都繼承了 AbstractController
,AbstractController
提供了諸如緩存支持和mimetype設置這樣的功能。
表?13.3.?AbstractController
提供的功能
功能 |
描述 |
supportedMethods
|
指定這個控制器應該接受什么樣的請求方法。通常它被設置成同時支持GET和POST,但是你可以選擇你想支持的方法。如果控制器不支持請求發送的方法,客戶端會得到通知(通常是拋出一個ServletException )。 |
requiresSession
|
指定這個控制器是否需要HTTP session才能正常工作。如果控制器在沒有session的情況下接收到請求,客戶端會因為拋出ServletException 而得到通知。 |
synchronizeSession
|
指定controller是否同步用戶的HTTP session。 |
cacheSeconds
|
指定controller通知客戶端對數據內容緩存的秒數,一般為大于零的整數。默認值為-1,即不緩存。 |
useExpiresHeader
|
指定Controller在響應請求時是否兼容HTTP 1.0 Expires header。缺省值為true 。 |
useCacheHeader
|
指定Controller在相應請求時是否兼容HTTP 1.1 Cache-Control header。默認值為true 。 |
當從AbstractController
繼承時,需要實現handleRequestInternal(HttpServletRequest, HttpServletResponse)
抽象方法,該方法將用來實現自己的邏輯,并返回一個ModelAndView
對象。下面這個簡單的例子演示了如何從AbstractController
繼承以及如何在applicationContext.xml中進行配置
package samples;
public class SampleController extends AbstractController {
public ModelAndView handleRequestInternal(
HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("hello");
mav.addObject("message", "Hello World!");
return mav;
}
}
<bean id="sampleController" class="samples.SampleController">
<property name="cacheSeconds" value="120"/>
</bean>
該controller返回的ModelAndView使用了硬編碼的視圖名(盡管這樣做不好),并通知客戶端將響應數據緩存2分鐘。除了通過以上方式創建和配置controller之外,還需要配置handler mapping(請參考第?13.4?節 “處理器映射(handler mapping)”),這樣該controller就可以工作了。
盡管可以繼承AbstractController
來實現自己的控制器,不過Spring提供的眾多控制器減輕了我們開發簡單MVC應用時的負擔。ParameterizableViewController
基本上和上面例子中的一樣,不同的是,你可以在applicationContext.xml配置中指定返回視圖名從而避免了在Java代碼中的硬編碼。
UrlFilenameViewController
會檢查URL,獲取文件請求的文件名,并把它作為視圖名加以使用。。例如,http://www.springframework.org/index.html
對應的視圖文件名是index
。
13.3.3.?MultiActionController
MultiActionController
將多個行為(action)合并在一個控制器里,這樣可以把相關功能組合在一起。MultiActionController
位于org.springframework.web.mvc.multiaction
包中,它通過將請求映射到正確的方法名來調用方法。當在一個控制器存在大量公共的行為,但是有多個調用入口時,使用MultiActionController
就特別方便。
表?13.4.?MultiActionController
提供的功能
功能 |
描述 |
delegate
|
MultiActionController 有兩種使用方式。第一種是你繼承MultiActionController ,并在子類中指定由MethodNameResolver 解析的方法(這種情況下不需要這個delegate參數)。第二種是你定義一個代理對象,由它提供MethodNameResolver 解析出來的方法(這種情況下,你必須使用這個配置參數定義代理對象)。 |
methodNameResolver
|
MultiActionController 需要一種策略,使其可以通過解析請求信息來獲得要調用的方法。這個解析策略由MethodNameResolver 這個接口定義的。這個參數允許你實現MethodNameResolver 接口,然后在控制器中使用你的策略。 |
MultiActionController
所支持的方法需要符合下列格式:
// anyMeaningfulName can be replaced by any methodname
public [ModelAndView | Map | void] anyMeaningfulName(HttpServletRequest, HttpServletResponse [, Exception | AnyObject]);
注意:在此不允許方法重載,因為MultiActionController
無法分辨出重載(overloading)了的方法。此外,你可以定義exception handler來處理方法中拋出的異常。
Exception
參數是可選的,它可以是任何異常,只要它是java.lang.Exception
或java.lang.RuntimeException
的子類。AnyObject
參數也是可選的,它可以是任何對象。HTTP Request中的參數會存在這個對象中,以便使用。
下面幾個例子示范了MultiActionController
正確的方法定義。
標準格式(跟Controller
接口定義的一樣)。
public ModelAndView doRequest(HttpServletRequest, HttpServletResponse)
下面這個方法支持Login
參數, 這個參數中包含從請求中抽取出來的信息。
public ModelAndView doLogin(HttpServletRequest, HttpServletResponse, Login)
下面這個方法可以處理Exception
。
public ModelAndView processException(HttpServletRequest, HttpServletResponse, IllegalArgumentException)
下面這個方法不返回任何數值。 (請參考后面的章節 第?13.11?節 “慣例優先原則(convention over configuration)”)
public void goHome(HttpServletRequest, HttpServletResponse)
This signature has a Map
return type (see the section entitled 第?13.11?節 “慣例優先原則(convention over configuration)” below).
下面這個方法返回一個Map
。 (請參考后面的章節第?13.11?節 “慣例優先原則(convention over configuration)”)
public Map doRequest(HttpServletRequest, HttpServletResponse)
MethodNameResolver
負責從請求中解析出需要調用的方法名稱。下面是Spring中內置的三個MethodNameResolver
實現。
-
ParameterMethodNameResolver
- 解析請求參數,并將它作為方法名。(對應http://www.sf.net/index.view?testParam=testIt
的請求,會調用 testIt(HttpServletRequest,HttpServletResponse)
方法)。使用paramName
配置參數,可以設定要檢查的參數。
-
InternalPathMethodNameResolver
-從路徑中獲取文件名作為方法名 (http://www.sf.net/testing.view
的請求會調用testing(HttpServletRequest,HttpServletResponse)
方法。
-
PropertiesMethodNameResolver
- 使用用戶自定義的屬性對象,將請求的URL映射到方法名。當屬性中包含/index/welcome.html=doIt
時,發到/index/welcome.html
的請求會調用doIt(HttpServletRequest, HttpServletResponse)
這個方法。 這個方法名解析器可以和PathMatcher
一起工作,比如上邊那個URL寫成/**/welcom?.html
也是可以的。
我們來看一組例子。首先是一個使用ParameterMethodNameResolver
和代理(delegate)屬性的例子,它接受包含參數名"method"的請求,調用方法retrieveIndex
:
<bean id="paramResolver" class="org....mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="method"/>
</bean>
<bean id="paramMultiController" class="org....mvc.multiaction.MultiActionController">
<property name="methodNameResolver" ref="paramResolver"/>
<property name="delegate" ref="sampleDelegate"/>
</bean>
<bean id="sampleDelegate" class="samples.SampleDelegate"/>
## together with
public class SampleDelegate {
public ModelAndView retrieveIndex(HttpServletRequest req, HttpServletResponse resp) {
return new ModelAndView("index", "date", new Long(System.currentTimeMillis()));
}
}
當使用上面的代理對象時,我們也可以使用PropertiesMethodNameRseolver
來匹配一組URL,將它們映射到我們定義的方法上:
<bean id="propsResolver" class="org....mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<value>
/index/welcome.html=retrieveIndex
/**/notwelcome.html=retrieveIndex
/*/user?.html=retrieveIndex
</value>
</property>
</bean>
<bean id="paramMultiController" class="org....mvc.multiaction.MultiActionController">
<property name="methodNameResolver" ref="propsResolver"/>
<property name="delegate" ref="sampleDelegate"/>
</bean>
Spring的CommandController是Spring MVC的重要部分。命令控制器提供了一種和數據對象交互的方式,并動態地將來自HttpServletRequest
的參數綁定到你指定的數據對象上。它的功能和Struts中的ActionForm
有點像,不過在Spring中,你不需要實現任何接口來實現數據綁定。首先,讓我們看一下有哪些可以使用的命令控制器:
-
AbstractCommandController
--你可以使用該抽象命令控制器來創建自己的命令控制器,它能夠將請求參數綁定到你指定的命令對象。這個類并不提供任何表單功能,但是它提供驗證功能,并且讓你在子類中去實現如何處理由請求參數產生的命令對象。
-
AbstractFormController
--一個支持表單提交的抽象控制器類。使用這個控制器,你可以定義表單,并使用從控制器獲取的數據對象構建表單。當用戶輸入表單內容,AbstractFormController
將用戶輸入的內容綁定到命令對象,驗證表單內容,并將該對象交給控制器,完成相應的操作。它支持的功能有防止重復提交、表單驗證以及一般的表單處理流程。子類需要實現自己的方法來指定采用哪個視圖來顯示輸入表單,哪個視圖顯示表單正確提交后的結果。如果你需要表單,但不想在應用上下文中指定顯示給用戶的視圖,就使用這個控制器。
-
SimpleFormController
--這是一個form cotnroller,當需要根據命令對象來創建相應的form的時候,該類可以提供更多的支持。你可以為其指定一個命令對象,顯示表單的視圖名,當表單提交成功后顯示給用戶的視圖名等等。
-
AbstractWizardFormController
--這是一個抽象類,繼承這個類需要實現validatePage()
、processFinish()
和processCancel()
方法。
你有可能也需要寫一個構造器,它至少需要調用setPages()
和setCommandName()
方法。setPages()的參數是一個String數組,這個數組包含了組成向導的視圖名。setCommandName()的參數是一個String,該參數將用來在視圖中調用你的命令對象。
和AbstractFormController
的實現一樣, 你需要使用命令對象(其實就是一個JavaBean, 這個bean中包含了表單的信息)。你有兩個選擇:在構造函數中調用setCommandClass()
方法(參數是命令對象的類名),或者實現formBackingObject()
方法。
AbstractWizardFormController
有幾個你可以復寫(override)的方法。最有用的一個是referenceData(..)
。這個方法允許你把模型數據以Map
的格式傳遞給視圖;getTargetPage()
允許你動態地更改向導的頁面順序,或者直接跳過某些頁面;onBindAndValidate()
允許你復寫內置的綁定和驗證流程。
最后,我們有必要提一下setAllowDirtyBack()
和setAllowDirtyForward()
兩個方法。 你可以在getTargetPage()
中調用這兩個方法,這兩個方法將決定在當前頁面驗證失敗時,是否允許向導前移或后退。
AbstractWizardFormController
的更詳細內容請參考JavaDoc。在Spring附帶的例子jPetStore中,有一個關于向導實現的例子: org.springframework.samples.jpetstore.web.spring.OrderFormController
。
posted @
2007-08-30 12:32 華夢行 閱讀(2330) |
評論 (0) |
編輯 收藏
jar -cvf test.war *
即可在當前目錄下得到test.war
隨后可以把test.war上傳到服務器
在server.xml添加
<Context path="" docBase="PEP" debug="0" reloadable="false">
????<ResourceLink global="jdbc/PathPlat" name="jdbc/PathPlat" type="javax.sql.DataSource"/>
???</Context>
將這段代碼中的
<Context path="/manager" docBase="manager" debug="0" privileged="true"/>
拷貝一下并修改:path="" 為war路徑,docBase=""為你的war的文件名。
使用不帶任何的 jar 命令我們可以看到 jar 命令的用法如下:
jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目錄] 文件名 ...
其中 {ctxu} 是 jar 命令的子命令,每次 jar 命令只能包含 ctxu 中的一個,它們分別表示:
-c 創建新的 JAR 文件包
-t 列出 JAR 文件包的內容列表
-x 展開 JAR 文件包的指定文件或者所有文件
-u 更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中)
[vfm0M] 中的選項可以任選,也可以不選,它們是 jar 命令的選項參數
-v 生成詳細報告并打印到標準輸出
-f 指定 JAR 文件名,通常這個參數是必須的
-m 指定需要包含的 MANIFEST 清單文件
-0 只存儲,不壓縮,這樣產生的 JAR 文件包會比不用該參數產生的體積大,但速度更快
-M 不產生所有項的清單(MANIFEST〕文件,此參數會忽略 -m 參數
[jar-文件] 即需要生成、查看、更新或者解開的 JAR 文件包,它是 -f 參數的附屬參數
[manifest-文件] 即 MANIFEST 清單文件,它是 -m 參數的附屬參數
[-C 目錄] 表示轉到指定目錄下去執行這個 jar 命令的操作。它相當于先使用 cd 命令轉該目錄下再執行不帶 -C 參數的 jar 命令,它只能在創建和更新 JAR 文件包的時候可用。
posted @
2007-08-30 11:12 華夢行 閱讀(183) |
評論 (0) |
編輯 收藏
jtds jdbc驅動
posted @
2007-08-30 10:19 華夢行 閱讀(186) |
評論 (0) |
編輯 收藏
視圖解析器
就象和Spring集成的其他表現層技術一樣,對于JSP頁面你需要一個視圖解析器來解析。最常用的JSP視圖解析器是InternalResourceViewResolver和ResourceBundleViewResolver。它們被定義在WebApplicationContext里:
# The ResourceBundleViewResolver:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename"><value>views</value></property>
</bean>
# And a sample properties file is uses (views.properties in WEB-INF/classes):
welcome.class=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
productList.class=org.springframework.web.servlet.view.JstlView
productList.url=/WEB-INF/jsp/productlist.jsp
你可以看到ResourceBundleViewResolver需要一個屬性文件來把視圖名稱映射到 1)類和 2) URL。 通過ResolverBundleViewResolver,你可以用一個解析器來解析兩種類型的視圖。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
<property name="prefix"><value>/WEB-INF/jsp/</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>
InternalResourceBundleViewResolver可以配置成使用JSP頁面。作為好的實現方式,強烈推薦你將JSP文件放在WEB-INF下的一個目錄中,這樣客戶端就不會直接訪問到它們。
posted @
2007-08-30 10:01 華夢行 閱讀(648) |
評論 (0) |
編輯 收藏
摘要: <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/beans"??xmlns:xsd="http://www.w3.org/2001/XMLSchema"??targetNamespace="http:...
閱讀全文
posted @
2007-08-30 09:24 華夢行 閱讀(2775) |
評論 (0) |
編輯 收藏
關鍵字: Spring ? ????
Spring 2.0版本支持擴展XML配置,著實興奮了一下,在我看來,Spring作為目前最流行的框架,不能擴展用戶自定義的配置,實在是Spring的一個很不爽的地方,<bean />的方式用起來比較通用,起碼到目前為止符合大部分人的使用習慣,并且能完成Spring所有的配置操作,但是對于第三方的提供商或則會經常擴展Spring功能的開發者來說,使用<bean />這樣的配置方式或許不是他們最想要的,他們需要使組件的配置更加直觀、易閱讀、易擴展……試想使用下面的配置方式
代碼
-
<mytag:datasource?id=
"datasource"
? ??
-
???????databaseType=
"oracle"
? ??
-
???????ip=
"192.168.1.110"
? ??
-
???????port=
"1521"
? ??
-
???????databaseName=
"myDB"
??
-
???????userName=
"admin"
??
-
???????password=
"password"
??
-
???????/> ??
-
??
-
<mytag:ehCache?id=
"ehcache"
? ??
-
???????cache=
"true"
? ??
-
???????maxElements=
"100000"
? ??
-
???????timeToIdleSeconds=
"120"
? ??
-
???????timeToLiveSeconds=
"120"
??
-
???????overflowToDisk=
"true"
??
-
???????/> ??
上面的代碼中配置了兩個組件,datasource和cache組件,相比普通的bean&propertiy方式,很顯然,這種配置方式更直觀,更易讀,更重要的是,如果作為組件發布,使用者也可以很方便快捷的開始使用,而不需要關心組件的任何實現細節。
擴展XML配置大致需要一下幾個步驟 1、創建一個需要擴展的組件 2、定義一個xsd文件描述組件內容 3、創建一個文件,實現BeanDefinitionParser接口,用來解析xsd文件中的定義和組件定義 4、創建一個Handler文件,擴展自NamespaceHandlerSupport,目的是將組件注冊到Spring容器 5、編寫spring.handlers和spring.schemas文件 提供一個簡單的例子,來說明如何去擴展一個Spring配置,需求如下:使用自定義標簽定義一個簡單的bean,這個bean有一個或多個屬性,標簽定義完成后,可以在其他項目中用自定義標簽來定義該bean。 首先,創建一個需要擴展的組件,在這里只是一個簡單的bean,而且這個bean只有一個屬性age. One.java
代碼 - package?com.mysite.tag; ??
- ??
- public?class?One?{ ??
- ????private?String?age; ??
- ???? ??
- ????public?One(){ ??
- ???????? ??
- ????} ??
- ??
- ????public?String?getAge()?{ ??
- ????????return?age; ??
- ????} ??
- ??
- ????public?void?setAge(String?age)?{ ??
- ????????this.age?=?age; ??
- ????} ??
- } ??
然后,建立一個xsd文件,來描述這個bean mytag.xsd
代碼 - <?xml?version="1.0"?encoding="UTF-8"?>??
- <xsd:schema?xmlns="http://www.mysite.org/schema/mytag"??
- ????????xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
- ????????xmlns:beans="http://www.springframework.org/schema/beans"??
- ????????targetNamespace="http://www.mysite.org/schema/mytag"??
- ????????elementFormDefault="qualified"??
- ????????attributeFormDefault="unqualified">??
- ???? ??
- ????<xsd:import?namespace="http://www.springframework.org/schema/beans"/>??
- ???? ??
- ????<xsd:element?name="one">??
- ????????<xsd:complexType>??
- ????????????<xsd:complexContent>??
- ????????????????<xsd:extension?base="beans:identifiedType">??
- ????????????????????<xsd:attribute?name="age"?type="xsd:string"?default="99999"/>??
- ????????????????</xsd:extension>??
- ????????????</xsd:complexContent>??
- ????????</xsd:complexType>??
- ????</xsd:element>??
- </xsd:schema>??
在上面的xsd文件描述了一個新的targetNamespace,并在這個空間中定義了一個name為one的element,one有一個age屬性,類型為string,默認值為99999.xsd文件是xml DTD的替代者,使用XML Schema語言進行編寫,這里對xsd schema不做太多解釋,有興趣可以參考相關的資料。
創建一個Java文件,該文件實現了BeanDefinitionParser接口,用來解析xsd文件中的定義并注冊到組件中。 MyBeanDefinitionParser.java
代碼 - package?com.mysite.tag; ??
- ??
- import?org.springframework.beans.factory.config.BeanDefinition; ??
- import?org.springframework.beans.factory.config.BeanDefinitionHolder; ??
- import?org.springframework.beans.factory.support.BeanDefinitionReaderUtils; ??
- import?org.springframework.beans.factory.support.RootBeanDefinition; ??
- import?org.springframework.beans.factory.xml.BeanDefinitionParser; ??
- import?org.springframework.beans.factory.xml.ParserContext; ??
- import?org.w3c.dom.Element; ??
- ??
- public?class?MyBeanDefinitionParser?implements?BeanDefinitionParser{ ??
- ????public?BeanDefinition?parse(Element?arg0,?ParserContext?arg1)?{ ??
- ????????RootBeanDefinition?def?=?new?RootBeanDefinition(); ??
- ??????????????????
- ????????def.setBeanClass(One.class); ??
- ???????? ??
- ??????????????????
- ????????String?id?=?arg0.getAttribute("id"); ??
- ????????BeanDefinitionHolder?idHolder=?new?BeanDefinitionHolder(def,id); ??
- ????????BeanDefinitionReaderUtils.registerBeanDefinition(idHolder,?arg1.getRegistry()); ??
- ???????? ??
- ??????????????????
- ????????String?age?=?arg0.getAttribute("age"); ??
- ????????BeanDefinitionHolder?ageHolder=?new?BeanDefinitionHolder(def,age); ??
- ????????BeanDefinitionReaderUtils.registerBeanDefinition(ageHolder,?arg1.getRegistry()); ??
- ????????def.getPropertyValues().addPropertyValue("age",?age); ??
- ???????? ??
- ????????return?def; ??
- ????} ??
- } ??
- ??
上面的代碼僅僅實現了一個方法public BeanDefinition parse(Element arg0, ParserContext arg1),設置相關的Bean Class,解析了對應的xsd文件,并將解析的內容注冊到上下文中,同時返回一個BeanDefinition對象(BeanDefinition是Spring的bean定義,提供了bean部分的操作方法,如isSingleton()、isLazyInit()等)。
注意,id屬性是一個默認的屬性,可以不在xsd文件中描述,但是需要注冊它,否則將無法通過getBean方法獲取標簽定義的bean,也無法被其他bean引用。 另外,下面代碼是給bean的屬性賦值,這個是不可缺少的,否則在使用標簽定義時將無法獲取bean屬性的值。
代碼 - def.getPropertyValues().addPropertyValue("age",?age); ??
然后為組件編寫一個Handler文件,擴展自NamespaceHandlerSupport,它的作用是將組件注冊到Spring容器 MyNameSpaceHandler.java
代碼 - package?com.mysite.tag; ??
- ??
- import?org.springframework.beans.factory.xml.NamespaceHandlerSupport; ??
- ??
- public?class?MyNameSpaceHandler?extends?NamespaceHandlerSupport?{ ??
- ??
- ????public?void?init()?{ ??
- ?????????registerBeanDefinitionParser("one",new?MyBeanDefinitionParser()); ??
- ????} ??
- } ??
實際執行的過程只有一句代碼,注冊了一個名字為one的擴展配置,包含了MyBeanDefinitionParser所parser相關xsd的內容。
到了這里,一個Spring擴展標簽已經完成,但是我們目前還沒辦法使用它,Spring沒那么聰明,它無法知道我們在什么地方定義了哪些擴展標簽,這些標簽將被誰解析,這個過程要我們通過一些文件來告知Spring知道,它們就是spring.handlers和spring.schemas,它們放在META-INF目錄中,Spring.jar的META-INF目錄中也有同名的文件,它們的文件內容基本上是相似的,而Spring在執行過程中,如果發現其他jar文件的META-INF文件夾中包含有這兩個文件,Spring將會合并它們。 spring.schemas
代碼 spring.handlers
代碼 spring.schemas將告訴Spring配置文件知道,如果在配置中引用http://www.mysite.org/schema/mytag.xsd,它應該去什么地方找相應的xsd文件。 而spring.handlers文件將告訴Spring,應該使用哪個Handler注冊擴展標簽。 現在為止,一個完整的xml擴展標簽全部完成,做一個小應用測試一下。 將整個項目打包成jar文件(別忘記META-INF內的兩個文件),然后新建一個項目,引用剛才打包的jar文件,并引用Spring相關文件。 需要注意,自定義xml擴展配置只有xsd方式的引用才可以使用. application.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:tag="http://www.mysite.org/schema/mytag"??
- ????xsi:schemaLocation="http://www.springframework.org/schema/beans ??
- ????http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ??
- ????http://www.mysite.org/schema/mytag ??
- ????http://www.mysite.org/schema/mytag.xsd">??
- ??
- ????<tag:one?id="oneBean"?age="99"/>??
- </beans>??
在xml文件引用上可以看到,配置了一個名字為tag的名稱空間,目標為http://www.mysite.org/schema/mytag命名空間,這個目標名稱空間必須是存在于項目的引用中的(mytag.xsd中所定義的).
代碼 - <tag:one?id="oneBean"?age="99"/> ??
上面定義了一個id為oneBean的組件,使用了“one”擴展標簽,也就是我們在handler中所注冊的,組件age屬性的值為99。
Main.java
代碼 - package?com.test; ??
- ??
- import?org.springframework.context.ApplicationContext; ??
- import?org.springframework.context.support.ClassPathXmlApplicationContext; ??
- ??
- import?com.mysite.tag.One; ??
- ??
- public?class?Main?{ ??
- ??
- ????public?static?void?main(String[]?args)?{ ??
- ????????ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("application.xml"); ??
- ????????One?tag?=?(One)?ctx.getBean("oneBean"); ??
- ????????System.out.println("oneBean?age?is?"+tag.getAge()); ??
- ????} ??
- } ??
運行測試程序,結果如下
代碼 Spring的xml擴展是一個非常有用的特性,在Spring2.0的版本中也提供了一些新的標簽使用,如<aop>,<tx>等,但就目前來講受大家關注程度并不高,我想大部分使用Spring的開發人員都在使用Spring開發企業應用,而Spring所提供的<bean />定義的方式對于開發人員來說已經能夠滿足需要,但是如果看的更遠一些,在Spring以后的發展過程中,xml擴展應該會成為spring的核心特性之一,或許到時大家會習慣這樣的方式來編寫Spring配置文件吧
代碼 - <XXCompany:XXXModule?id=""> ??
- ... ??
- ... ??
|
最后更新:2007-07-18 16:03 15:42??|?? 永久鏈接??|?? 瀏覽?(481)??|?? 評論?(2)??| ?? 收藏??|?? 進入論壇??|?? |
|
posted @
2007-08-29 15:08 華夢行 閱讀(264) |
評論 (0) |
編輯 收藏
spring中dispatcherservlet的運行機制
dispatcherservlet是spring的web框架(以下簡稱springweb)中的核心servlet."spring的web框架——象其它web框架一樣——是一個請求驅動的web框架,其設計圍繞一個能將請求分發到控制器的servlet,它也提供其它功能幫助web應用開發。"----《spring framework 開發參考手冊(中文版)》而在springweb框架中這個servlet就是org.springframework.web.servlet.dispatcherservlet。這個servlet的繼承關系如下圖所示:springweb首先將傳統的httpservlet抽象類包裝成了bean;frameworkservlet抽象出了web框架中的servlets的一些基本行為,比如對application context的訪問;dispatcherservlet的主要工作就是將一個request分發到一個合適的處理器上,并將處理返回的modelandview繪制出來返回給客戶端。
dispatcherservlet作為一個servlet那他一定有兩個主要的方法:init()和doservice()。
一 init()初始化。dispatcherservlet繼承體系中init()方法的實現位于httpservletbean中,httpservletbean首先調用initbeanwrapper(),初始化beanwrapper,然后調用抽象方法initservletbean(),這個方法的實現位于他的子類frameworkservlet中;framewordservlet中的initservletbean()方法將調用initwebapplicationcontext(),初始化webapplicationcontext,然后同樣調用他的抽象方法initframeworkservlet(),而這個抽象方法的實現位于最終的dispatcherservlet中;dispatcherservlet中的initframeworkservet()將依次初始化multipar(用作文件上傳)解析器、本地化信息解析器、主題解析器處理器映射等等內容。所以dispatcherservlet的初始化順序為init();initbeanwrapper();
initservletbeaninitwebapplicationcontext()
initframework();initmultipartresolver();initlocaleresolver();initthemeresolver();inithandlermappings();inithandleradapters();inithandlerexceptionresolvers();initviewresolvers();
二 doservice()處理請求。dispatcherservlet中無論是通過post方式還是get方式提交的request,最終都會交由doservice()處理。doservice()中的處理邏輯大致分以下六個步驟:1.if(request是multipart,即文件上傳) 則將request解析并包裝成multiparthttpservletrequest2.mappedhandler = gethandler(request)根據request得到相應的處理器3.調用注冊的所有攔截器的prehandle方法4.調用處理器??? handleradapter ha = new gethandleradapter(mappedhandler.gethandler());??? modelandview mv = ha.handle(req, res, mappedhandler.gethandler())//這里使用了adapter模式5.調用注冊的所有攔截器的posthandle方法6.繪制mv
也許spring不像struts、hibernate那樣是使用最為廣泛的,但他是全面的、輕量級的、足夠靈活的、容易替換、容易擴展的。springweb是springframework中的一個部分,而dispatcherservlet又是springweb中的一小部分,要弄懂spring以及他背后的設計思想,對我等菜鳥而言,還是有很長一段路要走的。但愿在新的一條路出現之前,我們已經走遍了這條路。路漫漫其修遠兮,吾將上下而求索。繼續研究ing...to be continue...
posted @
2007-08-29 12:25 華夢行 閱讀(697) |
評論 (0) |
編輯 收藏
select * from v$version
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
posted @
2007-08-29 11:33 華夢行 閱讀(587) |
評論 (0) |
編輯 收藏