使用 Commons-attributes-compiler一定要注意其中 在Meta-Info中的数据,因此,要注意他的版本
posted @
2007-09-07 13:53 华梦行 阅读(137) |
评论 (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 华梦行 阅读(154) |
评论 (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 华梦行 阅读(425) |
评论 (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 华梦行 阅读(191) |
评论 (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 华梦行 阅读(649) |
评论 (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 华梦行 阅读(428) |
评论 (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 华梦行 阅读(171) |
评论 (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 华梦行 阅读(183) |
评论 (0) |
编辑 收藏
http://www.mediafire.com/index.php
posted @
2007-08-31 13:56 华梦行 阅读(83) |
评论 (0) |
编辑 收藏
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<!--
- 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 华梦行 阅读(479) |
评论 (0) |
编辑 收藏
数组只有length属性
Locale.getAvailableLocales().length
posted @
2007-08-30 18:18 华梦行 阅读(195) |
评论 (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 华梦行 阅读(1931) |
评论 (0) |
编辑 收藏
控制器的概念是MVC设计模式的一部分(确切地说,是MVC中的C)。应用程序的行为通常被定义为服务接口,而控制器使得用户可以访问应用所提供的服务。控制器解析用户输入,并将其转换成合理的模型数据,从而可以进一步由视图展示给用户。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 华梦行 阅读(2312) |
评论 (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 华梦行 阅读(174) |
评论 (0) |
编辑 收藏
jtds jdbc驱动
posted @
2007-08-30 10:19 华梦行 阅读(180) |
评论 (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 华梦行 阅读(637) |
评论 (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 华梦行 阅读(2766) |
评论 (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 华梦行 阅读(247) |
评论 (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 华梦行 阅读(686) |
评论 (0) |
编辑 收藏
select * from v$version
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
posted @
2007-08-29 11:33 华梦行 阅读(578) |
评论 (0) |
编辑 收藏