﻿<?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-javaEE参考</title><link>http://www.blogjava.net/terryxue/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 13:09:51 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 13:09:51 GMT</pubDate><ttl>60</ttl><item><title>spring+hibernate连接泄漏之殇</title><link>http://www.blogjava.net/terryxue/archive/2012/11/07/390930.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Wed, 07 Nov 2012 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2012/11/07/390930.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/390930.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2012/11/07/390930.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/390930.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/390930.html</trackback:ping><description><![CDATA[<div>数据库连接泄漏是件可怕的事情，可能直接导致系统停止响应，另外因事务管理错误而导致数据出现不一致也是件可怕的事情，在后台系统中，这两个问题经常会结伴出现，本文将通过案例详解使用Spring+Hibernate时可能导致问题的几种情况，希望对大家有所帮助。<br /><br /><em>文章比较长，如果你是遇到了问题正急求解决方案的话，可以先只读这一条：检查你的dao是否有直接使用session，修改为使用hibernateTemplate。</em><br />如果你希望更多的了解session, hibernateTemplate, transaction，请继续。<br /><br />
以下案例基于Struts2.3.1+Spring3.1.1+hibernate3.5.4完成，案例场景为对系统参数进行管理，涉及如下四个类：<br />
<table>
     <tbody>
         <tr>
             <td>Action </td>
             <td>PropertyAction</td>
         </tr>
         <tr>
             <td>Service </td>
             <td>PropertyService/PropertyServiceImpl</td>
         </tr>
         <tr>
             <td>DAO </td>
             <td>PropertyDAO（继承HibernateDaoSupport）</td>
         </tr>
         <tr>
             <td>Entity </td>
             <td>SysProperty</td>
         </tr>
     </tbody>
</table><br />1. Action中直接调用dao，未使用getHibernateTemplate<br />
在一个复杂的多层架构系统中，事务控制在service中完成是更合理的，不应交由view层来控制，本文假定你是这么做的。一般我们代码的处理顺序为action-&gt;service-&gt;dao，然而总会有人会打破这种逻辑，打破可以，但要注意如下问题。<br />
假定Action中有如下代码：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">@Autowired<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;PropertyDAO&nbsp;propertyDAO;<br />
</span><span style="color: #008080; ">3</span>&nbsp;<span style="color: #000000; ">@Override<br />
</span><span style="color: #008080; ">4</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;String&nbsp;execute()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
</span><span style="color: #008080; ">5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;model&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;propertyDAO.get(</span><span style="color: #000000; ">1L</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br />
</span><span style="color: #008080; ">7</span>&nbsp;<span style="color: #000000; ">}</span></div>
<br />
&nbsp;这里action直接访问了dao中的get方法，因事务配置在service层，因此这里是没有事务控制的。<br />
接下来我们看dao中的get方法，假定你的定义如下：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;SysProperty&nbsp;get(Long&nbsp;id)&nbsp;{<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000FF; ">return</span><span style="color: #000000;">&nbsp;(SysProperty)&nbsp;getSession().get(SysProperty.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">,&nbsp;id);<br />
</span><span style="color: #008080; ">3</span>&nbsp;<span style="color: #000000; ">}</span></div>
<br />
代码很简单，getSession是父类HibernateDaoSupport中提供的方法，这里直接通过实体Id get得到结果。<br />
接下来发布一下系统，访问页面，好像一切OK，但是，再刷新几下看看，可能你的连接池配置的比较大，要刷新多次，最后你发会现你的系统停止了响应。更直接点，调用你采用的连接池中的相关API检测下当前连接占用情况，你会发现刷新一次，被占用连接增加一个，可怕的事情发生了。<br />
<strong>小结：在无事务管理器控制的情况下，通过getSession()打开的session不会被关闭，这个session所占用的数据库连接也不会被释放。</strong><br /><br />
接下来，来点更可怕的，假设你的action中是这样的：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #0000ff;">private</span><span style="color: #000000; ">&nbsp;List</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Long</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;ids;<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">@Override<br />
</span><span style="color: #008080; ">3</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;String&nbsp;execute()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
</span><span style="color: #008080; ">4</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(Long&nbsp;id:&nbsp;ids)&nbsp;{<br />
</span><span style="color: #008080; ">5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp; results.add(propertyDAO.get(id));<br />
</span><span style="color: #008080; ">6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;}<br />
</span><span style="color: #008080; ">7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br />
</span><span style="color: #008080; ">8</span>&nbsp;<span style="color: #000000; ">}<br />
</span><span style="color: #008080; ">9</span>&nbsp;<span style="color: #000000; "></span></div>
这时尝试一次传入多个id进行请求，请求结束后检查下连接数，你发现传入多少ID，就有多少连接被占用，也就是说每一次对dao的get调用都会占用一个不可释放的连接。<br />
<strong>小结：如果没有配置事务管理器且直接使用getSession得到session，每次getSession都会创建一个新的session，每个session占用一个新的数据库连接，session无线程级别的共享。</strong><br />
<br />
<div>2. Action中直接调用dao，使用getHibernateTemplate</div>
当然，你可能没遇到过前面的情况，因为你会在DAO中这样写代码：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;SysProperty&nbsp;get(Long&nbsp;id)&nbsp;{<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;getHibernateTemplate().get(getEntityClass(),&nbsp;id);<br />
</span><span style="color: #008080; ">3</span>&nbsp;<span style="color: #000000;">}</span></div>
那么是否就一切OK呢？如果只是想解决连接泄漏这个问题的话，答案是Yes，尝试多次请求，检查下你的连接池状况，没有连接泄漏的情况出现。所以简单而可靠的办法就是不再直接使用getSession，而是使用getHibernateTemplate进行相应操作，当需要使用session时，可以用下面的方法：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">getHibernateTemplate().execute(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;HibernateCallback</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">()&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> T doInHibernate(Session&nbsp;session)&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;HibernateException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;queryObject&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;session.createQuery(hql);<br />
&nbsp;&nbsp;&nbsp; //....<br />
&nbsp;&nbsp;}<br />
});<br />
</span></div>
But...如果你的系统真的出现了连接泄漏，可能你需要关注更多。<br />
还是前面Action中根据ID循环查询的操作，在这个案例中，每一次Dao的get方法都将重复这样的逻辑：创建session，分配session一个连接，关闭session，释放session占用的连接，也就是说session不会在线程级别共享。让我们继续，进入第三种情况来进一步说明。<br />
<br />
3. Service未合理配置事务管理器<br />
绝大部分情况下我们会给service配置事务管理器，可能是通过xml或是@Transactional注解，但并非配置了就OK了。看下面的例子：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">
<div>@Transactional</div>
public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;PropertyServiceImpl&nbsp;</span><span style="color: #0000FF; ">implements</span><span style="color: #000000; ">&nbsp;PropertyService&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;PropertyDAO&nbsp;propertyDAO;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@PostConstruct<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;init(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;propertyDAO.get(</span><span style="color: #000000; ">1L</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; "><img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">}</span></div>
当然，假定你的DAO还是写成了这样：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;SysProperty&nbsp;get(Long&nbsp;id)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(SysProperty)&nbsp;getSession().get(SysProperty.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">,&nbsp;id);<br />
}</span></div>
你期望在service初始化好后做一些数据库操作，你也给service配置了事务管理器，接下来你启动应用，然后检查连接池中的连接数，你会发现有连接未被释放！可能你会果断的修改dao中的方法：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;SysProperty&nbsp;get(Long&nbsp;id)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000;">&nbsp;getHibernateTemplate().get(getEntityClass(),&nbsp;id);<br />}<br /></span></div>然后你会理所当然的认为，即使配置了事务管理器，依然不能使用getSession()，事实可能并非如此。<br />我们调整一下代码，不在init中调用dao中的get方法，改为如下：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;SysProperty&nbsp;getProperty(Long&nbsp;id)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000;">&nbsp;propertyDAO.get(id);<br />}<br /></span></div>然后DAO继续使用<span style="color: #000000; ">(SysProperty)&nbsp;getSession().get(SysProperty.</span><span style="color: #0000FF; ">class</span><span style="color: #000000;">,&nbsp;id)</span>，而action中的调用修改为：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">@Autowired<br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;PropertyService&nbsp;propertyService;<br />@Override<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;String&nbsp;execute()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;model&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;propertyService.getProperty(</span><span style="color: #000000; ">1L</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000;">;<br />}<br /></span></div>重新发布，调用，检查连接数，发现无被占用连接存在。<br /><strong>小结：如果正确配置了事务管理器，getSession是安全的。</strong><br /><br />这时要清楚spring是通过AOP来实现事务控制的，而<span style="color: #000000; ">@PostConstruct</span>方法不会受AOP控制，因此上面的init方法等于无事务管理器。<br />那么再回头来说，是否只要dao中使用getHibernateTemplate就不会有问题呢？<br />假定service中的@PostConstruct方法如下：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">@PostConstruct<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;init(){<br />&nbsp;&nbsp;&nbsp;&nbsp;SysProperty&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;SysProperty();<br />&nbsp;&nbsp;&nbsp;&nbsp;p.setName(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">test_property_1</span><span style="color: #000000; ">"</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;propertyDAO.save(p);<br />}</span></div>强调一下，前面已经提到这个方法不受spring的事务管理器控制。<br />假定DAO中的save方法如下：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000;">&nbsp;save(SysProperty&nbsp;o){<br />&nbsp;&nbsp;&nbsp;&nbsp;getSession().save(o);<br />}</span></div>启动一下应用，检查一下连接数，再检查一下数据是否有存储到数据库中。因为我们直接使用了getSession，因此连接不会释放，这点前面已经提到，但同时我们还将发现数据没有被存储，当然这个也好理解，因为上面已经提到这个方法未配置事务管理器。<br /><strong>小结：通过getSession().save()保存数据时，事务不会自动提交。</strong><br /><br />现在再修改下DAO中的save方法：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;save(SysProperty&nbsp;o){<br />&nbsp;&nbsp;&nbsp;&nbsp;getHibernateTemplate().save(o);<br />}</span></div>启动一下应用，检查一下连接数，再检查一下数据是否有存储到数据库中。因为我们使用hibernateTemplate，因此连接有释放，这点前面已经提到，但同时我们还发现数据也已存储到数据库中，说明hibernateTemplate会自动提交事务。<br /><strong>小结：如果未配置事务管理器，通过hibernateTemplate操作时，会自动创建并提交事务。</strong><br /><br />所以如果你觉得使用hibernateTemplate就OK了，那就要小心下面的代码了：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">@PostConstruct<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;init(){<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">1.&nbsp;从你的账号A中扣除一万块<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">2.&nbsp;这里的代码抛出了异常<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">3.&nbsp;将你的账号B中增加一万块</span><span style="color: #000000; ">&nbsp; <br />}</span></div>如果上面的第2步出现了异常，那么因为1的事务已经提交，而3却没有执行，最终导致了数据的不一致，后果和连接泄漏一样严重！<br />除了@PostConstruct，还有其它原因会导致<span style="color: #0000ff;">@Transactional</span>无效，假定我们的service配置了事务管理器，但存在如下代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">pubic&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;someServiceMethod(){<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Thread(){<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;run(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doSomethingLater();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;doSomethingLater(){<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">做一系列数据库操作</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}</span></div>那么你可以去验证下doSomethingLater是否受事务管理器控制，事实上并不会，所以你需要理解spring AOP的机制，否则一个小坑会酿成灾难。<br />这里还有一种情况，你不是在类上面配置<span style="color: #0000ff;">@Transactional</span>，而是在方法上面配置，假定存在如下的代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">该方法不需要事务控制</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;method1(){<br />&nbsp;&nbsp;&nbsp;&nbsp;method2();<br />}<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">下面的方法需要事务控制</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">@Transactional<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;method2(){<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">do&nbsp;something</span><span style="color: #008000;"><br /></span><span style="color: #000000;">}</span></div>因为你需要给不同的方法配置不同的事务机制，因此你没有在类上面进行配置，然后你在客户端进行了如下调用：service.method1(); method2中的方法会受事务管理吗？可悲的是并不会。<br />上面讲到的线程调用和内部方法调用可以这样来处理：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">@Autowired<br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;ApplicationContext&nbsp;context;&nbsp;&nbsp; <br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> method1(){<br />&nbsp;&nbsp;&nbsp;&nbsp;PropertyService&nbsp;service&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;context.getBean(PropertyService.</span><span style="color: #0000FF; ">class</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;service.method2();<br />}</span></div><strong>小结：注意spring的AOP机制</strong><br /><br /><div>4. Service合理配置事务管理器</div>最后补充一下，如果事务管理器配置正确的话会发生什么。这时不管你是用getSession还是getHibernateTemplate，结果都是一样，session将在thread级别共享，session只有一个。<br /><br />总结：难得这周开始工作变得清闲，上班时间还能写写博客，想想前段日子真是自己何苦为难自己。回到话题，使用getSession没什么大错，因为你本应正确配置事务管理器。使用hibernateTemplate能解决所有连接泄漏的问题，但要小心他可能隐藏的事务问题。另外就是spring中内部方法调用时AOP的问题，创建新线程时的事务问题。最后希望这篇有点绕的文章能给你带来帮助。</div><img src ="http://www.blogjava.net/terryxue/aggbug/390930.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2012-11-07 16:32 <a href="http://www.blogjava.net/terryxue/archive/2012/11/07/390930.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse+JUnit测试Seam</title><link>http://www.blogjava.net/terryxue/archive/2011/04/29/349283.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Fri, 29 Apr 2011 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2011/04/29/349283.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/349283.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2011/04/29/349283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/349283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/349283.html</trackback:ping><description><![CDATA[折腾了一天，junit终于可以跑起来了，分享一下，希望对大家能有帮助。<br />
项目基于Maven搭建（Maven确实是个好东西）。使用的技术有jsf + richfaces3.3 + seam2.2 + hibernate3.3 + jasperreport3.7。感觉seam很强大，但没有spring方便，至少在测试方面要花费一翻功夫。<br />
我没有将测试代码放到项目的测试目录下，而是另起了一个工程，专用于测试，以下就完整的介绍一下这个过程。更多是步骤描述了，为什么要这样做就不多解释了，也没能力解释清楚。<br />
1. 建立测试工程：seamtest。最简单的maven工程即可。这里不介绍如何在eclipse中集成maven，读者可以搜搜m2eclipse，这是一个eclipse插件。<br />
<br />
2. 配置seamtest的pom.xml，增加如下三个依赖：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.jboss.seam.embedded</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">hibernate-all</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">beta3.SP10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.jboss.seam.embedded</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jboss-embedded-all</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">beta3.SP10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff;"><br />
&nbsp; &lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">org.jboss.seam.embedded</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">thirdparty-all</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">beta3.SP10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span></div>
<br />
3. 这三个依赖需要从jboss仓库下载，可以访问这个站点：https://repository.jboss.org/nexus/index.html，然后根据上面提供的构件Id进行搜索，或者直接将仓库指向：https://repository.jboss.org/nexus/content/repositories/releases/。如何在settings.xml文件中配置仓库地址不难，google下吧。<br />
<br />
4. 将需要测试的项目及junit加到maven依赖中，我的配置为：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">cn.terry</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">target-web</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0.0.1-SNAPSHOT</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">war</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">junit</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">groupId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">junit</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">artifactId</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">4.8.2</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">version</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">jar</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">type</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">dependency</span><span style="color: #0000FF; ">&gt;</span></div>
上面的&#8220;target-web&#8221;就是我要测试的基于maven构建的项目。<br />
<br />
5. 保存配置后等待eclipse下载完所有依赖的jar包。<br />
<br />
6. 将目标工程加到测试工程的依赖工程中。参考下图：<br />
<img src="http://www.blogjava.net/images/blogjava_net/terryxue/project.jpg" alt="" width="592" border="0" height="426" /><br />
<br />
7. 下载Embedded JBoss，下载地址：<a target="_blank" href="http://sourceforge.net/projects/jboss/files/Embedded%20JBoss/Embedded%20JBoss%20Beta%203/">http://sourceforge.net/projects/jboss/files/Embedded%20JBoss/Embedded%20JBoss%20Beta%203/</a>。<br />
<br />
8. 解压缩下载的压缩后，找到文件夹：bootstrap，除这个文件夹外，其它下载文件在我们这个案例里面都不需要用到。<br />
<br />
9. 将bootstrap文件夹链接到测试工程的source下面，参考如下操作界面：<br />
<img src="http://www.blogjava.net/images/blogjava_net/terryxue/source.jpg" alt="" width="600" border="0" height="434" /><br />
<br />
10. 将target-web的webapp目录链接到测试工程的source下面，这一步比较奇怪，不多解释了，照着做就行了。<br />
<br />
11. 配置DataSource。在bootstrap/deploy下面有文件hsqldb-ds.xml，注意文件名的结尾部分是&#8220;-ds.xml&#8221;，你可以按这个命名规则建立自己需要的datasource文件，如oracle-ds.xml。datasource文件具体怎么写，就要参考hsqldb-ds.xml了，这个还是比较容易的。如果你的项目不需要dataSource的话就跳过这一步吧。<br />
<br />
12. 接下来开始写测试代码了，如下二个类直接复制过去用：<br />
MySeamTestBase: 其它测试类可以直接继承该类<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;cn.terry.test;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.Properties;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.jboss.seam.mock.AbstractSeamTest;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.After;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.AfterClass;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.Before;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.BeforeClass;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.Test;</span><span style="color: #000000; "><br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;MySeamTestBase&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;AbstractSeamTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;static&nbsp;helper&nbsp;instance&nbsp;to&nbsp;call&nbsp;non&nbsp;static&nbsp;methods&nbsp;in<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;a&nbsp;static&nbsp;method</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;MySeamTestBase&nbsp;seamTest&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;MySeamTestBase();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">boolean</span><span style="color: #000000; ">&nbsp;batch&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;JUnit&nbsp;test&nbsp;life&nbsp;cycle&nbsp;methods.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@BeforeClass<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setUpBeforeClass()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">batch)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.startContainer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@AfterClass<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;tearDownAfterClass()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">batch)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.stopContainer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Before<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setUp()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setupClass();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@After<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;tearDown()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleanupClass();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Helper&nbsp;methods<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;starts&nbsp;the&nbsp;JBoss&nbsp;embedded&nbsp;ejb&nbsp;container</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;startContainer()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.startSeam();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;stops&nbsp;the&nbsp;JBoss&nbsp;embedded&nbsp;ejb&nbsp;container</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;stopContainer()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.stopSeam();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">boolean</span><span style="color: #000000; ">&nbsp;isBatch()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;batch;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;used&nbsp;by&nbsp;a&nbsp;JUnit.Suite&nbsp;runner&nbsp;to&nbsp;set&nbsp;the&nbsp;batch&nbsp;flag</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setBatch(</span><span style="color: #0000FF; ">boolean</span><span style="color: #000000; ">&nbsp;fBatch)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;batch&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;fBatch;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
<br />
MySuiteRunner, 批量执行多个测试类：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;cn.terry.test;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.AfterClass;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.BeforeClass;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.runner.RunWith;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.runners.Suite;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;cn.terry.test.testcase.HelloTest;<br />
<br />
&nbsp;<br />
@Suite.SuiteClasses({&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;HelloTest.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; "><br />
})<br />
@RunWith(Suite.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">)<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;MySuiteRunner&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;MySeamTestBase&nbsp;seamTest&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;MySeamTestBase();<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@BeforeClass<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setUpBeforeClass()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;set&nbsp;the&nbsp;flag&nbsp;to&nbsp;signal&nbsp;batch&nbsp;mode</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.setBatch(</span><span style="color: #0000FF; ">true</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.startContainer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@AfterClass<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;tearDownAfterClass()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.stopContainer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seamTest.setBatch(</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
下面的HelloTest是一个具体的测试类，模仿着写就行了：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;cn.terry.test.testcase;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;org.junit.Test;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;cn.terry.test.MySeamTestBase;<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;HelloTest&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;MySeamTestBase&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Test<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;testRollback()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;FacesRequest()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">protected</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;invokeApplication()&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;seamInstance&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;getInstance(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">instanceName</span><span style="color: #000000; ">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.run();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
</span></div>
FacesRequest里面还有许多方法可以重写，自己翻翻手册吧。<br />
<br />
<br />
13. 到执行这一步了，也不容易，如果是jdk6的话，要在运行时加上运行参数：-Dsun.lang.ClassLoader.allowArraySyntax=true。eclipse中如何配置请参考如下界面：<br />
<img src="http://www.blogjava.net/images/blogjava_net/terryxue/run.jpg" alt="" width="397" border="0" height="341" /><br />
点击run，享受成果吧。<br />
<br />
14，可能没有这么幸运，数据库连接池可能没有初始化。在我们的项目中，连接池是在一个servlet listener中初始化的，通过如上方式运行就没法自动初始化，导致测试时出现数据库连接失败的情况，这时候需要自己写些代码去初始化连接了。<br />
<br />
总结：整个过程可能会出现没完没了的异常，别放弃，多google，总会成功的。<br />
<img src ="http://www.blogjava.net/terryxue/aggbug/349283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2011-04-29 17:04 <a href="http://www.blogjava.net/terryxue/archive/2011/04/29/349283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>glassfishv2中ejb的定义与调用</title><link>http://www.blogjava.net/terryxue/archive/2010/03/06/314695.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Sat, 06 Mar 2010 13:08:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2010/03/06/314695.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/314695.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2010/03/06/314695.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/314695.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/314695.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: glassfish中ejb的定义与调用，包括远程调用，本地调用，在web应用中的调用，在javaSE中的调用。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2010/03/06/314695.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/314695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2010-03-06 21:08 <a href="http://www.blogjava.net/terryxue/archive/2010/03/06/314695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js压缩工具</title><link>http://www.blogjava.net/terryxue/archive/2009/12/18/306486.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Fri, 18 Dec 2009 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/18/306486.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306486.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/18/306486.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306486.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306486.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 当客户端代码越来越多时，我们面临着js文件过大的问题，另外你可能也不想将你公司的js代码直接暴露给最终用户，压缩混淆这时变得非常有必要。 yahoo提供了yuicompressor，这是一个非常不错的工具，但还不够好用，我在这个工具的基础上做了些改进，提供了gui界面和基于xml配置文件的批处理压缩功能，这个工具给我的开发工作带来了很大的便利，相信对大家一样会有帮助。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/18/306486.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306486.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-18 10:19 <a href="http://www.blogjava.net/terryxue/archive/2009/12/18/306486.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浏览网页时如何捕获网页内表单提交给服务器的内容</title><link>http://www.blogjava.net/terryxue/archive/2009/12/17/306396.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Thu, 17 Dec 2009 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/17/306396.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306396.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/17/306396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306396.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306396.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 利用js结合firebug得到正在浏览的网页中的表单提交数据时实际将向服务器发送过去的数据。我们利用抓取到的这些数据，可以伪造请求给服务器或达到其它目的。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/17/306396.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-17 17:40 <a href="http://www.blogjava.net/terryxue/archive/2009/12/17/306396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过java抓取任何指定网页的数据</title><link>http://www.blogjava.net/terryxue/archive/2009/12/17/306329.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Thu, 17 Dec 2009 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/17/306329.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306329.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/17/306329.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306329.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 使用java抓取网页内容。你可以利用这种技术实现网站静态化，即生成html页面，你可以伪造表单提交，还可以抓取互联网上任何网页内的部分数据。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/17/306329.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-17 17:31 <a href="http://www.blogjava.net/terryxue/archive/2009/12/17/306329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用java构建http服务器</title><link>http://www.blogjava.net/terryxue/archive/2009/12/17/306328.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Thu, 17 Dec 2009 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/17/306328.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306328.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/17/306328.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306328.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306328.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: web服务器大家都会用，可是它的实现原理是到底如何呢，其实只要读一下http协议，大家基本也能开发出一个简单的web服务器出来了。本文将介绍http协议，并带大家一块来开发一个简单的服务器。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/17/306328.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-17 17:26 <a href="http://www.blogjava.net/terryxue/archive/2009/12/17/306328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp乱码问题剖析与终极解决方案</title><link>http://www.blogjava.net/terryxue/archive/2009/12/17/306326.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Thu, 17 Dec 2009 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/17/306326.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306326.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/17/306326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306326.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 服务器返回乱码页面，请求的数据发送到服务器后取出来是乱码，以上两个问题是web开发人员经常遇到的问题，解决这类问题需要理解乱码问题的根源所在。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/17/306326.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-17 17:20 <a href="http://www.blogjava.net/terryxue/archive/2009/12/17/306326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>功能强大使用方便界面美观的js日历</title><link>http://www.blogjava.net/terryxue/archive/2009/12/17/306323.html</link><dc:creator>terryxue</dc:creator><author>terryxue</author><pubDate>Thu, 17 Dec 2009 09:16:00 GMT</pubDate><guid>http://www.blogjava.net/terryxue/archive/2009/12/17/306323.html</guid><wfw:comment>http://www.blogjava.net/terryxue/comments/306323.html</wfw:comment><comments>http://www.blogjava.net/terryxue/archive/2009/12/17/306323.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/terryxue/comments/commentRss/306323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/terryxue/services/trackbacks/306323.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: B/S系统中总少不了日历控件的使用，网上虽然可以搜到放多，但想找到一个能兼容多种浏览器，功能强大，界面美观的，而且文件还要非常小的日历实在太难了，没办法，只好自己开发一个，在这里给大家分享了。&nbsp;&nbsp;<a href='http://www.blogjava.net/terryxue/archive/2009/12/17/306323.html'>阅读全文</a><img src ="http://www.blogjava.net/terryxue/aggbug/306323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/terryxue/" target="_blank">terryxue</a> 2009-12-17 17:16 <a href="http://www.blogjava.net/terryxue/archive/2009/12/17/306323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>