﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Exciting IN JAVA WAY-文章分类-Spring Dev</title><link>http://www.blogjava.net/cgogg/category/23080.html</link><description>Take Easy</description><language>zh-cn</language><lastBuildDate>Tue, 19 Jun 2007 21:45:13 GMT</lastBuildDate><pubDate>Tue, 19 Jun 2007 21:45:13 GMT</pubDate><ttl>60</ttl><item><title>Spring aop</title><link>http://www.blogjava.net/cgogg/articles/124987.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:06:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124987.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124987.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124987.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124987.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124987.html</trackback:ping><description><![CDATA[		AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序，通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。 <br>为了理解AOP如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将&#8220;不可见的&#8221;、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <br>Spring
framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP
framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP
framework，其他人还是象往常一样编程。 <br>AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模
块。这三个概念是：advice，pointcut和advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需
要注入advice的位置，通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器，是将advice注入
主程序中预定义位置的代码。 <br><br>既然我们知道了需要使用advisor向主要代码中注入&#8220;不可见的&#8221;advice，让我们实现一个
Spring AOP的例子。在这个例子中，我们将实现一个before
advice，这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码： <br><br>
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
    <tbody>
        <tr>
            <td><span class="genmed"><strong>代码:</strong></span></td>
        </tr>
        <tr>
            <td class="code">package com.company.springaop.test; <br><br>import java.lang.reflect.Method; <br>import org.springframework.aop.MethodBeforeAdvice; <br><br>public class TestBeforeAdvice implements MethodBeforeAdvice { <br><br>&nbsp; public void before(Method m, Object[] args, Object target) <br>&nbsp; throws Throwable { <br>&nbsp; &nbsp; System.out.println("Hello world! (by " <br>&nbsp; &nbsp; &nbsp; &nbsp; + this.getClass().getName() <br>&nbsp; &nbsp; &nbsp; &nbsp; + ")"); <br>&nbsp; } <br>} <br>&nbsp;</td>
        </tr>
    </tbody>
</table>
<span class="postbody"><br><br>接
口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当
丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[]
args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，
但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 <br><br>在下面的BeanImpl类中，每个public方法调用前，都会执行advice： <br><br></span>
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
    <tbody>
        <tr>
            <td><span class="genmed"><strong>代码:</strong></span></td>
        </tr>
        <tr>
            <td class="code">package com.company.springaop.test; <br><br>public class BeanImpl implements Bean { <br><br>&nbsp; public void theMethod() { <br>&nbsp; &nbsp; System.out.println(this.getClass().getName() <br>&nbsp; &nbsp; &nbsp; &nbsp; + "." + new Exception().getStackTrace()[0].getMethodName() <br>&nbsp; &nbsp; &nbsp; &nbsp; + "()" <br>&nbsp; &nbsp; &nbsp; &nbsp; + " says HELLO!"); <br>&nbsp; } <br>}</td>
        </tr>
    </tbody>
</table>
<span class="postbody"><br><br>类BeanImpl实现了下面的接口Bean： <br><br></span>
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
    <tbody>
        <tr>
            <td><span class="genmed"><strong>代码:</strong></span></td>
        </tr>
        <tr>
            <td class="code">package com.company.springaop.test; <br><br>public interface Bean { <br>&nbsp; public void theMethod(); <br>}</td>
        </tr>
    </tbody>
</table>
<span class="postbody"><br><br><br>虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 <br><br>pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： <br></span>
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
    <tbody>
        <tr>
            <td><span class="genmed"><strong>代码:</strong></span></td>
        </tr>
        <tr>
            <td class="code"><br><br>package com.company.springaop.test; <br><br>import org.springframework.context.ApplicationContext; <br>import org.springframework.context.support.FileSystemXmlApplicationContext; <br><br>public class Main { <br><br>&nbsp; public static void main(String[] args) { <br>&nbsp; &nbsp; //Read the configuration file <br>&nbsp; &nbsp; ApplicationContext ctx <br>&nbsp; &nbsp; &nbsp; &nbsp; = new FileSystemXmlApplicationContext("springconfig.xml"); <br><br>&nbsp; &nbsp; //Instantiate an object <br>&nbsp; &nbsp; Bean x = (Bean) ctx.getBean("bean"); <br><br>&nbsp; &nbsp; //Execute the public method of the bean (the test) <br>&nbsp; &nbsp; x.theMethod(); <br>&nbsp; } <br>}</td>
        </tr>
    </tbody>
</table>
<span class="postbody"><br><br><br>我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的&#8220;胶水&#8221;。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 <br><br>仅仅用配置文件便可把程序的每一部分组装起来。 <br></span>
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
    <tbody>
        <tr>
            <td><span class="genmed"><strong>代码:</strong></span></td>
        </tr>
        <tr>
            <td class="code"><br>&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br>&lt;!DOCTYPE beans PUBLIC&nbsp; "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; <br><br>&lt;beans&gt; <br>&nbsp; &lt;!--CONFIG--&gt; <br>&nbsp; &lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <br>&nbsp; &nbsp; &lt;property name="proxyInterfaces"&gt; <br>&nbsp; &nbsp; &nbsp; &lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <br>&nbsp; &nbsp; &lt;/property&gt; <br>&nbsp; &nbsp; &lt;property name="target"&gt; <br>&nbsp; &nbsp; &nbsp; &lt;ref local="beanTarget"/&gt; <br>&nbsp; &nbsp; &lt;/property&gt; <br>&nbsp; &nbsp; &lt;property name="interceptorNames"&gt; <br>&nbsp; &nbsp; &nbsp; &lt;list&gt; <br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;theAdvisor&lt;/value&gt; <br>&nbsp; &nbsp; &nbsp; &lt;/list&gt; <br>&nbsp; &nbsp; &lt;/property&gt; <br>&nbsp; &lt;/bean&gt; <br><br>&nbsp; &lt;!--CLASS--&gt; <br>&nbsp; &lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; <br><br>&nbsp; &lt;!--ADVISOR--&gt; <br>&nbsp; &lt;!--Note: An advisor assembles pointcut and advice--&gt; <br>&nbsp; &lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <br>&nbsp; &nbsp; &lt;property name="advice"&gt; <br>&nbsp; &nbsp; &nbsp; &lt;ref local="theBeforeAdvice"/&gt; <br>&nbsp; &nbsp; &lt;/property&gt; <br>&nbsp; &nbsp; &lt;property name="pattern"&gt; <br>&nbsp; &nbsp; &nbsp; &lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <br>&nbsp; &nbsp; &lt;/property&gt; <br>&nbsp; &lt;/bean&gt; <br><br>&nbsp; &lt;!--ADVICE--&gt; <br>&nbsp; &lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <br>&lt;/beans&gt; <br>&nbsp;</td>
        </tr>
    </tbody>
</table>
<span class="postbody"><br><br>四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor，一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 <br><br>BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这就是全部的工作。 <br><br>advisor
通过Spring
framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的
advice-bean。第二个属性则用正则表达式定义了pointcut，确保良好的性能和易读性。 <br><br>最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义： <br><br>
<ul><br>
    <li>属性proxyInterface定义了接口类。 <br></li>
    <li>属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 <br></li>
    <li>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意，advisor列表的次序是非常重要的。 <br></li>
</ul>
<br><br><span style="font-weight: bold;">Spring工具</span> <br><br>虽
然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring
framework的一部分，并改名为spring-ide），使用Spring
AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后，你只需在你的project上右击鼠
标，并选择&#8220;add Spring Project Nature&#8221;。在project属性中，你可以在&#8220;Spring
Project&#8221;下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons-
logging.jar，jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： <br><br>... (logging information) <br>Hello world! (by com.company.springaop.test.TestBeforeAdvice) <br>com.company.springaop.test.BeanImpl.theMethod() says HELLO! <br><br><br><span style="font-weight: bold;">优点和缺点</span> <br><br>Spring
比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。作为一个轻型framework，它在J2EE不同的部分都可以发挥
作用。因此，即使不想使用Spring
AOP，你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring
reference的第一页开始。读了本文后，你应该可以更好地理解Spring
reference了。Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档。</span><span class="gensmall"><br></span><img src ="http://www.blogjava.net/cgogg/aggbug/124987.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:06 <a href="http://www.blogjava.net/cgogg/articles/124987.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring例子JPetStore分析---------3jpetstore的各层之间的关系部分分析</title><link>http://www.blogjava.net/cgogg/articles/124985.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:05:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124985.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124985.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124985.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124985.html</trackback:ping><description><![CDATA[<p>下面就jpetstore的账号管理部分，来分析一下jpetstore的各层之间的关系：</p>
<p><strong>1。持久层分析</strong></p>
<p>1.1账号管理的iBatis的xml影射部分如下：</p>
<p>账号管理涉及到四张表：</p>
<p>signon 存放用户名，密码</p>
<p>account, 存放用户的基本信息</p>
<p>&nbsp;profile,&nbsp; 存放用户选择的语言，以及喜爱的商品分类</p>
<p>&nbsp;bannerdata 目前不清楚</p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>&lt;!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "<a  href="http://www.ibatis.com/dtd/sql-map-2.dtd">http://www.ibatis.com/dtd/sql-map-2.dtd</a>"&gt;</p>
<p>&lt;sqlMap namespace="Account"&gt;</p>
<p><strong>《账号信息结果集》</strong></p>
<p>&nbsp; &lt;resultMap id="result" class="org.springframework.samples.jpetstore.domain.Account"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="username" column="userid" columnIndex="1"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="email" column="email" columnIndex="2"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="firstName" column="firstname" columnIndex="3"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="lastName" column="lastname" columnIndex="4"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="status" column="status" columnIndex="5"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="address1" column="addr1" columnIndex="6"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="address2" column="addr2" columnIndex="7"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="city" column="city" columnIndex="8"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="state" column="state" columnIndex="9"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="zip" column="zip" columnIndex="10"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="country" column="country" columnIndex="11"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="phone" column="phone" columnIndex="12"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="languagePreference" column="langpref" columnIndex="13"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="favouriteCategoryId" column="favcategory" columnIndex="14"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="listOption" column="mylistopt" columnIndex="15"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="bannerOption" column="banneropt" columnIndex="16"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;result property="bannerName" column="bannername" columnIndex="17"/&gt;<br>&nbsp; &lt;/resultMap&gt;</p>
<p><strong>《根据用户名，获得用户信息》</strong></p>
<p>&nbsp; &lt;select id="getAccountByUsername" resultMap="result"&gt;<br>&nbsp;&nbsp;&nbsp; select<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signon.username as userid,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.email,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.firstname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.lastname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.status,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.addr1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.addr2,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.city,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.state,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.zip,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.country,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.phone,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.langpref,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.favcategory,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.mylistopt,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.banneropt,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bannerdata.bannername<br>&nbsp;&nbsp;&nbsp; from account, profile, signon, bannerdata<br>&nbsp;&nbsp;&nbsp; where account.userid = #value#<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and signon.username = account.userid<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and profile.userid = account.userid<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and profile.favcategory = bannerdata.favcategory<br>&nbsp; &lt;/select&gt;</p>
<p><strong>《根据账号，密码，获取账号》</strong></p>
<p>&nbsp; &lt;select id="getAccountByUsernameAndPassword" resultMap="result"&gt;<br>&nbsp;&nbsp;&nbsp; select<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signon.username as userid,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.email,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.firstname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.lastname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.status,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.addr1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.addr2,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.city,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.state,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.zip,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.country,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; account.phone,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.langpref,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.favcategory,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.mylistopt,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile.banneropt,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bannerdata.bannername<br>&nbsp;&nbsp;&nbsp; from account, profile, signon, bannerdata<br>&nbsp;&nbsp;&nbsp; where account.userid = #username#<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and signon.password = #password#<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and signon.username = account.userid<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and profile.userid = account.userid<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and profile.favcategory = bannerdata.favcategory<br>&nbsp; &lt;/select&gt;</p>
<p><strong>《获取系统用户名列表》</strong></p>
<p>&nbsp; &lt;select id="getUsernameList" resultClass="java.lang.String"&gt;<br>&nbsp;&nbsp;&nbsp; select username as value from signon<br>&nbsp; &lt;/select&gt;</p>
<p><strong>《更新账号信息》</strong></p>
<p>&nbsp; &lt;update id="updateAccount"&gt;<br>&nbsp;&nbsp;&nbsp;
update account set email = #email#, firstname = #firstName#, lastname =
#lastName#, status = #status#, addr1 = #address1#, addr2 =
#address2:varchar#, city = #city#, state = #state#, zip = #zip#,
country = #country#, phone = #phone# where userid = #username#<br>&nbsp; &lt;/update&gt;</p>
<p><strong>《增加新账号》</strong></p>
<p>&nbsp; &lt;insert id="insertAccount"&gt;<br>&nbsp;&nbsp;&nbsp;
insert into account (email, firstname, lastname, status, addr1, addr2,
city, state, zip, country, phone, userid) values (#email#, #firstName#,
#lastName#, #status#, #address1#, #address2:varchar#, #city#, #state#,
#zip#, #country#, #phone#, #username#)<br>&nbsp; &lt;/insert&gt;</p>
<p><strong>《更新用户profile表，其中包括用户语言选择，以及喜欢的动物分类</strong></p>
<p>&nbsp; &lt;update id="updateProfile"&gt;<br>&nbsp;&nbsp;&nbsp;
update profile set langpref = #languagePreference#, favcategory =
#favouriteCategoryId#, mylistopt = #listOptionAsInt#, banneropt =
#bannerOptionAsInt# where userid = #username#<br>&nbsp; &lt;/update&gt;</p>
<p><strong>《增加用户profile信息〉</strong></p>
<p>&nbsp; &lt;insert id="insertProfile"&gt;<br>&nbsp;&nbsp;&nbsp;
insert into profile (langpref, favcategory, mylistopt, banneropt,
userid) values (#languagePreference#, #favouriteCategoryId#,
#listOptionAsInt#, #bannerOptionAsInt#, #username#)<br>&nbsp; &lt;/insert&gt;</p>
<p><strong>〈更新用户密码〉</strong></p>
<p>&nbsp; &lt;update id="updateSignon"&gt;<br>&nbsp;&nbsp;&nbsp; update signon set password = #password# where username = #username#<br>&nbsp; &lt;/update&gt;</p>
<p>〈<strong>增加用户名，密码到用户登录表Signon〉</strong></p>
<p>&nbsp; &lt;insert id="insertSignon"&gt;<br>&nbsp;&nbsp;&nbsp; insert into signon (password,username) values (#password#,#username#)<br>&nbsp; &lt;/insert&gt;</p>
<p>&lt;/sqlMap&gt;<br><strong>1.2&nbsp; Account为账号管理的POJO类，AccountDao 为账号管理interface，规定了一系列方法：</strong></p>
<p>public interface AccountDao {</p>
<p>&nbsp; Account getAccount(String username) throws DataAccessException;</p>
<p>&nbsp; Account getAccount(String username, String password) throws DataAccessException;</p>
<p>&nbsp; void insertAccount(Account account) throws DataAccessException;</p>
<p>&nbsp; void updateAccount(Account account) throws DataAccessException;</p>
<p>&nbsp;List getUsernameList() throws DataAccessException;</p>
<p>}</p>
<p><strong>1.3Account interface 实现：</strong></p>
<p>public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao {</p>
<p>&nbsp; public Account getAccount(String username) throws DataAccessException {<br>&nbsp;&nbsp;&nbsp; return (Account) getSqlMapClientTemplate().queryForObject("getAccountByUsername", username);<br>&nbsp; }</p>
<p><strong>根据用户名，密码，获得账号</strong></p>
<p>&nbsp; public Account getAccount(String username, String password) throws DataAccessException {<br>&nbsp;&nbsp;&nbsp; Account account = new Account();<br>&nbsp;&nbsp;&nbsp; account.setUsername(username);<br>&nbsp;&nbsp;&nbsp; account.setPassword(password);<br>&nbsp;&nbsp;&nbsp; return (Account) getSqlMapClientTemplate().queryForObject("getAccountByUsernameAndPassword", account);<br>&nbsp; }</p>
<p><strong>创建账号，需要更新account,signon,profile三张表</strong></p>
<p>&nbsp; public void insertAccount(Account account) throws DataAccessException {<br>&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().insert("insertAccount", account);<br>&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().insert("insertProfile", account);<br>&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().insert("insertSignon", account);<br>&nbsp; }</p>
<p><strong>更新账号，需要更新account,signon,profile三张表</strong></p>
<p>&nbsp; public void updateAccount(Account account) throws DataAccessException {<br>&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().update("updateAccount", account, 1);<br>&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().update("updateProfile", account, 1);<br>&nbsp;&nbsp;&nbsp; if (account.getPassword() != null &amp;&amp; account.getPassword().length() &gt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getSqlMapClientTemplate().update("updateSignon", account, 1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</p>
<p><strong>《获取系统用户名列表》</strong><br>&nbsp;<br>&nbsp;public List getUsernameList() throws DataAccessException {<br>&nbsp;&nbsp;return getSqlMapClientTemplate().queryForList("getUsernameList", null);<br>&nbsp;}</p>
<p>}</p>
<p><strong>总结：</strong></p>
<p><strong>iBatiｓ持久层使用sql-map-config.xml配置所有ibatis&nbsp;.xml文件</strong></p>
<p>&lt;sqlMapConfig&gt;</p>
<p><strong>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Account.xml"/&gt;</strong><br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Category.xml"/&gt;<br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Product.xml"/&gt;<br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Item.xml"/&gt;<br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Order.xml"/&gt;<br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/LineItem.xml"/&gt;<br>&nbsp;&lt;sqlMap resource="org/springframework/samples/jpetstore/dao/ibatis/maps/Sequence.xml"/&gt;</p>
<p>&lt;/sqlMapConfig&gt;</p>
<p><strong>使用dataAccessContext-config.xml配置所有DAO实现</strong></p>
<p><strong>&lt;bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt;<br>&nbsp;&nbsp;&lt;property name="configLocation" value="WEB-INF/sql-map-config.xml"/&gt;<br>&nbsp;&nbsp;&lt;property name="dataSource" ref="dataSource"/&gt;<br>&nbsp;&lt;/bean&gt;</strong></p>
<p>&nbsp;<strong>&lt;bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao"&gt;<br>&nbsp;&nbsp;&lt;property name="sqlMapClient" ref="sqlMapClient"/&gt;<br>&nbsp;&lt;/bean&gt;</strong></p>
<p><strong>2，持久层和业务逻辑层的耦合，业务逻辑接口中包含了AccountDAO的接口操作</strong></p>
<p>public interface PetStoreFacade {</p>
<p>&nbsp;Account getAccount(String username);</p>
<p>&nbsp;Account getAccount(String username, String password);</p>
<p>&nbsp;void insertAccount(Account account);</p>
<p>&nbsp;void updateAccount(Account account);</p>
<p>&nbsp;List getUsernameList();</p>
<p>。。。。。。。</p>
<p>}<br><br><strong>业务逻辑对象PetStoreImpl 实现了对accountDao的再次封装</strong></p>
<p>public class PetStoreImpl implements PetStoreFacade, OrderService {</p>
<p>&nbsp;private AccountDao accountDao;</p>
<p>public Account getAccount(String username) {<br>&nbsp;&nbsp;return this.accountDao.getAccount(username);<br>&nbsp;}</p>
<p>&nbsp;public Account getAccount(String username, String password) {<br>&nbsp;&nbsp;return this.accountDao.getAccount(username, password);<br>&nbsp;}</p>
<p>&nbsp;public void insertAccount(Account account) {<br>&nbsp;&nbsp;this.accountDao.insertAccount(account);<br>&nbsp;}</p>
<p>&nbsp;public void updateAccount(Account account) {<br>&nbsp;&nbsp;this.accountDao.updateAccount(account);<br>&nbsp;}</p>
<p>&nbsp;public List getUsernameList() {<br>&nbsp;&nbsp;return this.accountDao.getUsernameList();<br>&nbsp;}</p>
<p>。。。。</p>
<p>}</p>
<p>总结：</p>
<p>持久层与业务逻辑层的耦合是在applicationContext.cml中：</p>
<p><strong>为业务逻辑层提供事务管理</strong></p>
<p><strong></strong><br><strong>&lt;bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"<br>&nbsp;&nbsp;&nbsp; abstract="true"&gt;<br>&nbsp;&nbsp;&lt;property name="transactionManager"&gt;&lt;ref bean="transactionManager"/&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="transactionAttributes"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="insert*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/props&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;</strong></p>
<p><strong>&nbsp;<br>&nbsp;&lt;bean id="petStore" parent="baseTransactionProxy"&gt;<br>&nbsp;&nbsp;&lt;property name="target"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;bean class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="accountDao" ref="accountDao"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="categoryDao" ref="categoryDao"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="productDao" ref="productDao"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="itemDao" ref="itemDao"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="orderDao" ref="orderDao"/&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br>&nbsp;&nbsp;&lt;/property&gt;</strong></p>
<p><strong>4表示层和业务逻辑层的耦合：</strong></p>
<p>表示层和业务逻辑层的耦合是通过BaseAction来实现的，并通过接口来访问业务逻辑对象：</p>
<p>public abstract class BaseAction extends Action {</p>
<p><strong>&nbsp; private PetStoreFacade petStore;</strong></p>
<p><strong>&nbsp;public void setServlet(ActionServlet actionServlet) {<br>&nbsp;&nbsp;super.setServlet(actionServlet);<br>&nbsp;&nbsp;if (actionServlet != null) {<br>&nbsp;&nbsp;&nbsp;ServletContext servletContext = actionServlet.getServletContext();<br>&nbsp;&nbsp;&nbsp;WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);<br>&nbsp;&nbsp;&nbsp;this.petStore = (PetStoreFacade) wac.getBean("petStore");<br>&nbsp;&nbsp;}<br>&nbsp;}</strong></p>
<p><strong>&nbsp;protected PetStoreFacade</strong> getPetStore() {<br>&nbsp;&nbsp;return petStore;<br>&nbsp;}</p>
<p>}</p>
<p>所有的系统里面的Action都是从BaseAction派生过来的，而BaseAction的派生类中，提供了对业务逻辑对象<br>&nbsp;<strong>PetStoreFacade 的访问。</strong></p><img src ="http://www.blogjava.net/cgogg/aggbug/124985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:05 <a href="http://www.blogjava.net/cgogg/articles/124985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分析和学习Spring中的jpetstore用户管理</title><link>http://www.blogjava.net/cgogg/articles/124986.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:05:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124986.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124986.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124986.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124986.html</trackback:ping><description><![CDATA[<a  href="http://blog.csdn.net/ylong/archive/2004/07/10/38486.aspx">分析和学习Spring中的jpetstore用户管理</a>
<div class="postText">
<p><font size="2">&nbsp; 存在用户的系统，必然需要用户的登录和认证，今天就通过分析Spring中自带的jpetstore的例子来学习一下如何实现在Spring构架的系统中用户登录。</font></p>
<p><font size="2">1、首先从注册用户开始，先看看jpetstore-servlet.xml中关于注册用户的bean定义，从定义命名中就可以看出下面这段就是注册用户的：<br><font color="#614db3">&nbsp; &lt;bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="petStore"&gt;&lt;ref bean="petStore"/&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="validator"&gt;&lt;ref bean="accountValidator"/&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="successView"&gt;&lt;value&gt;index&lt;/value&gt;&lt;/property&gt;<br>&nbsp; &lt;/bean&gt;<br></font>&nbsp;1). formView呢？从AccountFormController的构造函数中得到，原来为EditAccountForm；&nbsp; <br>&nbsp;2). EditoAccountForm.jsp中显得非常乱，其实没有多少难理解的地方，最主要的是这个form既是添加新用户的，又是编辑用户信息的，所以显得有点乱糟糟的。</font></p>
<p><font size="2">2、添加好了新用户，接下来看看如何登录，在jpetstore-servlet中发现这两个相关bean定义，如下：<br><font color="#614db3">&nbsp; &lt;bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="petStore"&gt;&lt;ref bean="petStore"/&gt;&lt;/property&gt;<br>&nbsp; &lt;/bean&gt;<br>&nbsp; &lt;bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="viewName"&gt;&lt;value&gt;SignonForm&lt;/value&gt;&lt;/property&gt;<br>&nbsp; &lt;/bean&gt;<br></font>&nbsp;1).
第二个bean是在运行时用户输入用户名和密码的form，叫做SignonForm，对于这个
ParameterizableViewController，用文档里的话说这是最简单的Controller，其作用就是在运行中指向
Controller而不是直接指向jsp文件，仅此而已。<br>&nbsp;2).
SignonForm.jsp，里面就是一个简单的form，其action就是第一个bean，即/shop/signon.do，最需要注意的是
signonForwardAction，其主要作用是forward到需要输入用户名和密码的那个页面上去，这个变量哪里来的呢？看看下面：<br>&nbsp;<font color="#614db3"> &lt;bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="interceptors"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="signonInterceptor"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp;&nbsp;&nbsp; &lt;property name="urlMap"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;map&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entry key="/shop/editAccount.do"&gt;&lt;ref local="secure_editAccount"/&gt;&lt;/entry&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entry key="/shop/listOrders.do"&gt;&lt;ref local="secure_listOrders"/&gt;&lt;/entry&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entry key="/shop/newOrder.do"&gt;&lt;ref local="secure_newOrder"/&gt;&lt;/entry&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;entry key="/shop/viewOrder.do"&gt;&lt;ref local="secure_viewOrder"/&gt;&lt;/entry&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/map&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br>&nbsp; &lt;/bean&gt;<br></font>&nbsp;
原来，上面的signonInterceptor实现了preHandle，因此在请求上面的map页面时，首先要经过这个Interceptor，看看
SignonInterceptor的源码，原来在其中为signon.jsp赋予一个signonForwardAction对象，呵呵，总算明白了。<br>&nbsp;3).
接下来去学习一下SignonController，其主体部分中可以看出，首先取出用户输入的username和password，然后到数据库中验证
有没有这个用户，如果没有这个用户，返回各错误页面；如果成功，首先生成一个UserSession对象，在request的session加入这个
userSession，注意这部分代码中给出了PagedListHolder分页的简单使用方法，关于分页显示，以后再学习吧。</font></p>
<p><font size="2">3、登录成功后，就可以根据不同的用户设施不同的行为了，取得用户信息，无非就是从session取出userSession即可。</font></p>
</div><img src ="http://www.blogjava.net/cgogg/aggbug/124986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:05 <a href="http://www.blogjava.net/cgogg/articles/124986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（六） aop</title><link>http://www.blogjava.net/cgogg/articles/124984.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:03:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124984.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124984.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124984.html</trackback:ping><description><![CDATA[<p>实践了《指南》中的例子165页到169页，最后补充一个Action，<br><font color="#008080">public class AOPMethodCostTimeAction extends ActionSupport {</font></p>
<p><font color="#008080">&nbsp;public ActionForward execute(ActionMapping mapping, ActionForm form,<br>&nbsp;&nbsp;&nbsp;HttpServletRequest request, HttpServletResponse response)<br>&nbsp;&nbsp;&nbsp;throws Exception {<br>&nbsp;&nbsp;WebApplicationContext wac = this.getWebApplicationContext();<br>&nbsp;&nbsp;ITest dao =(ITest)wac.getBean("myAOPProxyFactory");<br>&nbsp;&nbsp;dao.doTest();<br>&nbsp;&nbsp;dao.executeTest();<br>&nbsp;&nbsp;return mapping.findForward("success");<br>&nbsp;}</font></p>
<p><font color="#008080">}</font><br>具体代码已经放到gmail邮箱了。</p>
<p>仅仅从这个例子总结一下：</p>
<p>1，配置文件中需要<br><font color="#008080">&lt;!-- aop test--&gt;<br>&nbsp;&lt;bean id="<font color="#ff0000">myPointcutAdvisor</font>" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt;<br>&nbsp;&nbsp;&lt;property name="advice"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="MyInterceptor"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="patterns"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;.*do.*&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;.*execute.*&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;&lt;!-- user by PointcutAdvisor --&gt;<br>&nbsp;&lt;bean id="<font color="#ff0000">MyInterceptor</font>" class="srx.test.interceptor.MethodTimeCostInterceptor"&gt;&lt;/bean&gt;<br>&nbsp;&lt;!-- proxy factory user by Actoin --&gt;<br>&nbsp;&lt;bean id="<font color="#ff0000">myAOPProxyFactory</font>" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<br>&nbsp;&nbsp;&lt;property name="proxyInterfaces"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;srx.test.interfaces.ITest&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="target"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="test"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="interceptorNames"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;myPointcutAdvisor&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;&lt;!-- the dao bean be proxyed--&gt;<br>&nbsp;&lt;bean id="<font color="#ff0000">test</font>" class="srx.test.impl.test"&gt;&lt;/bean&gt;</font></p>
<p>&nbsp; </p>
<p>&nbsp;2，struts-config.xml</p>
<p><font color="#008080">&lt;!-- AOP test , this is a action call two function ,and pring every method proced cost time--&gt;<br>&nbsp;&nbsp;&lt;action path="/methodcost" type="srx.test.struts.action.AOPMethodCostTimeAction"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="success" path="/WEB-INF/jsp/srx/test/aop/success.jsp"/&gt;<br>&nbsp;&nbsp;&lt;/action&gt;</font></p>
<p><font color="#ff0000">使用动态代理，我本来有ITest接口，及其实现类test。以及使用test的Action。现在，我想测试test</font></p>
<p><font color="#ff0000">种方法的调用时间，我需要怎么做呢？</font></p>
<p><font color="#ff0000">我只需要多定义三个Bean，myPointcutAdvisor，MyInterceptor，myAOPProxyFactory。</font></p>
<p><font color="#ff0000">三者的依赖关系</font></p>
<p><font color="#008080">myAOPProxyFactory [ <font color="#ff0000">myPointcutAdvisor </font>[&nbsp; <font color="#0000ff">MyInterceptor &nbsp;</font>] ]<br><br></font>其中advice定义和具体的Spring advice类有关系。<br><br>待续。</p><img src ="http://www.blogjava.net/cgogg/aggbug/124984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:03 <a href="http://www.blogjava.net/cgogg/articles/124984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（五） 与hibernate整合 b</title><link>http://www.blogjava.net/cgogg/articles/124983.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:02:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124983.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124983.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124983.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124983.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124983.html</trackback:ping><description><![CDATA[常见问题及解决方案<br>
<p>现象1：<br><font color="#008080">org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.aop.support.DefaultPointcutAdvisor' defined in
null: Can't resolve reference to bean 'txAdvice' while setting property
'advice'; nested exception is</font> </p>
<p>原因：缺少Spring开头的各种包，到Spring2.0 src中编译新的dist目录出来，拷贝全部的springxxx.jar到jpetstore/WEB-INF/lib下。OK。<br><br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>现象2：<br><font color="#008080">org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in resource
[/WEB-INF/dataAccessContext-hibernate.xml] of ServletContext:
Instantiation of bean failed; nested exception is
java.lang.NoClassDefFoundError: javax/transaction/TransactionManager<br>java.lang.NoClassDefFoundError: javax/transaction/TransactionManager</font><br><br>原因：缺少jta.jar，OK</p>
<p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>现象3：</p>
<p><font color="#008080">java.lang.NoClassDefFoundError: org/dom4j/Attribute<br></font>缺dom4j.jar<br><font color="#008080">java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException</font><br>缺ehcache.jar<br><font color="#008080">java.lang.NoClassDefFoundError: net/sf/cglib/core/KeyFactory</font><br>缺cglib-full.jar<br></p>
<p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>现象4：<br><font color="#008080">org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in resource
[/WEB-INF/dataAccessContext-hibernate.xml] of ServletContext:
Initialization of bean failed; nested exception is
net.sf.hibernate.MappingException: could not instantiate id generator<br>net.sf.hibernate.MappingException: could not instantiate id generator</font><br></p>
<p>原因：<br>hbm中id字段的定义为没有定义的sequesce,修改为inc<br>&lt;id<br>&nbsp;&nbsp;&nbsp;name="id"<br>&nbsp;&nbsp;&nbsp;type="string"<br>&nbsp;&nbsp;&nbsp;column="userid"<br>&nbsp;&nbsp;&gt;<br>&nbsp;&nbsp;&nbsp;&lt;generator class="net.sf.hibernate.id.IncrementGenerator"/&gt; // 原来是sequence.<br>&nbsp;&nbsp;&lt;/id&gt;<br>这样就可以了。<br></p>
<p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>现象6：<br><font color="#008080">org.springframework.beans.factory.BeanCreationException:
Error creating bean with name '/shop/addItemToCart.do' defined in
ServletContext resource [/WEB-INF/petstore-servlet.xml]: Can't resolve
reference to bean 'petStore' while setting property 'petStore'; nested
exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'petStore' is defined<br>org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'petStore' is defined<br></font>原因：<br>我使用Struts作为action,当然就不需要使用Spring WEB framework,因此也不需要与之配套的配置文件例如,petstore-servlet.xml,<br>还有remote-servlet.xml ,但是Spring仍旧加载此两个文件，没办法，只好将此两个文件挪动到别的地方，但是又出现找不到这两个<br>文件的IO异常，没办法，只好又拷贝回来，然后把文件内容晴空。<br>终于好用了。<br>原
因就是，只要你在web.xml中定义了这个servlet，他就要去找此servlet名字对应的配置文件（servletname-
servlet.xml）,找不到就出错。ok，现在注释掉web.xml中名字为petstore的servlet定义和影色，删除petstore-
servlet.xml文件，哈哈，这下不报告错误了。<br>同理，注释名字为remote的servlet，删除remote-servlet.xml后，重新启动tomcat，这下不报告任何错误了。呵呵。原来如此啊。</p>
<p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>现象：<br><font color="#008080">java.lang.NullPointerException<br>&nbsp;srx.test.testhibernate.UserDAO.getAll(UserDAO.java:9)<br>&nbsp;srx.test.struts.action.UserAction.execute(UserAction.java:20)<br></font>原因：</p>
<p>Action原来<br>UserDAO // 这个类OK<br>public class UserDAO extends HibernateDaoSupport {<br>&nbsp;public List getAll() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.getHibernateTemplate().find("select aa from Account aa");<br>&nbsp;}<br>}</p>
<p>//这个类需要修改<br>public class UserAction extends ActionSupport {<br>&nbsp; UserDAO dao = new UserDAO(); <br>&nbsp;&nbsp;List accounts = dao.getAll();<br>。。。<br>}<br>修改：<br><font color="#ff0000">//UserDAO dao = new UserDAO(); <br></font><font color="#ff0000">WebApplicationContext wac = this.getWebApplicationContext();<br>&nbsp;&nbsp;UserDAO dao = (UserDAO) wac.getBean("userDAO");<br></font>OK</p>
<br>
<p>现象:<br>UserAction中修改:<br><font color="#008080">//UserDAO dao = (UserDAO) wac.getBean("userDAO");</font><br><font color="#ff0000">UserDAO dao = (UserDAO) wac.getBean("userDAOProxy"); </font><a><font color="#ff0000">//@1</font></a><br>配置文件中增加:<br><font color="#008080">&lt;bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;<br>&nbsp;&nbsp;&lt;property name="transactionManager"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="transactionManager"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="target"&gt;&lt;ref local="userDAO"/&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="transactionAttributes"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="insert*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="get*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/props&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&lt;/bean&gt;</font><br>这样运行时@1处抛出ClassCastException.<br>===================================================================================================<br>原因:<br>仔细看指南0.8版本145页所描述的事情.UserDAO虽然只继承了HibernateDAOSupport,看来没有事先任何接口,但是<br>HibernateDAOSupport实现了InitiralBean接口，所以UserDAO也相当于实现了这个接口。<br>因此本例按照实现了某个接口的DAO来处理，处理过程如下：<br>&nbsp;因为他实现了接口A，所以getBean得到一个实现了A的实例，并非继承UserDAO。所以用UserDAO转型会失败。<br>&nbsp;如果UserDAO没有实现接口A，那么getBean会得到一个UserDAO的子类实例，这时可以用UserDAO来转型。<br><font color="#ff0000">综上所诉，UserDAO必须实现IUserDAO接口,并且用IUserDAO转型才行.<br></font>&nbsp;因为UserDAO必须继承HibernateDAOSupport,所以没有办法不实现任何接口.</p>
<p>本问题和AOP有关。因为对AOP还不熟悉，所以需要看看。</p>
<br><br> <img src ="http://www.blogjava.net/cgogg/aggbug/124983.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:02 <a href="http://www.blogjava.net/cgogg/articles/124983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（五） 与hibernate整合 a</title><link>http://www.blogjava.net/cgogg/articles/124982.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:01:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124982.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124982.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124982.html</trackback:ping><description><![CDATA[<div>在学习这一部分的时候我作了一个用StrutsAction访问UserDAO中方法，此方法使用了hibernateTemplate。调试过程中问题多多，好在一个一个解决了。</div>
<div>JPetStore2.0
已经有ibatis做为OR层了，我要换成hibernate需要修改Spring配置文件中的bean
id="TransactionManager" 、增加bean
id=&#8220;sessionFactory&#8221;。又因为配置文件id=TransactionManager的bean只能有一个，修改为hibernate后
原来使用ibatis的bean就都不好用了，所以我新创建了一个空的配置文件dataAccessContext-hibernate.xml。只有几
个字定义的bean，如下：<br></div>
<div>
<table style="width: 449px; height: 1235px;" border="1" cellpadding="1" cellspacing="1" width="449">
    <tbody>
        <tr>
            <td>
            <p>&nbsp;<font color="#009999">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "</font><a  href="http://www.springframework.org/dtd/spring-beans.dtd"><font color="#009999">http://www.springframework.org/dtd/spring-beans.dtd</font></a><font color="#009999">"&gt;</font></p>
            <p><font color="#009999">&lt;beans&gt;</font></p>
            <p><font color="#009999">&nbsp;&lt;!-- ========================= RESOURCE DEFINITIONS ========================= --&gt;</font></p>
            <p><font color="#009999">&nbsp;&lt;!-- Local Apache Commons DBCP DataSource that refers to a combined database --&gt;<br>&nbsp;&lt;!-- (see dataAccessContext-jta.xml for an alternative) --&gt;<br>&nbsp;&lt;!-- The placeholders are resolved from jdbc.properties through --&gt;<br>&nbsp;&lt;!-- the PropertyPlaceholderConfigurer in applicationContext.xml --&gt;<br>&nbsp;&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;<br>&nbsp;&nbsp;&lt;property name="driverClassName"&gt;&lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="url"&gt;&lt;value&gt;jdbc:mysql://localhost:3306/jpetstore&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="username" &gt;&lt;value&gt;root&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="password" &gt;&lt;value&gt;123456&lt;/value&gt;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;<br>&nbsp;<br>&nbsp;&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"&gt;<br>&nbsp;&nbsp;&lt;property name="dataSource"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="dataSource"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="mappingResources"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;srx/test/hibernate/Account.hbm&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="hibernateProperties"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="hibernate.dialect"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.sf.hibernate.dialect.MySQLDialect<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="hibernate.showsql"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/props&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; &lt;!-- Transaction manager for a single JDBC DataSource --&gt;<br>&nbsp;&lt;!-- (see dataAccessContext-jta.xml for an alternative) --&gt;<br>&nbsp;&lt;bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"&gt;<br>&nbsp;&nbsp;&lt;property name="sessionFactory"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="sessionFactory"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;<br>&nbsp;<br>&nbsp;<br>&nbsp;&lt;!-- this bellow is hibernate configuration for srx test--&gt;<br>&nbsp;<br>&nbsp;<br>&nbsp;&lt;bean id="userDAO" class="srx.test.testhibernate.UserDAO"&gt;<br>&nbsp;&nbsp;&lt;property name="sessionFactory"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref local="sessionFactory"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&lt;/beans&gt;<br></font></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>原来包含很多复杂内容的applicationContext.xml也拷贝一份applicationContext2.xml，删除和JPetStore相关的内容，留下通用的部分：</p>
<p>
<table border="1" cellpadding="1" cellspacing="1" width="400">
    <tbody>
        <tr>
            <td>
            <p><font color="#006666">&nbsp;</font><font color="#339999">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</font></p>
            <p><font color="#339999">&lt;!--<br>&nbsp; - Application context definition for JPetStore's business layer.<br>&nbsp; - Contains bean references to the transaction manager and to the DAOs in<br>&nbsp; - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").<br>&nbsp; --&gt;<br>&lt;beans xmlns="</font><a  href="http://www.springframework.org/schema/beans"><font color="#339999">http://www.springframework.org/schema/beans</font></a><font color="#339999">"<br>&nbsp;&nbsp;&nbsp; xmlns:xsi="</font><a  href="http://www.w3.org/2001/XMLSchema-instance"><font color="#339999">http://www.w3.org/2001/XMLSchema-instance</font></a><font color="#339999">"<br>&nbsp;&nbsp;&nbsp; xmlns:aop="</font><a  href="http://www.springframework.org/schema/aop"><font color="#339999">http://www.springframework.org/schema/aop</font></a><font color="#339999">"<br>&nbsp;&nbsp;&nbsp; xmlns:tx="</font><a  href="http://www.springframework.org/schema/tx"><font color="#339999">http://www.springframework.org/schema/tx</font></a><font color="#339999">"<br>&nbsp;&nbsp;&nbsp; xsi:schemaLocation="</font><a  href="http://www.springframework.org/schema/beans"><font color="#339999">http://www.springframework.org/schema/beans</font></a><font color="#339999"> </font><a  href="http://www.springframework.org/schema/beans/spring-beans.xsd"><font color="#339999">http://www.springframework.org/schema/beans/spring-beans.xsd</font></a><br><font color="#339999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><a  href="http://www.springframework.org/schema/aop"><font color="#339999">http://www.springframework.org/schema/aop</font></a><font color="#339999"> </font><a  href="http://www.springframework.org/schema/aop/spring-aop.xsd"><font color="#339999">http://www.springframework.org/schema/aop/spring-aop.xsd</font></a><br><font color="#339999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><a  href="http://www.springframework.org/schema/tx"><font color="#339999">http://www.springframework.org/schema/tx</font></a><font color="#339999"> </font><a  href="http://www.springframework.org/schema/tx/spring-tx.xsd"><font color="#339999">http://www.springframework.org/schema/tx/spring-tx.xsd</font></a><font color="#339999">"&gt;</font></p>
            <p><font color="#339999">&nbsp;&lt;bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;<br>&nbsp;&nbsp;&lt;property name="locations"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;WEB-INF/mail.properties&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;WEB-INF/jdbc.properties&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;<br>&nbsp;&lt;aop:config&gt;<br>&nbsp;&nbsp;&lt;aop:advisor pointcut="execution(* *..PetStoreImpl.*(..))" advice-ref="txAdvice"/&gt;<br>&nbsp;&lt;/aop:config&gt;</font></p>
            <p><font color="#339999">&nbsp;&lt;!--<br>&nbsp;&nbsp;Transaction advice definition, based on method name patterns.<br>&nbsp;&nbsp;Defaults to PROPAGATION_REQUIRED for all methods whose name starts with<br>&nbsp;&nbsp;"insert" or "update", and to PROPAGATION_REQUIRED with read-only hint<br>&nbsp;&nbsp;for all other methods.<br>&nbsp;--&gt;<br>&nbsp;&lt;tx:advice id="txAdvice"&gt;<br>&nbsp;&nbsp;&lt;tx:attributes&gt;<br>&nbsp;&nbsp;&nbsp;&lt;tx:method name="insert*"/&gt;<br>&nbsp;&nbsp;&nbsp;&lt;tx:method name="update*"/&gt;<br>&nbsp;&nbsp;&nbsp;&lt;tx:method name="*" read-only="true"/&gt;<br>&nbsp;&nbsp;&lt;/tx:attributes&gt;<br>&nbsp;&lt;/tx:advice&gt;<br>&lt;/beans&gt;</font></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>在Struts配置文件中增加自己的Action如下：<br>
<table style="width: 498px; height: 116px;" border="1" cellpadding="1" cellspacing="1" width="498">
    <tbody>
        <tr>
            <td><font color="#339999">&nbsp;&lt;action path="/showusers" type="srx.test.struts.action.UserAction"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="success" path="/WEB-INF/jsp/srx/test/hibernate/showusers.jsp"/&gt;<br>&nbsp;&nbsp;&lt;/action&gt;<br></font>&nbsp;&nbsp;</td>
        </tr>
    </tbody>
</table>
</p>
<p>web.xml中使用action作为*。do处理的servlet而不是默认的petstore。<br>并注释掉名字为petstore,remoting的servlet。如下：</p>
<p><font color="#339999">&nbsp;&lt;web-app xmlns="</font><a  href="http://java.sun.com/xml/ns/j2ee"><font color="#339999">http://java.sun.com/xml/ns/j2ee</font></a><font color="#339999">" xmlns:xsi="</font><a  href="http://www.w3.org/2001/XMLSchema-instance"><font color="#339999">http://www.w3.org/2001/XMLSchema-instance</font></a><font color="#339999">" xsi:schemaLocation="</font><a  href="http://java.sun.com/xml/ns/j2ee"><font color="#339999">http://java.sun.com/xml/ns/j2ee</font></a><font color="#339999"> </font><a  href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><font color="#339999">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</font></a><font color="#339999">" version="2.4"&gt;</font></p>
<p><font color="#339999">&nbsp;&lt;display-name&gt;Spring JPetStore&lt;/display-name&gt;</font></p>
<p><font color="#339999">&nbsp;&lt;description&gt;Spring JPetStore sample application&lt;/description&gt;<br>&nbsp;<br>&nbsp;&lt;context-param&gt;<br>&nbsp;&nbsp;&lt;param-name&gt;webAppRootKey&lt;/param-name&gt;<br>&nbsp;&nbsp;&lt;param-value&gt;petstore.root&lt;/param-value&gt;<br>&nbsp;&lt;/context-param&gt;</font></p>
<p><font color="#339999">&nbsp;&lt;context-param&gt;<br>&nbsp;&nbsp;&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;<br>&nbsp;&nbsp;&lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;<br>&nbsp;&lt;/context-param&gt;</font></p>
<p><font color="#339999">&nbsp;&lt;context-param&gt;<br>&nbsp;&nbsp;&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br>&nbsp;&nbsp;&lt;param-value&gt;<br>&nbsp;&nbsp;&nbsp;/WEB-INF/dataAccessContext-hibernate.xml<br>&nbsp;&nbsp;&lt;/param-value&gt;<br>&nbsp;&lt;/context-param&gt;</font></p>
<p><font color="#339999">&nbsp;&lt;listener&gt;<br>&nbsp;&nbsp;&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br>&nbsp;&lt;/listener&gt;</font><font color="#339999">&nbsp;<br><br>&nbsp;&lt;servlet&gt;<br>&nbsp;&nbsp;&lt;servlet-name&gt;action&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&lt;load-on-startup&gt;3&lt;/load-on-startup&gt;<br>&nbsp;&lt;/servlet&gt;</font></p>
<p><font color="#339999">&nbsp;</font><font color="#339999">&lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&lt;servlet-name&gt;action&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br>&nbsp;&lt;/servlet-mapping&gt;<br></font><font color="#339999">&nbsp;...</font></p>
<p><font color="#339999">&lt;/web-app&gt;</font></p><img src ="http://www.blogjava.net/cgogg/aggbug/124982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:01 <a href="http://www.blogjava.net/cgogg/articles/124982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（三） 异常处理</title><link>http://www.blogjava.net/cgogg/articles/124980.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:00:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124980.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124980.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124980.html</trackback:ping><description><![CDATA[<p>配置Spring异常处理之需要增加一个bean的配置：<font style="background-color: #ffff99;">
<p>
<table border="1" cellpadding="1" cellspacing="1" width="200">
    <caption>增加了一个异常处理的bean</caption>
    <tbody>
        <tr>
            <td>&nbsp;<font style="background-color: #ffff99;">&lt;!-- Exception Resolver--&gt;<br>&nbsp;&lt;bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"&gt;<br>&nbsp;&nbsp;&lt;property name="defaultErrorView"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;/exception/failure&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br><br>&nbsp;&nbsp;&lt;property name="exceptionMappings"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="java.sql.SQLException"&gt;/exception/showDBError&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="java.lang.RuntimeException"&gt;/exception/showError&lt;/prop&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&lt;/props&gt;&nbsp;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><font style="background-color: #ffffff;">这样就可以统一分别处理不同Exception了。注意jsp页面在request中attribute等于&#8220;exception&#8221;,<br><br>而不是&#8220;Exception&#8221;注意大小写。页面如下：</font></p>
<p>
<table style="width: 574px; height: 153px;" border="1" cellpadding="1" cellspacing="1" width="574">
    <caption>错误显示页面</caption>
    <tbody>
        <tr>
            <td>
            <p>&nbsp;&lt;c:set value="${exception}" var="ee"/&gt;<br>&nbsp;&nbsp;&lt;jsp:useBean id="ee" type="java.lang.Exception" /&gt;<br>&nbsp;&nbsp;&lt;%=ee.getMessage()%&gt;&lt;br&gt;<br>&lt;%ee.printStackTrace( new java.io.PrintWriter(out));%&gt;<br></p>
            </td>
        </tr>
    </tbody>
</table>
<br></p>
<p><font style="background-color: #ffffff;">当然也可以做得更友好些，例如可以显示隐藏详细信息。</font></p>
<p>
<table style="width: 563px; height: 877px;" border="1" cellpadding="1" cellspacing="1" width="563">
    <tbody>
        <tr>
            <td>
            <p>&lt;%@ taglib prefix="c" uri="<a  href="http://java.sun.com/jstl/core_rt%22%">http://java.sun.com/jstl/core_rt"%</a>&gt;<br>&lt;%@ taglib prefix="spring"&nbsp; uri="<a  href="http://www.springframework.org/tags%22%">http://www.springframework.org/tags"%</a>&gt;<br>&lt;%@ page contentType="text/html;charset=GBK" language="java" pageEncoding="GBK"%&gt;<br>&lt;%@ page import="java.util.Enumeration,java.util.Iterator"%&gt;<br>&lt;script&gt;<br>&nbsp;function showErr(){<br>&nbsp;&nbsp;var isHidde = document.all.isHidde.value;<br>&nbsp;&nbsp;//alert(isHidde);<br>&nbsp;&nbsp;if( isHidde == "true" ){<br>&nbsp;&nbsp;&nbsp;document.all.errdiv.style.display='block';<br>&nbsp;&nbsp;&nbsp;document.all.isHidde.value= 'false';<br>&nbsp;&nbsp;&nbsp;document.all.showbtn.value="隐藏错误信息";<br>&nbsp;&nbsp;}else{<br>&nbsp;&nbsp;&nbsp;document.all.errdiv.style.display='none';<br>&nbsp;&nbsp;&nbsp;document.all.isHidde.value= 'true';<br>&nbsp;&nbsp;&nbsp;document.all.showbtn.value="显示错误信息";<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&lt;/script&gt;<br>&lt;html&gt;<br>&nbsp;&lt;head&gt;<br>&nbsp;&nbsp;&lt;title&gt;this is failure&lt;/title&gt;<br>&nbsp;&lt;/head&gt;<br>&nbsp;&lt;body onload="showErr()"&gt;&nbsp;</p>
            <p>&lt;c:set value="${exception}" var="ee"/&gt;<br>&nbsp;&nbsp;&lt;jsp:useBean id="ee" type="java.lang.Exception" /&gt;<br>&nbsp;&nbsp;&lt;%=ee.getMessage()%&gt;ok，&lt;br&gt;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&lt;table id="errdiv" align="center" bgcolor="darkseagreen"&gt;<br>&nbsp;&nbsp;&lt;tr&gt;&lt;td&gt;<br>&nbsp;&nbsp;&lt;font color=red&gt;<br>&nbsp;&nbsp;&lt;%ee.printStackTrace( new java.io.PrintWriter(out));%&gt;<br>&nbsp;&nbsp;&lt;/font&gt;<br>&nbsp;&nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;<br>&nbsp;&nbsp;&lt;input type="hidden" id="isHidde" value="true"/&gt;<br>&nbsp;&nbsp;&lt;input type="button" id="showbtn" onclick="showErr();"/&gt;</p>
            <p>&nbsp;&lt;/body&gt;<br>&lt;/html&gt;<br></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
</font></p>
<p>
<table border="1" cellpadding="1" cellspacing="1" width="200">
    <caption>增加了一个异常处理的bean</caption>
    <tbody>
        <tr>
            <td>&nbsp;<font style="background-color: #ffff99;">&lt;!-- Exception Resolver--&gt;<br>&nbsp;&lt;bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"&gt;<br>&nbsp;&nbsp;&lt;property name="defaultErrorView"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;/exception/failure&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br><br>&nbsp;&nbsp;&lt;property name="exceptionMappings"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="java.sql.SQLException"&gt;/exception/showDBError&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="java.lang.RuntimeException"&gt;/exception/showError&lt;/prop&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&lt;/props&gt;&nbsp;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><font style="background-color: #ffffff;">这样就可以统一分别处理不同Exception了。注意jsp页面在request中attribute等于&#8220;exception&#8221;,<br><br>而不是&#8220;Exception&#8221;注意大小写。页面如下：</font></p>
<p>
<table style="width: 574px; height: 153px;" border="1" cellpadding="1" cellspacing="1" width="574">
    <caption>错误显示页面</caption>
    <tbody>
        <tr>
            <td>
            <p>&nbsp;&lt;c:set value="${exception}" var="ee"/&gt;<br>&nbsp;&nbsp;&lt;jsp:useBean id="ee" type="java.lang.Exception" /&gt;<br>&nbsp;&nbsp;&lt;%=ee.getMessage()%&gt;&lt;br&gt;<br>&lt;%ee.printStackTrace( new java.io.PrintWriter(out));%&gt;<br></p>
            </td>
        </tr>
    </tbody>
</table>
<br></p>
<p><font style="background-color: #ffffff;">当然也可以做得更友好些，例如可以显示隐藏详细信息。</font></p>
<p>
<table style="width: 563px; height: 877px;" border="1" cellpadding="1" cellspacing="1" width="563">
    <tbody>
        <tr>
            <td>
            <p>&lt;%@ taglib prefix="c" uri="<a  href="http://java.sun.com/jstl/core_rt%22%">http://java.sun.com/jstl/core_rt"%</a>&gt;<br>&lt;%@ taglib prefix="spring"&nbsp; uri="<a  href="http://www.springframework.org/tags%22%">http://www.springframework.org/tags"%</a>&gt;<br>&lt;%@ page contentType="text/html;charset=GBK" language="java" pageEncoding="GBK"%&gt;<br>&lt;%@ page import="java.util.Enumeration,java.util.Iterator"%&gt;<br>&lt;script&gt;<br>&nbsp;function showErr(){<br>&nbsp;&nbsp;var isHidde = document.all.isHidde.value;<br>&nbsp;&nbsp;//alert(isHidde);<br>&nbsp;&nbsp;if( isHidde == "true" ){<br>&nbsp;&nbsp;&nbsp;document.all.errdiv.style.display='block';<br>&nbsp;&nbsp;&nbsp;document.all.isHidde.value= 'false';<br>&nbsp;&nbsp;&nbsp;document.all.showbtn.value="隐藏错误信息";<br>&nbsp;&nbsp;}else{<br>&nbsp;&nbsp;&nbsp;document.all.errdiv.style.display='none';<br>&nbsp;&nbsp;&nbsp;document.all.isHidde.value= 'true';<br>&nbsp;&nbsp;&nbsp;document.all.showbtn.value="显示错误信息";<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&lt;/script&gt;<br>&lt;html&gt;<br>&nbsp;&lt;head&gt;<br>&nbsp;&nbsp;&lt;title&gt;this is failure&lt;/title&gt;<br>&nbsp;&lt;/head&gt;<br>&nbsp;&lt;body onload="showErr()"&gt;&nbsp;</p>
            <p>&lt;c:set value="${exception}" var="ee"/&gt;<br>&nbsp;&nbsp;&lt;jsp:useBean id="ee" type="java.lang.Exception" /&gt;<br>&nbsp;&nbsp;&lt;%=ee.getMessage()%&gt;ok，&lt;br&gt;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&lt;table id="errdiv" align="center" bgcolor="darkseagreen"&gt;<br>&nbsp;&nbsp;&lt;tr&gt;&lt;td&gt;<br>&nbsp;&nbsp;&lt;font color=red&gt;<br>&nbsp;&nbsp;&lt;%ee.printStackTrace( new java.io.PrintWriter(out));%&gt;<br>&nbsp;&nbsp;&lt;/font&gt;<br>&nbsp;&nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;<br>&nbsp;&nbsp;&lt;input type="hidden" id="isHidde" value="true"/&gt;<br>&nbsp;&nbsp;&lt;input type="button" id="showbtn" onclick="showErr();"/&gt;</p>
            <p>&nbsp;&lt;/body&gt;<br>&lt;/html&gt;<br></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><br></p><img src ="http://www.blogjava.net/cgogg/aggbug/124980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:00 <a href="http://www.blogjava.net/cgogg/articles/124980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（四） 与struts整合</title><link>http://www.blogjava.net/cgogg/articles/124981.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 10:00:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124981.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124981.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124981.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124981.html</trackback:ping><description><![CDATA[		《Spring开发指南》只写了一种与struts整合的方法，另一种到Spring2.0 Demo自带的Doc中查找到Action直接继承ActionSupport。详细信息:<br>
<p>To integrate your Struts application with Spring, you have two options:</p>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p>Configure Spring to manage your Actions as beans, using the <tt class="literal">ContextLoaderPlugin</tt>, and set their dependencies in a Spring context file.</p>
    </li>
    <li>
    <p>Subclass Spring's <span class="emphasis"><em>ActionSupport</em></span> classes and grab your Spring-managed beans explicitly using a <span class="emphasis"><em>getWebApplicationContext()</em></span> method.<br></p>
    </li>
</ul>
</div>
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="struts-actionsupport"></a>16.3.2.&nbsp;ActionSupport Classes</h3>
</div>
</div>
</div>
<p>As previously mentioned, you can retrieve the <tt class="literal">WebApplicationContext</tt> from the <tt class="literal">ServletContext</tt>
using the WebApplicationContextUtils class. An easier way is to extend
Spring's Action classes for Struts. For example, instead of subclassing
Struts' Action class, you can subclass Spring's <a  href="http://www.springframework.org/docs/api/org/springframework/web/struts/ActionSupport.html" target="_top"><tt class="literal">ActionSupport</tt></a> class.</p>
<p>The <tt class="literal">ActionSupport</tt> class provides additional convenience methods, like <span class="emphasis"><em>getWebApplicationContext()</em></span>. Below is an example of how you might use this in an Action: </p>
<pre class="programlisting">public class UserAction extends DispatchActionSupport {    public ActionForward execute(ActionMapping mapping,                                 ActionForm form,                                 HttpServletRequest request,                                 HttpServletResponse response)            throws Exception {        if (log.isDebugEnabled()) {            log.debug("entering 'delete' method...");        }        WebApplicationContext ctx = getWebApplicationContext();        UserManager mgr = (UserManager) ctx.getBean("userManager");        // talk to manager for business logic        return mapping.findForward("success");    }}</pre>
<p>Spring includes subclasses for all of the standard Struts Actions - the Spring versions merely have <span class="emphasis"><em>Support</em></span> appended to the name: </p>
<div class="itemizedlist">
<ul compact="65535" type="disc">
    <li>
    <p><a  href="http://www.springframework.org/docs/api/org/springframework/web/struts/ActionSupport.html" target="_top"><tt class="literal">ActionSupport</tt></a>,</p>
    </li>
    <li>
    <p><a  href="http://www.springframework.org/docs/api/org/springframework/web/struts/DispatchActionSupport.html" target="_top"><tt class="literal">DispatchActionSupport</tt></a>,</p>
    </li>
    <li>
    <p><a  href="http://www.springframework.org/docs/api/org/springframework/web/struts/LookupDispatchActionSupport.html" target="_top"><tt class="literal">LookupDispatchActionSupport</tt></a> and</p>
    </li>
    <li>
    <p><a  href="http://www.springframework.org/docs/api/org/springframework/web/struts/MappingDispatchActionSupport.html" target="_top"><tt class="literal">MappingDispatchActionSupport</tt></a>.</p>
    </li>
</ul>
</div>
<p>The
recommended strategy is to use the approach that best suits your
project. Subclassing makes your code more readable, and you know
exactly how your dependencies are resolved. However, using the <tt class="literal">ContextLoaderPlugin</tt>
allow you to easily add new dependencies in your context XML file.
Either way, Spring provides some nice options for integrating the two
frameworks.</p>
<p>可见第二种方法更加简便。</p>
<p>JPetstore例子中并没有使用此方法，而使用了第三种方法。同样只需要动Action。如下：</p>
<p>public abstract class BaseAction extends Action {</p>
<p>&nbsp; private PetStoreFacade petStore;</p>
<p>&nbsp;public void setServlet(ActionServlet actionServlet) {<br>&nbsp;&nbsp;super.setServlet(actionServlet);<br>&nbsp;&nbsp;if (actionServlet != null) {<br>&nbsp;&nbsp;&nbsp;ServletContext servletContext = actionServlet.getServletContext();<br>&nbsp;&nbsp;&nbsp;WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);<br>&nbsp;&nbsp;&nbsp;this.petStore = (PetStoreFacade) wac.getBean("petStore");<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p>&nbsp;protected PetStoreFacade getPetStore() {<br>&nbsp;&nbsp;return petStore;<br>&nbsp;}</p>
<p>}<br>ok，这三种方法都可以让Spring与Struts整合，相比较第一种（因为配置很多这里没写，见refernce 16.3.1），<br>第二第三种方法比较简洁，侵入不多。</p><img src ="http://www.blogjava.net/cgogg/aggbug/124981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 18:00 <a href="http://www.blogjava.net/cgogg/articles/124981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（一）</title><link>http://www.blogjava.net/cgogg/articles/124979.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 09:58:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124979.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124979.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124979.html</trackback:ping><description><![CDATA[<p>ApplicationContext ctx </p>
<p>1，定义资源文件获得资源文件的消息，国际化信息<br>&lt;bean id="messageResource" class="org.springFramework.context.support.ResourceBoundleMessageSource"&gt;<br>&nbsp;&lt;property name="basenames"&gt;<br>&nbsp;&nbsp;xxxx<br>&nbsp;&lt;/property&gt;<br>&lt;/bean&gt;<br>将会搜索xxxx.properties,xxxx_zh.properties ,xxxx_ch.properties等。</p>
<p>2，<br>程序里使用资源文件 ：ctx.getMessage('key',arg);<br>页面上使用资源文件：&lt;spring:message code="keyxxx"/&gt;</p>
<p><br>3，使用其他文件。<br>&nbsp;Resource rs = ctx.getResource("classpath:config.properties");<br>&nbsp;File file = rs.getFile();<br>&nbsp;目录规则：<br>&nbsp;file：c：/test。txt<br>&nbsp;/config.properties<br>&nbsp;classpath:config.properties<br>&nbsp;三种方式。</p>
<p>4，事件传播<br>&nbsp; 不过没有找到ApplicationListener这个类。</p>
<p>5, WebApp获取ApplicaionContext的方法，<br>&nbsp;首先是在web。xml中进行配置，可以配置成一个listener，也可以配置成一个servlet。<br>&nbsp;然后程序里使用WebApplicationContextUtils.getWebApplicationContext.获得饮用。</p>
<p>6，Spring可以和很多框架进行集成。<br>&nbsp;Struts+Spring，Webwork+Spring。</p>
<p>7，Spring可以有自己的调度类，DispatherServlet。<br>&nbsp;使用的配置文件就是beans的配置，名字可以随便取。</p>
<p>8，Sping配置文件（具体名字见web.xml中对ContextLoaderServlet的参数）类似于Struts的配置文件。<br>&nbsp;定义viewer使用的是系统类：<br>&nbsp;&nbsp;org.springframework.web.servlet.view.InternalResourceViewResolver<br>&nbsp;Request mapping 使用的系统类：<br>&nbsp;&nbsp;org.springframework.web.servlet.handler.SimpleUrlHandleMapping<br>&nbsp;对Action的定义使用自定义类，但这些类都是下面类的子类：<br>&nbsp;&nbsp;SimpleFormController<br>&nbsp;Actoin的属性包括：<br>&nbsp;&nbsp;1，跳转的页面，和view关联<br>&nbsp;&nbsp;2，封装form类，就是一个普通的javabean。<br>&nbsp;&nbsp;<br>9，Acition类的内容，<br>&nbsp; 实现onsubmit（ 封装的form，异常对象） 返回一个ModelAndView。<br>&nbsp; ModelAndView用字符串初始化，字符串来自Action的两个跳转view名称。<br>&nbsp; 还可以把Map传入ModelAndView构造函数，用来返回消息。</p>
<p><br>10，Spring自带的数据验证功能。<br>&nbsp;10.1，验证类作为Aciotn的一个名为&#8220;validator&#8221;的属性在配置文件中配置。<br>&nbsp;此类继承org.springframework.validation.Validator<br>&nbsp;需要实现两个接口，support（传入一个类），验证此类是否是Action对应的form类。<br>&nbsp;validator（object obj，Errors err )首先把obj转为form类对象，如果有错误放到errors里，用法和<br>&nbsp;&nbsp;struts类似。<br>&nbsp;<br>&nbsp;10.2，表现层页面需要的显示错误<br>&nbsp;&nbsp;全部错误：<br>&nbsp;&nbsp;&lt;spring:bind path="command.*"&gt;<br>&nbsp;&nbsp;&nbsp;//遍历status.errorMessages<br>&nbsp;&nbsp;&lt;/spring:bind&gt;&nbsp;&nbsp;<br>&nbsp;<br>&nbsp;&nbsp;单个错误：<br>&nbsp;&nbsp;&lt;spring:bind path="command.username"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;input type="text" value="${staus.value}" name="${status.expression}"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;c:if test="${status.error}"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;//遍历status.errorMessages<br>&nbsp;&nbsp;&nbsp;&lt;/c:if&gt;<br>&nbsp;&nbsp;&lt;/spring:bind&gt;<br>&nbsp;&nbsp;如果已经在Action中配置了commandName，那么就不使用command了，而是使用配置的名字<br>&nbsp;&nbsp;&lt;bean id=&#8216;loginActoni&#8217;&gt;<br>&nbsp;&nbsp;&nbsp;&lt;property name="commandName"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;RegisterInfo&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;/bean&gt;</p>
<p>11,&nbsp;异常处理<br>&nbsp;在Dispather的配置文件中配置<br>&nbsp;&lt;bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"&gt;<br>&nbsp;定义两个属性：<br>&nbsp;&lt;property name="defaultErrorView"&gt;<br>&nbsp;&lt;property name="exceptionMapping"&gt;<br>&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&lt;prop key="java.sql.SQLException"&gt;sss&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&lt;prop key="java.lang.RuntimeException"&gt;yyy&lt;/prop&gt;<br>&nbsp;&nbsp;&lt;/props&gt;<br>&nbsp;&lt;/property&gt;&nbsp;<br>&nbsp;可以按不同异常映射到不同的页面。<br>&nbsp;异常页面从request.getAttribute("Exception")取得Exception对象。显示他的message属性。</p>
<p>12，国际化<br>&nbsp;看完1后，补充如下：<br>&nbsp;Spring判断用户Locale的方式有三种，request中取，session中取，cookie中取客户端的locale。<br>&nbsp;分别用三个类，配置到配置文件中。</p>
<p>13，数据持久层（重要）对事务的封装<br>&nbsp;Spring是依赖容器的参数化事务管理不用写代码。<br>&nbsp;见p67。<br>&nbsp;1，在配置文件中配置完数据源，<br>&nbsp;2，之后配置事务管理的bean，数据源是它的属性。<br>&nbsp;3，DAO，事务员是它的属性。<br>&nbsp;4，事务beanDAOProxy，事务策略，事务bean，DAO都是它的属性。</p>
<p>14，数据持久层，对JDBC的封装<br>&nbsp;org.springframework.jdbc.core.JdbcTemplate.<br>&nbsp;JdbcTemplate jdbctemplate = new JdbcTemptlate( datasource );<br>&nbsp;jdbctemplate.update("xxxxx");<br>&nbsp;jdbctemplate.update("xxxxx",new PreparedStatementSetter(){<br>&nbsp;&nbsp;public void setValues( PreparedStatementSetter ps ){<br>&nbsp;&nbsp;&nbsp;ps.setInt(1,15);<br>&nbsp;&nbsp;&nbsp;ps.setString(2,"jjjjjjj");<br>&nbsp;&nbsp;}<br>&nbsp;});<br>&nbsp;jdbctemplate.query("select ...",new RollbackHandler(){<br>&nbsp;&nbsp;public void processRow( ResultSet rs ){<br>&nbsp;&nbsp;&nbsp;User user = new User();<br>&nbsp;&nbsp;&nbsp;user.setName= rs.getString("name");<br>&nbsp;&nbsp;&nbsp;userList.add( user )；<br>&nbsp;&nbsp;}<br>&nbsp;});</p>
<p>&nbsp;.call()可以调用存储过程。<br>&nbsp;query,update还有很多不同版本的实现。<br>&nbsp;</p>
<p>15,&nbsp;JDBC封装还要引入事务管理机制，默认是没有事务的。<br>&nbsp;两种方式<br>&nbsp;1，代码控制的，在DAO里TransactionTemplate使用它的方法。<br>&nbsp;2，参数化配置的事务。配置一个ProxyDAO，不用写这个类，只需要在配置文件里增加他对DAO的事物设置。<br>&nbsp;&nbsp;使得DAO代码十分简洁。</p>
<p>&nbsp;测试代码：<br>&nbsp;InputStream is = new FileInputStream("xxx.xml");<br>&nbsp;XmlBeanFactory factory = new XmlBeanFactoy( is );<br>&nbsp;UserDAO dao = (UserDAO)factory.getBean("ProxyDAO");<br>&nbsp;dao.insert();//这样就行了</p>
16，Hibernate in Spring<br>&nbsp;只需修改配置文件增加一个bean名字为sessionFactory，数据源作为他的属性。<br>&nbsp;TrsactionManager的属性：sessionFactory<br>&nbsp;IDAO接口：定义数据库操作方法。<br>&nbsp;DAO的属性：sessionFactory。继承HibernateDAOSupport，并实现IDAO接口。<br>&nbsp;&nbsp;&nbsp;里面使用getHibernateTemplate模版进行数据库操作。<br>&nbsp;ProxyDAO的属性：transactionManager,DAO.<br>&nbsp;<br>&nbsp;测试例子：<br>&nbsp;IUserDAO dao=(IUserDAO)factory.getBean("ProxyUserDAO");&nbsp;<br>&nbsp;User user = new User();<br>&nbsp;user.setxxx...<br>&nbsp;dao.insertOrUpdate(user);<br>&nbsp;<img src ="http://www.blogjava.net/cgogg/aggbug/124979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 17:58 <a href="http://www.blogjava.net/cgogg/articles/124979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记系列（二）</title><link>http://www.blogjava.net/cgogg/articles/124978.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Mon, 18 Jun 2007 09:53:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/124978.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/124978.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/124978.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/124978.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/124978.html</trackback:ping><description><![CDATA[<p>Spring学习笔记二(2006.1.4)</p>
<p>1,配置文件的配置头<br>&lt;?xml version="1.0" encoding="UTF-8"?&gt;</p>
<p>&lt;!--<br>&nbsp; - Application context definition for JPetStore's business layer.<br>&nbsp; - Contains bean references to the transaction manager and to the DAOs in<br>&nbsp; - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").<br>&nbsp; --&gt;<br>&lt;beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"<br>&nbsp;&nbsp;&nbsp; xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br>&nbsp;&nbsp;&nbsp; xmlns:aop="<a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a>"<br>&nbsp;&nbsp;&nbsp; xmlns:tx="<a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a>"<br>&nbsp;&nbsp;&nbsp; xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans.xsd">http://www.springframework.org/schema/beans/spring-beans.xsd</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a> <a href="http://www.springframework.org/schema/aop/spring-aop.xsd">http://www.springframework.org/schema/aop/spring-aop.xsd</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a> <a href="http://www.springframework.org/schema/tx/spring-tx.xsd">http://www.springframework.org/schema/tx/spring-tx.xsd</a>"&gt;<br>这样写才对</p>
<p>2，配置文件可以使用多个属性文件<br>&lt;!-- Configurer that replaces ${...} placeholders with values from properties files --&gt;<br>&nbsp;&lt;!-- (in this case, mail and JDBC related properties) --&gt;<br>&nbsp;&lt;bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;<br>&nbsp;&nbsp;&lt;property name="locations"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;WEB-INF/mail.properties&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;WEB-INF/jdbc.properties&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&lt;/bean&gt;<br>类是框架的。<br>里面包含两个属性文件，属性文件里都是&#8220;key=value&#8221;这种形式的。这样配置文件里就可以使用属性文件里的key，使用方法<br>${key},这样转移出属性设置，维护起来比较方便。</p>
<p>3,定义Validator供web层使用，自定义类。<br>&lt;bean id="accountValidator" class="org.springframework.samples.jpetstore.domain.logic.AccountValidator"/&gt;<br>类里面使用了ValidatorUtils系统类来进行处理。</p>
<p>4，服务层的定义。<br>&nbsp;PetStoreImpl定义在配置文件中，是自己的类。<br>&nbsp;所有的DAO都是它的属性，注意，DAO是interface,而不是class.<br>&nbsp;PetStoreImpl中定义了所有的DAO接口作为属性，定义了他们的set方法，但是没有定义get方法。<br>&nbsp;这样所有的业务操作就可以不用管DAO是如何实现的了，而只管使用这个PetStoreImpl就好了。</p>
<p>&nbsp;DAO都是接口这种做法与平时开发不一样，我以前使用hibernate生成工具生成的dao都是默认好的实现类。<br>&nbsp;而此处的DAO却都是接口。他们的实现方法是这样的：<br>&nbsp;interface PetStoreFacade { } //定义所有的业务方法。<br>&nbsp;interface AccountDao{} //定义所有帐户的业务方法。<br>&nbsp;interface CategoryDao{} //定义类别的业务方法。<br>&nbsp;interface ProductDao{} //定义产品的业务方法。<br>&nbsp;。。。其他DAO接口，定义自己的业务方法。<br>&nbsp;class PetStoreImpl implements PetStoreFacade //这个类就是一个javabean，操作的都是接口。<br>&nbsp;//定义所有DAO接口当作自己的属性。<br>&nbsp;//实现set方法<br>&nbsp;//实现PetStoreFacade 定义的业务接口，实现的时候调用DAO接口的方法。</p>
<p>&nbsp;如果是我自己，那么就会定义IDAO当作接口，因为hibernate插件自动生成dao类，容易混淆。<br>&nbsp;<br>5，配置文件中定义dataSource<br>&nbsp;&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;<br>&nbsp;&nbsp;&lt;property name="driverClassName" value="${jdbc.driverClassName}"/&gt;<br>&nbsp;&nbsp;&lt;property name="url" value="${jdbc.url}"/&gt;<br>&nbsp;&nbsp;&lt;property name="username" value="${jdbc.username}"/&gt;<br>&nbsp;&nbsp;&lt;property name="password" value="${jdbc.password}"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;可见，可以直接使用properties中的key。另外可以将数据库操作弄成另外一个配置文件。只要在web.xml中设置好就可以了，<br>&nbsp;&lt;context-param&gt;<br>&nbsp;&nbsp;&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br>&nbsp;&nbsp;&lt;param-value&gt;<br>&nbsp;&nbsp;&nbsp;/WEB-INF/dataAccessContext-local.xml&nbsp; /WEB-INF/applicationContext.xml<br>&nbsp;&nbsp;&lt;/param-value&gt;<br>&nbsp;&lt;/context-param&gt;</p>
<p>6，配置文件中定义事务管理<br>&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;<br>&nbsp;&nbsp;&lt;property name="dataSource" ref="dataSource"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;使用了数据源作为属性。</p>
<p>7，dao具体实现类。<br>&nbsp;JPetStore使用ibatis作为ORM层。所以dao类的定义也都使用了ibatis。<br>&nbsp;PetStoreImpl五个接口接受五个实现了对应接口的实现类。这里的实现类，<br>&lt;bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl"&gt;<br>&nbsp;&nbsp;&lt;property name="accountDao" ref="accountDao"/&gt;<br>&nbsp;&nbsp;&lt;property name="categoryDao" ref="categoryDao"/&gt;<br>&nbsp;&nbsp;&lt;property name="productDao" ref="productDao"/&gt;<br>&nbsp;&nbsp;&lt;property name="itemDao" ref="itemDao"/&gt;<br>&nbsp;&nbsp;&lt;property name="orderDao" ref="orderDao"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;&lt;bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao"&gt;<br>&nbsp;&nbsp;&lt;property name="sqlMapClient" ref="sqlMapClient"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;实现类，使用ibatis。在配置文件中对英。<br>public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao{<br>&nbsp;//实现了业务接口，继承了ibatis基本类。<br>&nbsp;}</p>
<p><br>8，ibatis基础类。<br>&nbsp;&nbsp;&nbsp; &lt;!-- SqlMap setup for iBATIS Database Layer --&gt;<br>&nbsp;&lt;bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt;<br>&nbsp;&nbsp;&lt;property name="configLocation" value="WEB-INF/sql-map-config.xml"/&gt;<br>&nbsp;&nbsp;&lt;property name="dataSource" ref="dataSource"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;dao实现类都由他作属性。<br>&nbsp;&nbsp;&nbsp; &lt;bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao"&gt;<br>&nbsp;&nbsp;&lt;property name="sqlMapClient" ref="sqlMapClient"/&gt;<br>&nbsp;&lt;/bean&gt;</p>
<p>9，我竟然找不到action对应的mapping在什么地方定义的。<br>后来找到了是petstore-servlet.xml,by default defined in "{servlet-name}-servlet.xml"...<br>&lt;!--<br>&nbsp;&nbsp; - Spring web MVC servlet that dispatches requests to registered handlers.<br>&nbsp;&nbsp; - Has its own application context, by default defined in "{servlet-name}-servlet.xml",<br>&nbsp;&nbsp; - i.e. "petstore-servlet.xml" in this case.<br>&nbsp;&nbsp; -<br>&nbsp;&nbsp; - A web app can contain any number of such servlets.<br>&nbsp;&nbsp; - Note that this web app has a shared root application context, serving as parent<br>&nbsp;&nbsp; - of all DispatcherServlet contexts.<br>&nbsp;&nbsp; --&gt;<br>&nbsp;&lt;servlet&gt;<br>&nbsp;&nbsp;&lt;servlet-name&gt;petstore&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br>&nbsp;&lt;/servlet&gt;<br>&nbsp;原来是根据servlet名字命名影射文件的。<br>&nbsp;影射文件和配置文件的结构完全一致，也是beans开头的。主要是web层的url影射，<br>&nbsp;&lt;beans&gt;<br>&nbsp;&lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;<br>&nbsp;&nbsp;&lt;property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/&gt;<br>&nbsp;&nbsp;&lt;property name="prefix" value="/WEB-INF/jsp/spring/"/&gt;<br>&nbsp;&nbsp;&lt;property name="suffix" value=".jsp"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;....<br>&nbsp;&lt;/beans&gt;<br>&nbsp;ok，现在把petstore-servlet.xml也放到SpringIDE里察看。</p>
<p>10，配置文件petstore-servlet.xml<br>&nbsp;viewResolver,定义了一个表现层的基本配置，此bean名字固定。<br>&nbsp;属性viewClass使用了jstl技术。<br>&nbsp;&lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;<br>&nbsp;&nbsp;&lt;property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/&gt;<br>&nbsp;&nbsp;&lt;property name="prefix" value="/WEB-INF/jsp/spring/"/&gt;<br>&nbsp;&nbsp;&lt;property name="suffix" value=".jsp"/&gt;<br>&nbsp;&lt;/bean&gt;</p>
<p>11，配置文件petstore-servlet.xml<br>&nbsp;defaultHandlerMapping使用默认的BeanNameUrl影射，具体不太明白。<br>&nbsp;&lt;bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/&gt;</p>
<p>12，配置文件petstore-servlet.xml<br>&nbsp;定义*.do<br>&lt;bean name="/shop/addItemToCart.do" class="org.springframework.samples.jpetstore.web.spring.AddItemToCartController"&gt;<br>&nbsp;&nbsp;&lt;property name="petStore" ref="petStore"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;属性petStore是在applicationContext.xml里定义的，看来这里也可以使用其他&lt;beans&gt;定义的bean。</p>
<p>13，*.do类研究<br>&nbsp;实现了Controller，接口public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) <br>&nbsp;有一个属性petstore,是一个接口PetStoreFacade，包括全部业务逻辑接口。<br>&nbsp;<br>14，首页index<br>&nbsp;在mapping文件里定义了系统ParameterizableViewController，相当于forwardAction。<br>&nbsp;&lt;bean name="/shop/index.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController"&gt;<br>&nbsp;&nbsp;&lt;property name="viewName" value="index"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;而首页里大量使用了jstl语言，最重要的地方是所有 a href=, action=,处都使用了&lt;c:url value="/xxxx"/&gt;<br>&nbsp;这样的定义，这样换域名或者设置虚拟目录名，就会运行正常了。例如，<br>&lt;center&gt;<br>&lt;a href="&lt;c:url value="/shop/viewCategory.do?categoryId=FISH"/&gt;"&gt;<br>&lt;img border="0" src="../images/sm_fish.gif" /&gt;&lt;/a&gt;<br>&lt;img border="0" src="../images/separator.gif" /&gt;<br>&lt;a href="&lt;c:url value="/shop/viewCategory.do?categoryId=DOGS"/&gt;"&gt;<br>&lt;img border="0" src="../images/sm_dogs.gif" /&gt;&lt;/a&gt;<br>&lt;img border="0" src="../images/separator.gif" /&gt;<br>&lt;a href="&lt;c:url value="/shop/viewCategory.do?categoryId=REPTILES"/&gt;"&gt;<br>&lt;img border="0" src="../images/sm_reptiles.gif" /&gt;&lt;/a&gt;<br>&lt;img border="0" src="../images/separator.gif" /&gt;<br>&lt;a href="&lt;c:url value="/shop/viewCategory.do?categoryId=CATS"/&gt;"&gt;<br>&lt;img border="0" src="../images/sm_cats.gif" /&gt;&lt;/a&gt;<br>&lt;img border="0" src="../images/separator.gif" /&gt;<br>&lt;a href="&lt;c:url value="/shop/viewCategory.do?categoryId=BIRDS"/&gt;"&gt;<br>&lt;img border="0" src="../images/sm_birds.gif" /&gt;&lt;/a&gt;<br>&lt;/center&gt;</p>
<p>15，&nbsp;进入首页后点左边的链接都指向同一个viewCategory.do,<br>&nbsp;&lt;bean name="/shop/viewCategory.do" class="org.springframework.samples.jpetstore.web.spring.ViewCategoryController"&gt;<br>&nbsp;&nbsp;&lt;property name="petStore" ref="petStore"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;类研究：<br>&nbsp;ViewCategoryController implement Controller<br>&nbsp;里面只使用了PetStore实现类的方法，并没有DAO对象。只有Domain对象。<br>&nbsp;很好，把主要的和业务相关的东西都在Controller中展现出来了，其他辅助的东西都被隐藏了，使得Controller非常简洁。<br>&nbsp;另外，在业务PetStoreImp类中，使用了DAO，这样就使得后台程序也开始分层了。<br>&nbsp;<br>&nbsp;|--层Controller及使用的daomain对象 /// 第一层<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |----层PetStoreFacade 接口及他的实现类PetStoreImpl //第二层<br>&nbsp;&nbsp;&nbsp;|-------- 层DAO接口 ，DAO接口实现类，//第三层<br>&nbsp;&nbsp;&nbsp;&nbsp;|------------实现类中使用的ORM类&nbsp; //第四层<br>&nbsp;层次非常的分明。<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;daomain符合javabean规范，并且有些javabean还有自己的public方法。大多数javabean没有必要有public方法。</p>
<p>16, 点击分类后，显示分类中的items，点items可以进入viewProduct.do？productId=xxx，来观看产品。<br>&nbsp;&lt;bean name="/shop/viewProduct.do" class="org.springframework.samples.jpetstore.web.spring.ViewProductController"&gt;<br>&nbsp;&nbsp;&lt;property name="petStore" ref="petStore"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;这是一个翻页功能的Controller。<br>&nbsp;没弄清楚成功后跳转到什么地方？&nbsp;return new ModelAndView("Product", model);没有理解。<br>&nbsp;<br>public
class ModelAndViewextends ObjectHolder for both Model and View in the
web MVC framework. Note that these are entirely distinct. This class
merely holds both to make it possible for a controller to return both
model and view in a single return value. </p>
<p>Class to represent a
model and view returned by a handler used by a DispatcherServlet. The
view can take the form of a reference to a View object, or a String
view name which will need to be resolved by a ViewResolver object. The
model is a Map, allowing the use of multiple data objects keyed by
name. </p>
<p>public ModelAndView(String viewName,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map model)Creates new ModelAndView given a view name and a model. </p>
<p>Parameters:<br>viewName - name of the View to render, to be resolved by the DispatcherServlet<br>model
- Map of model names (Strings) to model objects (Objects). Model
entries may not be null, but the model Map may be null if there is no
model data.</p>
<p>这样viewName就知道了，返回给DispatcherServerlet,再根据viewResolver中的定义，就可以知道是/jsp/spring/Product.jsp了。<br>也就是说，viewName也就是jsp文件的名字。</p>
<p>17，ModelAndView传递给页面之后页面如何使用其中的数据 ？<br>&nbsp;Controller传递的model是一个map，一共传递了两个key-value对。<br>&nbsp;model.put("itemList", itemList);<br>&nbsp;model.put("product", product);<br>&nbsp;ok，看jsp页面。&lt;c:out value="${product.name}"/&gt;<br>&lt;c:forEach var="item" items="${itemList.pageList}"&gt;<br>&nbsp; &lt;tr bgcolor="#FFFF88"&gt;<br>&nbsp; &lt;td&gt;&lt;b&gt;<br>&nbsp; &lt;a href="&lt;c:url value="/shop/viewItem.do"&gt;&lt;c:param name="itemId" value="${item.itemId}"/&gt;&lt;/c:url&gt;"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.itemId}"/&gt;<br>&nbsp; &lt;/a&gt;&lt;/b&gt;&lt;/td&gt;<br>&nbsp; &lt;td&gt;&lt;c:out value="${item.productId}"/&gt;&lt;/td&gt;<br>&nbsp; &lt;td&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.attribute1}"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.attribute2}"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.attribute3}"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.attribute4}"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${item.attribute5}"/&gt;<br>&nbsp;&nbsp;&nbsp; &lt;c:out value="${product.name}"/&gt;<br>&nbsp; &lt;/td&gt;<br>&nbsp; &lt;td&gt;&lt;fmt:formatNumber value="${item.listPrice}" pattern="$#,##0.00"/&gt;&lt;/td&gt;<br>&nbsp;
&lt;td&gt;&lt;a href="&lt;c:url
value="/shop/addItemToCart.do"&gt;&lt;c:param name="workingItemId"
value="${item.itemId}"/&gt;&lt;/c:url&gt;"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;img border="0" src="../images/button_add_to_cart.gif"/&gt;<br>&nbsp; &lt;/a&gt;&lt;/td&gt;<br>&nbsp; &lt;/tr&gt;<br>&lt;/c:forEach&gt;<br>原来是把key当作attributename放到了request范围内了。这样就ok了，model的key实际上就是request的属性名字啊。<br>&nbsp;model的value就是request的属性值。jstl真正发挥简洁的威力了。</p>
<p>18，viewProduct.do里还有一个翻页的逻辑，没看明白怎么回事。</p>
<p><br>19，viewProduct.do之后再点链接就进入了viewItem.do,相对简单。不用看了。<br>PagedListHolder itemList = new PagedListHolder(this.petStore.getItemListByProduct(productId));<br>java.lang.Object<br>&nbsp; org.springframework.beans.support.PagedListHolder<br>PagedListHolder
is a simple state holder for handling lists of objects, separating them
into pages. Page numbering starts with 0. <br>Constructor Summary <br>PagedListHolder() <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Create a new holder instance. <br>PagedListHolder(List source) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Create a new holder instance with the given source list, starting with
a default sort definition (with "toggleAscendingOnProperty" activated).
<br>PagedListHolder(List source, SortDefinition sort) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Create a new holder instance with the given source list. <br>&nbsp;boolean isFirstPage() <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return if the current page is the first one. <br>&nbsp;boolean isLastPage() <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return if the current page is the last one. <br>&nbsp;void nextPage() <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Switch to next page. <br>&nbsp;void previousPage() <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Switch to previous page. <br>&nbsp;可以排序。可以设置页数。<br>这
个类明显是把所有的结果一次性查询出来后，设定每页个数，之后再把当页数据发送给页面。虽然不是把全部数据发送给页面由页面来分页，但是一次把全部数据都
查询出来的做法只适合少量数据。如果多量数据几万条的话同时查出来，存放到session，用不了多久服务器的内存就被耗光了。<br>还不太清楚放到session中的对象什么时候被晴空，好像只有在退出的时候才晴空一次。</p>
<p>20，addItemToCart.do?workingItemId=EST-11，代码很清楚。有两点主意：<br>&nbsp;一，webUtil org.springframework.web.util.webUtil提供了有限的几个方法。<br>&nbsp;二，return new ModelAndView("Cart", "cart", cart); // Cart.jsp , key ,value<br>&nbsp;因为不熟悉ibatis所以ORM层的代码都没有阅读，也就是PetsoreImpl实现类的各个DAO实例都没有阅读。</p>
<p>&nbsp;&nbsp;&nbsp; removeItemFromCart.do?workingItemId=EST-11 也是同一页面上的购物车操作 ，过于简单。略<br>&nbsp;updateCartQuantities.do //更新的是内存中的数据，所以没有什么技术。</p>
<p>21，checkout.do有一点需要注意，别的Controller没有传入viewName。它传了，<br>&nbsp;&lt;bean name="/shop/checkout.do" class="org.springframework.samples.jpetstore.web.spring.ViewCartController"&gt;<br>&nbsp;&nbsp;&lt;property name="successView" value="Checkout"/&gt;<br>&nbsp;&lt;/bean&gt;<br>&nbsp;Controller中：<br>&nbsp;private String successView;</p>
<p>&nbsp;public void setSuccessView(String successView) {<br>&nbsp;&nbsp;this.successView = successView;<br>&nbsp;}<br>&nbsp;最后return new ModelAndView(this.successView, "cart", cart);</p>
<br><br>
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=571067</p>
<br><img src ="http://www.blogjava.net/cgogg/aggbug/124978.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-18 17:53 <a href="http://www.blogjava.net/cgogg/articles/124978.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Springweb 表现层集成技术</title><link>http://www.blogjava.net/cgogg/articles/springweb.html</link><dc:creator>chenguo</dc:creator><author>chenguo</author><pubDate>Wed, 13 Jun 2007 01:53:00 GMT</pubDate><guid>http://www.blogjava.net/cgogg/articles/springweb.html</guid><wfw:comment>http://www.blogjava.net/cgogg/comments/123781.html</wfw:comment><comments>http://www.blogjava.net/cgogg/articles/springweb.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cgogg/comments/commentRss/123781.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cgogg/services/trackbacks/123781.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 13.1. 简介Spring之所以出色的一个原因就是将表现层从MVC的框架中分离出来。例如，通过配置就可以让Velocity或者XSLT来代替已经存在的JSP页面。本章介绍和Spring集成的一些主流表现层技术，并简要描述如何集成新的表现层。这里假设你已经熟悉第 12.5 节 &#8220;视图与视图解析&#8221;，那里介绍了将表现层集成到MVC框架中的基本知识。13.2. 和JSP &amp...&nbsp;&nbsp;<a href='http://www.blogjava.net/cgogg/articles/springweb.html'>阅读全文</a><img src ="http://www.blogjava.net/cgogg/aggbug/123781.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cgogg/" target="_blank">chenguo</a> 2007-06-13 09:53 <a href="http://www.blogjava.net/cgogg/articles/springweb.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>