﻿<?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-Steady's Java Zone-随笔分类-Java</title><link>http://www.blogjava.net/steady/category/23663.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 27 Feb 2011 18:40:13 GMT</lastBuildDate><pubDate>Sun, 27 Feb 2011 18:40:13 GMT</pubDate><ttl>60</ttl><item><title>IntelliJ IDEA 10.0 注册机/注册码/keygen/破解版</title><link>http://www.blogjava.net/steady/archive/2010/12/18/341047.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Sat, 18 Dec 2010 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2010/12/18/341047.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/341047.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2010/12/18/341047.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/341047.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/341047.html</trackback:ping><description><![CDATA[IntelliJ IDEA 10.0 发布了，放出 IntelliJ IDEA 10.0 的注册机下载。<a href="http://www.ok51.cc" target="_blank">点击</a><font color="#002c99"><a href="http://www.steadyxp.com/?p=947"><font color="#002c99">下载</font></a></font> 
<img src ="http://www.blogjava.net/steady/aggbug/341047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2010-12-18 09:56 <a href="http://www.blogjava.net/steady/archive/2010/12/18/341047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp-api.jar 引发的页面编译错误</title><link>http://www.blogjava.net/steady/archive/2009/08/17/291523.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Mon, 17 Aug 2009 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2009/08/17/291523.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/291523.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2009/08/17/291523.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/291523.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/291523.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt">　　为了编译方便我把 servlet-api.jar 和 jsp-api.jar 和其他 jar 包都放在一起，在 ant build 的时候就会一并被拷到 Web 项目的 WEB-INF/lib 下，不过这次因此出现了一个 jsp 页面的编译错误，所有的 jsp 页面打开都会在页面上报编译错误，后台无任何信息。考虑到 jsp 页面的编译可能和 jsp-api.jar 有关，于是将 WEB-INF/lib 下的 servlet-api.jar 和 jsp-api.jar 移走，问题解决。</span></p>
<p><span style="font-size: 10pt">　　后来发现放在里面的这两个包是 tomcat5.5 的，是 JSP 2.0 规范的，而部署的服务器是 tomcat 6.0 是 JSP 2.1 规范的，两者可能有一定的冲突，才导致这样的错误。</span></p>
<img src ="http://www.blogjava.net/steady/aggbug/291523.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2009-08-17 17:22 <a href="http://www.blogjava.net/steady/archive/2009/08/17/291523.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单的玩了下BeanShell</title><link>http://www.blogjava.net/steady/archive/2009/02/26/256741.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Thu, 26 Feb 2009 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2009/02/26/256741.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/256741.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2009/02/26/256741.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/256741.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/256741.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt">　　为了实现工作流中对脚本的支持，简单的玩了一下 BeanShell，这个小小的嵌入式 Java 代码解释器可以将 &nbsp;Java 语言像动态脚本一样执行，几行命令，它就能把一段 Java 代码给玩转。</span></p>
<p><span style="font-size: 10pt">　　工作流中有个这样的简单案例，当一笔单子金额大于 50万时，应该将任务分配给 Senior Agent 处理，否则交给 Junior Agent 处理，我们用 BeanShell 简单模拟这段脚本。</span></p>
<p><em><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Interpreter i = new Interpreter();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i.set(&#8221;price&#8221;, 1000000);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i.set(&#8221;user&#8221;, &#8220;&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i.eval(&#8221;if(price &gt; 500000)\n&#8221; +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;user = \&#8221;SeniorAgent\&#8221;;\n&#8221; +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;else \n&#8221; +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;user = \&#8221;JuniorAgent\&#8221;;&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(i.get(&#8221;user&#8221;));<br />
&nbsp;&nbsp;&nbsp; }&nbsp;</span></em></p>
<p><span style="font-size: 10pt">　　运行结果是打印出了：SeniorAgent</span></p>
<p><span style="font-size: 10pt">　　可以看出，BeanShell 用非常动态化的方式，完成了我们一个简单的案例的处理，这里，我们只需要将需要解析的 Java 语言的脚本交给 BeanShell 的 Interceptor，并把脚本中用到的参数值传入，就可以了，最后，我们把运算结果赋给一个变量，然后获取变量结果，就可以了。</span></p>
<p><span style="font-size: 10pt">　　看到 Developer Works 网站上有一篇 BeanShell 实现公式管理的文章：</span><a href="http://www.ibm.com/developerworks/cn/java/l-formula/index.html"><span style="font-size: 10pt">http://www.ibm.com/developerworks/cn/java/l-formula/index.html</span></a><span style="font-size: 10pt">，可以参考一下。<br />
<br />
From: </span><a href="http://www.steadyxp.com/archives/851.html"><span style="font-size: 10pt">http://www.steadyxp.com/archives/851.html</span></a><span style="font-size: 10pt"> <br />
</span></p>
 <img src ="http://www.blogjava.net/steady/aggbug/256741.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2009-02-26 09:56 <a href="http://www.blogjava.net/steady/archive/2009/02/26/256741.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HttpClient连接的强制释放</title><link>http://www.blogjava.net/steady/archive/2009/02/23/256206.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Mon, 23 Feb 2009 05:49:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2009/02/23/256206.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/256206.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2009/02/23/256206.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/256206.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/256206.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>　　服务器上用 HttpClient 远程调用另一台服务器的一些资源，但是用 netstat 查看经常出现了很多的 CLOSE_WAIT 的连接，最后追查原因，是因为 HttpClient 的 method.releaseConnection() 并不是强制释放连接，为了减小连接数，使用了如下解决方案。在 HttpClient 完成请求后的 finally 块里面这么写。</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp; } </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>finally</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>if</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> (method != </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>null</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>) {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>try</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; method.releaseConnection();</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>catch</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> (Exception e) {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><em><span style="font-size: 10pt; color: #0000c0; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #0000c0; font-family: "Courier New";'>logger</span></em><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>.error(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";'>"-------&gt; Release HTTP connection exception:"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>, e);</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>if</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> (client != </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>null</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>) {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>try</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown();</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>catch</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'> (Exception e) {</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><em><span style="font-size: 10pt; color: #0000c0; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #0000c0; font-family: "Courier New";'>logger</span></em><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>.error(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";'>"-------&gt; Close HTTP connection exception:"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>, e);</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client = </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'" mce_style='font-size: 10pt; color: #7f0055; font-family: "Courier New";'>null</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>;</span></p>
<p style="margin: 0cm 0cm 0pt; text-align: left" align="left" mce_style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0cm 0cm 0pt" mce_style="margin: 0cm 0cm 0pt;"><span style="font-size: 10pt; color: black; font-family: 'Courier New'" mce_style='font-size: 10pt; color: black; font-family: "Courier New";'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<br />
原文：<a href="http://www.steadyxp.com/archives/832.html">http://www.steadyxp.com/archives/832.html</a> 
 <img src ="http://www.blogjava.net/steady/aggbug/256206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2009-02-23 13:49 <a href="http://www.blogjava.net/steady/archive/2009/02/23/256206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jBPM 整合 Drools(JBoss Rule) - 整合角色分配</title><link>http://www.blogjava.net/steady/archive/2008/09/05/227236.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Fri, 05 Sep 2008 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2008/09/05/227236.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/227236.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2008/09/05/227236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/227236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/227236.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt">　　jBPM 是一个非常优秀的开源工作流引擎，虽然他不是一个一站式的工作流平台，不过它已经为我们提供了比较丰富的底层操作，为了满足特定的项目需求，我们一般需要对其进行二次开发，才能适用于具体的业务需求。</span></p>
<p><span style="font-size: 10pt">　　其中一个主要的扩展点是针对 TaskNode 进行的用户的分配。TaskNode 是 jBPM 中一个非常重要的概念，一个任务节点可以包含若干个任务，不同的任务可以由不同的人来完成，任务实例被分配给 actorId 来完成，其中指定到人的分配工作就是 Assignment 要处理的，这也是我们需要定制的功能，为了实现用户的分配，我们需要实现 AssignmentHandler 接口，接口原型如下。</span></p>
<p><span style="font-size: 10pt">public interface AssignmentHandler extends Serializable {&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; void assign(Assignable assignable, ExecutionContext executionContext) throws Exception;<br />
}</span></p>
<p><span style="font-size: 10pt">　　通常用代码实现的话，我们可以让一个类实现这个接口，并在 swimlane 或者 tasknode 中的 assignment 指定该类。但是，这样的灵活性是显然不够的，在系统的使用过程中，分配策略会不断的进行调整，因此我们需要更为灵活的解决方案，jBPM 本身可以使用基于 Bean Shell 的脚本来写分配策略，但是 Bean Shell 不是那么强大，我们需要更为强大的解决方案，因此，我们选用了已经被 JBoss 收为旗下的 JBoss Drools 4.0 规则引擎&nbsp;(在 3.0 的时候曾经改名为 JBoss Rules，4.0 又改回来了)</span></p>
<p><span style="font-size: 10pt">　　完整版本请查看：<a href="http://www.steadyxp.com/archives/120.html">http://www.steadyxp.com/archives/120.html</a> </span></p>
 <img src ="http://www.blogjava.net/steady/aggbug/227236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2008-09-05 15:29 <a href="http://www.blogjava.net/steady/archive/2008/09/05/227236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>禁用JavaWeb应用中URL上包含的jsessionid</title><link>http://www.blogjava.net/steady/archive/2007/09/08/143664.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Sat, 08 Sep 2007 12:13:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2007/09/08/143664.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/143664.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2007/09/08/143664.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/143664.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/143664.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt">Java Web 应用似乎总有这样的情况，有事没事总是要在 URL 后面加上个 jsessionid，而且似乎不能使用配置的方式直接禁用 URL 传递 sessionid，这样，就比较容易造成安全性的问题，或者在浏览器地址栏里留下一堆很不好看的地址，在 Struts2 中，使用了 url 标签的所有<a style="color: #8ab037" href="http://www.linkedcast.cn" target="_blank">链接</a>，甚至 CSS, JS 这样的东西，都会加上 jsessionid，如何去禁用呢，搜索国内的相关文章，无功而返，询问我们过去的架构师，也没有做过，只好想办法去找国外的网站，找到了这样的一篇文章。<br />
<br />
http://randomcoder.com/articles/jsessionid-considered-harmful<br />
<br />
通过加入 Filter 的方式过滤掉 URL 中包含的 jsessionid，再重新包装 Response 返回给浏览器。<br />
<br />
因为没有太多东西，就不多解释了，大家拿了用就可以了。<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpServletRequest;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpServletResponse;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpServletResponseWrapper;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpSession;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.IOException;<br />
<br />
</span><span style="color: #008000">/**</span><span style="color: #008000"><br />
&nbsp;*&nbsp;Servlet&nbsp;filter&nbsp;which&nbsp;disables&nbsp;URL-encoded&nbsp;session&nbsp;identifiers.<br />
&nbsp;*&nbsp;&lt;p/&gt;<br />
&nbsp;*&nbsp;&lt;pre&gt;<br />
&nbsp;*&nbsp;Copyright&nbsp;(c)&nbsp;2006,&nbsp;Craig&nbsp;Condit.&nbsp;All&nbsp;rights&nbsp;reserved.<br />
&nbsp;*&nbsp;&lt;p/&gt;<br />
&nbsp;*&nbsp;Redistribution&nbsp;and&nbsp;use&nbsp;in&nbsp;source&nbsp;and&nbsp;binary&nbsp;forms,&nbsp;with&nbsp;or&nbsp;without<br />
&nbsp;*&nbsp;modification,&nbsp;are&nbsp;permitted&nbsp;provided&nbsp;that&nbsp;the&nbsp;following&nbsp;conditions&nbsp;are&nbsp;met:<br />
&nbsp;*&nbsp;&lt;p/&gt;<br />
&nbsp;*&nbsp;&nbsp;&nbsp;*&nbsp;Redistributions&nbsp;of&nbsp;source&nbsp;code&nbsp;must&nbsp;retain&nbsp;the&nbsp;above&nbsp;copyright&nbsp;notice,<br />
&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;list&nbsp;of&nbsp;conditions&nbsp;and&nbsp;the&nbsp;following&nbsp;disclaimer.<br />
&nbsp;*&nbsp;&nbsp;&nbsp;*&nbsp;Redistributions&nbsp;in&nbsp;binary&nbsp;form&nbsp;must&nbsp;reproduce&nbsp;the&nbsp;above&nbsp;copyright&nbsp;notice,<br />
&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;list&nbsp;of&nbsp;conditions&nbsp;and&nbsp;the&nbsp;following&nbsp;disclaimer&nbsp;in&nbsp;the&nbsp;documentation<br />
&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and/or&nbsp;other&nbsp;materials&nbsp;provided&nbsp;with&nbsp;the&nbsp;distribution.<br />
&nbsp;*&nbsp;&lt;p/&gt;<br />
&nbsp;*&nbsp;THIS&nbsp;SOFTWARE&nbsp;IS&nbsp;PROVIDED&nbsp;BY&nbsp;THE&nbsp;COPYRIGHT&nbsp;HOLDERS&nbsp;AND&nbsp;CONTRIBUTORS&nbsp;"AS&nbsp;IS"<br />
&nbsp;*&nbsp;AND&nbsp;ANY&nbsp;EXPRESS&nbsp;OR&nbsp;IMPLIED&nbsp;WARRANTIES,&nbsp;INCLUDING,&nbsp;BUT&nbsp;NOT&nbsp;LIMITED&nbsp;TO,&nbsp;THE<br />
&nbsp;*&nbsp;IMPLIED&nbsp;WARRANTIES&nbsp;OF&nbsp;MERCHANTABILITY&nbsp;AND&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE<br />
&nbsp;*&nbsp;ARE&nbsp;DISCLAIMED.&nbsp;IN&nbsp;NO&nbsp;EVENT&nbsp;SHALL&nbsp;THE&nbsp;COPYRIGHT&nbsp;OWNER&nbsp;OR&nbsp;CONTRIBUTORS&nbsp;BE<br />
&nbsp;*&nbsp;LIABLE&nbsp;FOR&nbsp;ANY&nbsp;DIRECT,&nbsp;INDIRECT,&nbsp;INCIDENTAL,&nbsp;SPECIAL,&nbsp;EXEMPLARY,&nbsp;OR<br />
&nbsp;*&nbsp;CONSEQUENTIAL&nbsp;DAMAGES&nbsp;(INCLUDING,&nbsp;BUT&nbsp;NOT&nbsp;LIMITED&nbsp;TO,&nbsp;PROCUREMENT&nbsp;OF<br />
&nbsp;*&nbsp;SUBSTITUTE&nbsp;GOODS&nbsp;OR&nbsp;SERVICES;&nbsp;LOSS&nbsp;OF&nbsp;USE,&nbsp;DATA,&nbsp;OR&nbsp;PROFITS;&nbsp;OR&nbsp;BUSINESS<br />
&nbsp;*&nbsp;INTERRUPTION)&nbsp;HOWEVER&nbsp;CAUSED&nbsp;AND&nbsp;ON&nbsp;ANY&nbsp;THEORY&nbsp;OF&nbsp;LIABILITY,&nbsp;WHETHER&nbsp;IN<br />
&nbsp;*&nbsp;CONTRACT,&nbsp;STRICT&nbsp;LIABILITY,&nbsp;OR&nbsp;TORT&nbsp;(INCLUDING&nbsp;NEGLIGENCE&nbsp;OR&nbsp;OTHERWISE)<br />
&nbsp;*&nbsp;ARISING&nbsp;IN&nbsp;ANY&nbsp;WAY&nbsp;OUT&nbsp;OF&nbsp;THE&nbsp;USE&nbsp;OF&nbsp;THIS&nbsp;SOFTWARE,&nbsp;EVEN&nbsp;IF&nbsp;ADVISED&nbsp;OF&nbsp;THE<br />
&nbsp;*&nbsp;POSSIBILITY&nbsp;OF&nbsp;SUCH&nbsp;DAMAGE.<br />
&nbsp;*&nbsp;&lt;/pre&gt;<br />
&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
@SuppressWarnings(</span><span style="color: #000000">"</span><span style="color: #000000">deprecation</span><span style="color: #000000">"</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;DisableUrlSessionFilter&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Filter&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">/**</span><span style="color: #008000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Filters&nbsp;requests&nbsp;to&nbsp;disable&nbsp;URL-based&nbsp;session&nbsp;identifiers.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><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;doFilter(ServletRequest&nbsp;request,&nbsp;ServletResponse&nbsp;response,&nbsp;FilterChain&nbsp;chain)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;skip&nbsp;non-http&nbsp;requests</span><span style="color: #008000"><br />
</span><span style="color: #000000">&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">(request&nbsp;</span><span style="color: #0000ff">instanceof</span><span style="color: #000000">&nbsp;HttpServletRequest))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request,&nbsp;response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest&nbsp;httpRequest&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(HttpServletRequest)&nbsp;request;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;httpResponse&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(HttpServletResponse)&nbsp;response;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;clear&nbsp;session&nbsp;if&nbsp;session&nbsp;id&nbsp;in&nbsp;URL</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(httpRequest.isRequestedSessionIdFromURL())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpSession&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;httpRequest.getSession();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(session&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;session.invalidate();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;wrap&nbsp;response&nbsp;to&nbsp;remove&nbsp;URL&nbsp;encoding</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponseWrapper&nbsp;wrappedResponse&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;HttpServletResponseWrapper(httpResponse)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;encodeRedirectUrl(String&nbsp;url)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;url;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;encodeRedirectURL(String&nbsp;url)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;url;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;encodeUrl(String&nbsp;url)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;url;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;encodeURL(String&nbsp;url)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;url;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;process&nbsp;next&nbsp;request&nbsp;in&nbsp;chain</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request,&nbsp;wrappedResponse);<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;Unused.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><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(FilterConfig&nbsp;config)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;ServletException&nbsp;{<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;Unused.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><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;destroy()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
-------------------------------------------------------------------------------------------------<br />
顺便做个小<a style="color: #8ab037" href="http://www.linkedcast.cn" target="_blank">广告</a> <a href="http://www.linkedcast.cn">链客中国</a>&nbsp;<a href="http://www.linkedcast.cn">www.linkedcast.cn</a>&nbsp;上线运行，欢迎广大 Blogger 使用</span> <br />
<a href="http://www.linkedcast.cn" target="_blank"><img alt="链客中国，写文章也可以赚钱哦" src="http://www.linkedcast.cn/website/monitor/access.do?id=9d19090d1a00565f" border="0" /></a> 
   <img src ="http://www.blogjava.net/steady/aggbug/143664.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2007-09-08 20:13 <a href="http://www.blogjava.net/steady/archive/2007/09/08/143664.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2 整合 Discuz 论坛 (1)</title><link>http://www.blogjava.net/steady/archive/2007/08/11/136046.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Sat, 11 Aug 2007 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2007/08/11/136046.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/136046.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2007/08/11/136046.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/136046.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/136046.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 10pt">因为有一个 Struts2 网站发布，需要整合一个论坛来使用，公司的一个项目过去曾经整合过一个英文论坛，但似乎不能满足我们的需求，需要找一个成熟稳定的中文论坛，与我们的系统结合。<br><br>最终选择了 Discuz 作为我们的论坛系统，主要是因为它提供了一套可用的 Passport API，来直接与我们现有系统进行整合。<br><br>下面摘录 Discuz 文档中的内容来说明整合原理，随后的几篇中，将详细描述具体的整合过程。<br><br>
<p class=subtitle>假设已设置如下变量或参数
<p>
<ul>
    <li>挂接 Discuz! Passport 的应用程序假设为一套 PHP 语言编写的 CMS 系统
    <li>Discuz! 的 URL 为 http://www.myforums.com
    <li>应用程序的 URL 为 http://www.mywebsite.com
    <li>应用程序的注册页面为 http://www.mywebsite.com/register.php
    <li>应用程序的登录页面为 http://www.mywebsite.com/login.php?action=login
    <li>应用程序的退出页面为 http://www.mywebsite.com/login.php?action=logout</li>
</ul>
<p class=subtitle>开启通行证后的用户登录流程
<p>
<ul type=1>
    <li>如果用户在论坛点击&#8220;登录&#8221;，则转向到事先设置好的应用程序登录页面（http://www.mywebsite.com/login.php?action=login），并在登录页面的 URL 中加入参数 forward（加入 forward 后的链接例如 http://www.mywebsite.com/login.php?action=login&amp;forward=http://www.myforums.com/index.php），用于在登录后将用户导向到指定的 URL。<br><br>
    <li>应用程序收到此请求后，按照惯例生成表单，并<u>增加一个表单变量，将 GET 方式传递过来的 forward 参数通过表单进行传递。</u><br><br>
    <li>用户在应用程序的表单中填写登录信息，并提交到应用程序的登录验证程序。应用程序验证用户提交的用户名和密码的合法性：
    <ul><br>
        <li>如果不通过：提示用户名密码错误，要求其返回上一页重新填写。<br><br>
        <li>如果通过，需要进行如下操作：
        <ul><br>
            <li>设置自身 Cookie 或 Session，使得应用程序自身处于登录状态。<br><br>
            <li><u>检查表单中是否提交了 forward 变量，如有，则意味着登录请求可能是由论坛而来，将此变量传递到后面的请求中。如没有，自行生成 forward 变量，使得论坛登录后能够跳转回到应用程序中。</u><br><br>
            <li><u>通过 header('Location: http://www.myforums.com/api/passport.php?action=login&amp;auth=xxx&amp;forward=http://yyy&amp;verify=zzz') 的方式，将登录请求传递到论坛进行处理。其中 auth 用来将用户信息与资料以特定的格式，加密传递给论坛，forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址，verify 用于验证前面两个变量的有效性。auth、forward、verify 格式与结构将在后面进行说明。</u></li>
        </ul>
        </li>
    </ul>
    <br><br>
    <li>Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后，进行如下操作：
    <ul><br>
        <li>根据 verify 判断 auth 和 forward 变量是否合法，如合法则继续，否则终止。<br><br>
        <li>将 auth 根据既定算法解密，并还原成数组，数组的内容与格式将在后面进行说明。根据数组中的内容，检查此用户是否存在。如存在，则根据上述数组中的内容 UPDATE 论坛中相应的用户资料。如不存在，则使用数组中的信息 INSERT 到论坛用户资料表中。<br><br>
        <li>论坛设置 Cookie 或 Session，使得论坛自身处于登录状态。<br><br>
        <li>根据应用程序反馈的 forward 值，通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL。</li>
    </ul>
    <br><br>
    <li>至此，登录流程结束</li>
</ul>
<p class=subtitle>开启通行证后的用户退出流程
<p>
<ul type=1>
    <li>如果用户在论坛点击&#8220;退出&#8221;，则转向到事先设置好的应用程序退出页面（http://www.mywebsite.com/login.php?action=logout），并在登录页面的 URL 中加入参数 forward（例如 http://www.mywebsite.com/login.php?action=login&amp;forward=http://www.myforums.com/index.php），用于在退出后将用户导向到指定的 URL。<br><br>
    <li>应用程序收到此请求后，清除自身 Cookie 或 Session，使得应用程序自身处于非登录状态。<br><br>
    <li><u>检查是否提交了 forward 变量，如有，则意味着登录请求可能是由论坛而来，将此变量传递到后面的请求中。如没有，自行生成 forward 变量，使得论坛登录后能够跳转回到应用程序中</u>。<br><br>
    <li><u>通过 header('Location: http://www.myforums.com/api/passport.php?action=logout&amp;forward=http://yyy&amp;verify=zzz') 的方式，将退出请求传递到论坛进行处理。其中 forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址，verify 用于验证 forward 变量的有效性。forward、verify 格式与结构将在后面进行说明</u>。<br><br>
    <li>Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后，进行如下操作：
    <ul><br>
        <li>根据 verify 判断 forward 变量是否合法，如合法则继续，否则终止。<br><br>
        <li>清楚论坛的 Cookie 或 Session，使得论坛自身处于非登录状态。<br><br>
        <li>根据应用程序反馈的 forward 值，通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL。</li>
    </ul>
    <br><br>
    <li>至此，退出流程结束。</li>
</ul>
<p class=subtitle>开启通行证后的用户注册流程
<p>
<ul type=1>
    <li>如果用户在论坛点击&#8220;注册&#8221;，则转向到事先设置好的应用程序注册页面（<a href="http://www.mywebsite.com/register.php"><u><font color=#0000ff>http://www.mywebsite.com/register.php</font></u></a>），并在注册页面的 URL 中加入参数 forward（例如 http://www.mywebsite.com/register.php?forward=http://www.myforums.com/index.php），用于在注册后将用户导向到指定的 URL<br><br>
    <li>应用程序收到此请求后，按照惯例生成表单，并<u>增加一个表单变量，将 GET 方式传递过来的 forward 参数通过表单进行传递</u><br><br>
    <li>用户在应用程序的表单中填写注册信息，并提交到应用程序的注册验证程序。应用程序验证用户提交信息的完整性和合法性：
    <ul><br>
        <li>如果不通过：提示其问题所在，要求其返回上一页重新填写<br><br>
        <li>如果通过，需要进行如下操作：
        <ul><br>
            <li>将用户资料插入到应用程序自身用户数据库中<br><br>
            <li>设置自身 Cookie 或 Session，使得应用程序自身处于登录状态<br><br>
            <li><u>检查表单中是否提交了 forward 变量，如有，则意味着注册请求可能是由论坛而来，将此变量传递到后面的请求中。如没有，自行生成 forward 变量，使得论坛注册后能够跳转回到应用程序中</u><br><br>
            <li><u>通过 header('Location: http://www.myforums.com/api/passport.php?action=login&amp;auth=xxx&amp;forward=http://yyy&amp;verify=zzz') 的方式，将注册请求传递到论坛进行处理。其中 auth 用来将用户信息与资料以特定的格式，加密传递给论坛，forward 用于告知论坛 Passport API 完成自身操作后转向到的 URL 地址，verify 用于验证前面两个变量的有效性。auth、forward、verify 格式与结构将在后面进行说明</u></li>
        </ul>
        </li>
    </ul>
    <br><br>
    <li>Discuz! Passport API 在接收到由应用程序通过 header() 提交过来的请求后，进行如下操作：
    <ul><br>
        <li>根据 verify 判断 auth 和 forward 变量是否合法，如合法则继续，否则终止<br><br>
        <li>将 auth 根据既定算法解密，并还原成数组，数组的内容与格式将在后面进行说明。根据数组中的内容，检查此用户是否存在。如存在，则根据上述数组中的内容 UPDATE 论坛中相应的用户资料。如不存在，则使用数组中的信息 INSERT 到论坛用户资料表中<br><br>
        <li>论坛设置 Cookie 或 Session，使得论坛自身处于登录状态<br><br>
        <li>根据应用程序反馈的 forward 值，通过 header('Location: http://xxx') 的形式将页面跳转到 forward 变量指定的 URL</li>
    </ul>
    <br><br>
    <li>至此，注册流程结束
    <p><strong>本部分中，加下划线显示的部分，是需要对您的应用程序进行更改的部分，事实上，这部分更改会非常容易和方便。</strong></p>
    </li>
</ul>
</span>
 <img src ="http://www.blogjava.net/steady/aggbug/136046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2007-08-11 17:30 <a href="http://www.blogjava.net/steady/archive/2007/08/11/136046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Quartz 项目应用笔记-补充</title><link>http://www.blogjava.net/steady/archive/2007/08/03/134149.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Fri, 03 Aug 2007 01:00:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2007/08/03/134149.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/134149.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2007/08/03/134149.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/134149.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/134149.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt">Reschedule<br>rescheduleJob(<a onclick="javascript:tagshow(event, 'String');" href="javascript:;" target=_self><u><strong><font color=#000066>String</font></strong></u></a> triggerName, String groupName, Trigger newTrigger)</p>
<p style="FONT-SIZE: 10pt">在进行 reschedule 操作的时候，我们通常只需要修改 Trigger 的时间，这时候我们只需要重新 new 一个含有新的 <a onclick="javascript:tagshow(event, 'Schedule');" href="javascript:;" target=_self><u><strong><font color=#000066>Schedule</font></strong></u></a> 时间的 Trigger 对象，reschedule 一下就可以了。</p>
<p style="FONT-SIZE: 10pt">Unschedule<br>unscheduleJob(String triggerName, String groupName)</p>
<p style="FONT-SIZE: 10pt">进行 unschedule 的时候，我们只需要知道名字和 group 就可以了。</p>
<p style="FONT-SIZE: 10pt">进行 Schedule 操作前后，Database 中的相关数据都会被更改，在执行 unschedule 或者该 schedule 已经执行过，数据库中的 trigger 信息都会被删除。</p>
 <img src ="http://www.blogjava.net/steady/aggbug/134149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2007-08-03 09:00 <a href="http://www.blogjava.net/steady/archive/2007/08/03/134149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Quartz 项目应用笔记</title><link>http://www.blogjava.net/steady/archive/2007/08/02/134017.html</link><dc:creator>steady</dc:creator><author>steady</author><pubDate>Thu, 02 Aug 2007 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/steady/archive/2007/08/02/134017.html</guid><wfw:comment>http://www.blogjava.net/steady/comments/134017.html</wfw:comment><comments>http://www.blogjava.net/steady/archive/2007/08/02/134017.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/steady/comments/commentRss/134017.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/steady/services/trackbacks/134017.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt"><a onclick="javascript:tagshow(event, 'Quartz');" href="javascript:;" target=_self><u><strong><font color=#000066>Quartz</font></strong></u></a> 是一个强大的企业级 <a onclick="javascript:tagshow(event, 'Schedule');" href="javascript:;" target=_self><u><strong><font color=#000066>Schedule</font></strong></u></a> 工具，也是目前最好的<a onclick="javascript:tagshow(event, '%BF%AA%D4%B4');" href="javascript:;" target=_self><u><strong><font color=#000066>开源</font></strong></u></a> Schedule 工具，最近因为项目的需要，简单的用到了 Quartz 的一些功能，对项目中使用 Quartz 的一些问题做简单的记录。</p>
<p style="FONT-SIZE: 10pt">在 Quartz 的应用中，我们用到了以下的一些东西，ScheduleFactory, Scheduler, Job, JobDetail, Trigger，简单说明一下他们的用途。</p>
<p style="FONT-SIZE: 10pt">SchedulerFactory 是 Scheduler 的工厂，我们可以从中获得受工厂管理的 Scheduler 对象。<br><br>SchedulerFactory scheduleFactory = new StdSchedulerFactory();<br>Scheduler scheduler = scheduleFactory.getScheduler();</p>
<p style="FONT-SIZE: 10pt">Scheduler 是一个计划集，其中可以包含多个 JobDetail 和 Trigger 组成的计划任务。<br>我们可以从 SchedulerFactory 中取得 Scheduler。</p>
<p style="FONT-SIZE: 10pt">接口Job是每个业务上需要执行的任务需要实现的接口，该接口只有一个方法：<br><br>public interface Job {<br>&nbsp;&nbsp;&nbsp; public void execute(JobExecutionContext context)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws JobExecutionException;<br>}<br><br>我们可以在里面定义我们的 Job 执行逻辑，比如清除过期数据，更新缓存等。</p>
<p style="FONT-SIZE: 10pt">JobDetail描述了一个任务具体的信息，比如名称，组名等等。<br>JobDetail jobDetail = new JobDetail("SayHelloWorldJob", Scheduler.DEFAULT_GROUP, SayHelloWorldJob.class);<br>在上面的构造方法中，第一个是任务的名称，第二个是组名，第三个就是实际当任务需要执行的回调类。</p>
<p style="FONT-SIZE: 10pt">Trigger顾名思义就是触发器，Quartz有个很好的想法就是分离了任务和任务执行的条件。Trigger就是控制任务执行条件的类，当Trigger认为执行条件满足的时刻，Trigger会通知相关的Job去执行。分离的好处是：<br>1.你可以为某个Job关联多个Trigger，其中任何一个条件满足都可以触发job执行，这样可以完成一些组合的高级触发条件<br>2.当Trigger失效后（比如：一个永远都不能满足的条件），你不必去声明一个新的job，代替的是你可以为job关联一个新的Trigger让job可以继续执行。</p>
<p style="FONT-SIZE: 10pt">目前的Quartz实现中，存在两种Trigger,SimpleTrigger和CronTrigger,SimpleTrigger用来完成一些比如固定时间执行的任务，比如：从现在开始1分钟后等等；而CronTrigger(没错，和unix的cron进程的含意一样)用来执行calendar-like的任务，比如：每周五下午3：00，每月最后一天等等。</p>
<p style="FONT-SIZE: 10pt">在我们项目中，都是一些固定时间的 Job，所以只用到了 SimpleTrigger。<br>Trigger trigger = new SimpleTrigger("SayHelloWorldJobTrigger",Scheduler.DEFAULT_GROUP,new Date(),null,0,0L);<br>这个构造方法中，第一个是Trigger的名称，第二个是Trigger的组名，第三个是任务开始时间，第四个是结束时间，第五个是重复次数（使用SimpleTrigger.REPEAT_INDEFINITELY常量表示无限次），最后一个是重复周期（单位是毫秒），那么这样就创建了一个立刻并只执行一次的任务。</p>
<p style="FONT-SIZE: 10pt">但我们定义好了 JobDetail，Job，和 Trigger 后，就可以开始 Schedule 一个 Job 了。</p>
<p style="FONT-SIZE: 10pt">scheduler.scheduleJob(jobDetail, trigger);<br><br>这条语句就是把job和Trigger关联，这样当Trigger认为应该触发的时候就会调用（实际上是Scheduler调用）job.execute方法了。</p>
<p style="FONT-SIZE: 10pt">scheduler.start();<br>千万别忘了加上上面的语句，这条语句通知Quartz使安排的计划生效。</p>
<p style="FONT-SIZE: 10pt">关于execute方法的参数JobExecutionContext<br>JobExecutionContext就和很多Context结尾的类功能一样，提供的运行时刻的上下文环境，JobExecutionContext中有Scheduler,JobDetail,Trigger等很多对象的引用，从而当你在execute方法内部须需要这些对象的时刻提供的便利。</p>
<p style="FONT-SIZE: 10pt">在项目中，我们把需要执行的 Job 相对应的一些信息放在 JobExecutionContext 中，在 Job 执行的时候可以调用。<br><br>jobDetail.getJobDataMap().put(userid, id);<br><br>在 Job 中，我们可以拿到相关的 Context 信息：<br><br>jobExecutionContext.getJobDetail().getJobDataMap().getInt(userid);</p>
<p style="FONT-SIZE: 10pt">JobDetail和Trigger的name和group<br>Scheduler实例对应了很多job和trigger的实例，为了方便的区分，Quartz使用name和group这两个特性，正如你想向的一样，同一个group下不能有两个相同name的JobDetail，Trigger同理，同一个Scheduler下不能有两个相同group的JobDetail,Trigger同理，JobDetail和Trigger的完全限定名为：group + name</p>
<p style="FONT-SIZE: 10pt">为了让服务器重启以后，我们的 Scheduler 信息仍然不丢失，我们通常采用数据库持久化 Scheduler 的信息。<br>DBScript 在 Quartz 的下载包中的：quartz-1.6.0\docs\dbTables 下，选择自己使用的 DB 相应的 Script 导入数据库就可以了。<br>在应用中，我们需要配置一个 quartz.properties 才能正常使用 DB。我们可以在 quartz-1.6.0\examples\example10 中找到该文件的样例，稍作一些修改，就可以放到自己项目源码的根目录下使用了。<br><br>设置 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX 即可启用基于 JDBC 的 Quartz 信息持久化。<br><br>根据项目情况设置以下配置信息：<br>org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX<br>org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate<br>org.quartz.jobStore.useProperties = false<br>org.quartz.jobStore.dataSource = myDS<br>org.quartz.jobStore.tablePrefix = QRTZ_<br>org.quartz.jobStore.isClustered = false</p>
<p style="FONT-SIZE: 10pt">org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver<br>org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/myapplication<br>org.quartz.dataSource.myDS.user = root<br>org.quartz.dataSource.myDS.password =<br>org.quartz.dataSource.myDS.maxConnections = 5</p>
<p style="FONT-SIZE: 10pt">但是光设置了 Database 不够，我们还需要在 Application 启动的时候自动启动 Scheduler 才行，我们只需要简单的写一个 Servlet 的 Listener 并在 web.xml 中声明该 Listener ，在 Servlet 容易启动的时候，Scheduler 就开始自动执行。</p>
<p style="FONT-SIZE: 10pt">public class ScheduleStartListener implements ServletContextListener {<br>&nbsp;&nbsp;&nbsp; public void contextInitialized(ServletContextEvent servletContextEvent) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduleFactory.getScheduler().start();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (SchedulerException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // write log<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp; public void contextDestroyed(ServletContextEvent servletContextEvent) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduleFactory.getScheduler().shutdown();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (SchedulerException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // write log<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</p>
<p style="FONT-SIZE: 10pt">在 web.xml 里面加入以下配置：<br>&lt;listener&gt;<br>&nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.agilejava.scheduler.ScheduleStartListener&lt;/listener-class&gt;<br>&lt;/listener&gt;</p>
<p style="FONT-SIZE: 10pt">以上简单的记录了在项目中关于 Quartz 的一些应用，如果有什么新的使用心得，会在后面继续加入的。</p>
 <img src ="http://www.blogjava.net/steady/aggbug/134017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/steady/" target="_blank">steady</a> 2007-08-02 16:28 <a href="http://www.blogjava.net/steady/archive/2007/08/02/134017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>