﻿<?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-我的JAVA学习笔记</title><link>http://www.blogjava.net/EvanLiu/</link><description>休息，休息</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 18:56:04 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 18:56:04 GMT</pubDate><ttl>60</ttl><item><title>WebSphere下LinkageError解决办法</title><link>http://www.blogjava.net/EvanLiu/archive/2009/03/14/259752.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sat, 14 Mar 2009 12:26:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2009/03/14/259752.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/259752.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2009/03/14/259752.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/259752.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/259752.html</trackback:ping><description><![CDATA[<p>环境：WebSphere 6.l<br />
JRE: WebSphere 6.1 JRE<br />
项目需求：用SUN JDK6自带的JAX-WS创建Web Service。 其中Server端的Web Service接口已发布，我这边的项目直接根据对方提供的WSDL创建Client。<br />
碰到的问题：<br />
当调用javax.xml.ws.Service的构造方法 Service(URL url, QName qName)的时候，报错如下：<br />
<br />
[3/14/09 14:51:53:750 CST] 0000002c SystemErr&nbsp;&nbsp;&nbsp;&nbsp; R Caused by: java.lang.Throwable: java.lang.LinkageError: You are loading old SAAJ from jar:file:/C:/Program%20Files/IBM/SDP70/runtimes/base_v61/lib/j2ee.jar!/javax/xml/soap/MessageFactory.class<br />
&nbsp;at com.sun.xml.ws.api.SOAPVersion.&lt;init&gt;(SOAPVersion.java:184)<br />
&nbsp;at com.sun.xml.ws.api.SOAPVersion.&lt;clinit&gt;(SOAPVersion.java:83)<br />
&nbsp;at java.lang.J9VMInternals.initializeImpl(Native Method)<br />
&nbsp;at java.lang.J9VMInternals.initialize(J9VMInternals.java:177)<br />
&nbsp;at com.sun.xml.ws.api.BindingID.&lt;clinit&gt;(BindingID.java:318)<br />
&nbsp;...(以下省略300字)<br />
Caused by: java.lang.Throwable: java.lang.NoSuchMethodError: javax/xml/soap/MessageFactory.newInstance(Ljava/lang/String;)Ljavax/xml/soap/MessageFactory;<br />
&nbsp;at com.sun.xml.ws.api.SOAPVersion.&lt;init&gt;(SOAPVersion.java:178)<br />
&nbsp;... 21 more</p>
<br />
也就是说，程序先去读取了WebSphere 6.1的j2ee.jar包里的相关类，而没去读取我们真正要用的两个SAAJ jar包：saaj-api.jar和saaj-impl.jar. 结果就出错了。<br />
<br />
IBM上找到的原因及解决办法：<br />
<h1><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/haoaili/0512/">如何在WebSphere中解决jar包冲突</a></h1>
<p>&nbsp;</p>
<p>主要就是把Classloader mode从默认的Parent_First改成Parent_Last，让程序先读自己的class文件以及jar包。<br />
我就照样画葫芦设置了。顺便说一下，关联共享库到应用程序，我无论如何都做不成功。关闭Application,进入Application，关联共享库，关联好了，保存成功，退到外面，再进去，共享库又没关联上。设置Classloader mode的时候也遇到了这样的问题，但最终还是迫使其让我保存了。共享库就不管理，反正无所谓，只要加载顺序变了就成。<br />
但事实上，我的担心成为了事实：程序启动失败，虽然起来了，但只跑了一小部分代码，后面的服务都没起来。想想也是，程序那么大，用到的jar包那么多，改了Classloader mode，一切全都乱套了...</p>
<p>之后，查看Console--&gt;TroubleShooting--&gt;Class Loader View，发现系统最开始加载的是WebSphere下的ext目录下的jar包</p>
<h1><img height="644" alt="" src="http://www.blogjava.net/images/blogjava_net/evanliu/22222.JPG" width="918" border="0" />、</h1>
<p>所以就投机取巧，把我要用的两个saaj包放到了ext目录下，重启，程序运行成功<br />
当然，这不是一个好的解决办法，阿三那里能不能通得过还是个问题</p>
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script><script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
<img src ="http://www.blogjava.net/EvanLiu/aggbug/259752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2009-03-14 20:26 <a href="http://www.blogjava.net/EvanLiu/archive/2009/03/14/259752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ThreadLocal学习</title><link>http://www.blogjava.net/EvanLiu/archive/2009/02/18/255272.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Wed, 18 Feb 2009 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2009/02/18/255272.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/255272.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2009/02/18/255272.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/255272.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/255272.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ThreadLocal 多线程&nbsp;&nbsp;<a href='http://www.blogjava.net/EvanLiu/archive/2009/02/18/255272.html'>阅读全文</a><img src ="http://www.blogjava.net/EvanLiu/aggbug/255272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2009-02-18 16:28 <a href="http://www.blogjava.net/EvanLiu/archive/2009/02/18/255272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.ConcurrentModificationException</title><link>http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sun, 31 Aug 2008 11:44:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/224453.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/224453.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/224453.html</trackback:ping><description><![CDATA[工作中碰到个ConcurrentModificationException。代码如下：<br />
<span style="color: #0000ff">List list = ...;<br />
for(Iterator iter = list.iterator(); iter.hasNext();) {<br />
&nbsp;&nbsp;&nbsp; Object obj = iter.next();<br />
&nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp; if(***) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.remove(obj);<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
</span>在执行了remove方法之后，再去执行循环，iter.next()的时候，报java.util.ConcurrentModificationException(当然，如果remove的是最后一条，就不会再去执行next()操作了)<br />
<br />
下面来看一下源码<br />
<span style="color: #0000ff">public interface Iterator&lt;E&gt; {<br />
&nbsp;&nbsp;&nbsp; boolean hasNext();<br />
&nbsp;&nbsp;&nbsp; E next();<br />
&nbsp;&nbsp;&nbsp; void remove();<br />
}<br />
<br />
public interface Collection&lt;E&gt; extends Iterable&lt;E&gt; {<br />
&nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp; Iterator&lt;E&gt; iterator();<br />
&nbsp;&nbsp;&nbsp; boolean add(E o);<br />
&nbsp;&nbsp;&nbsp; boolean remove(Object o);<br />
&nbsp;&nbsp;&nbsp; ...<br />
}</span><br />
这里有两个remove方法<br />
<br />
接下来来看看AbstractList<br />
<span style="color: #0000ff">public abstract class AbstractList&lt;E&gt; extends AbstractCollection&lt;E&gt; implements List&lt;E&gt; {&nbsp; <br />
//AbstractCollection和List都继承了Collection<br />
&nbsp;&nbsp;&nbsp; protected transient int modCount = 0;<br />
&nbsp;&nbsp;&nbsp; private class Itr implements Iterator&lt;E&gt; {&nbsp; //内部类Itr<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int cursor = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lastRet = -1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int expectedModCount = modCount;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public boolean hasNext() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return cursor != size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public E next() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checkForComodification();&nbsp; <span style="color: #ff0000">//特别注意这个方法<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; E next = get(cursor);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastRet = cursor++;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return next;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch(IndexOutOfBoundsException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checkForComodification();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new NoSuchElementException();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void remove() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (lastRet == -1)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalStateException();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checkForComodification();<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AbstractList.this.remove(lastRet);&nbsp; <span style="color: #ff0000">//执行remove对象的操作<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (lastRet &lt; cursor)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cursor--;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastRet = -1;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expectedModCount = modCount;&nbsp; <span style="color: #ff0000">//重新设置了expectedModCount的值，避免了ConcurrentModificationException的产生<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch(IndexOutOfBoundsException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ConcurrentModificationException();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final void checkForComodification() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (modCount != expectedModCount)&nbsp; <span style="color: #ff0000">//当expectedModCount和modCount不相等时，就抛出ConcurrentModificationException</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ConcurrentModificationException();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
}</span><br />
<br />
remove(Object o)在ArrayList中实现如下：<br />
<span style="color: #0000ff">public boolean remove(Object o) {<br />
&nbsp;&nbsp;&nbsp; if (o == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; size; index++)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (elementData[index] == null) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fastRemove(index);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; size; index++)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (o.equals(elementData[index])) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fastRemove(index);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return false;<br />
}<br />
private void fastRemove(int index) {<br />
&nbsp;&nbsp;&nbsp; modCount++;&nbsp; <span style="color: #ff0000">//只增加了modCount<br />
</span>&nbsp;&nbsp;&nbsp; ....<br />
}<br />
<span style="color: #339966"><br />
<strong style="color: #800000">所以，产生ConcurrentModificationException的原因就是：<br />
执行remove(Object o)方法之后，modCount和expectedModCount不相等了。然后当代码执行到next()方法时，判断了checkForComodification()，发现两个数值不等，就抛出了该Exception。<br />
要避免这个Exception，就应该使用remove()方法。</strong></span><strong><br />
</strong></span>这里我们就不看add(Object o)方法了，也是同样的原因，但没有对应的add()方法。一般嘛，就另建一个List了<br />
<br />
<br />
下面是网上的其他解释，更能从本质上解释原因：<br />
Iterator 是工作在一个独立的线程中，并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表，当原来的对象数量发生变化时，这个索引表的内容不会同步改变，所以当索引指针往后移动的时候就找不到要迭代的对象，所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。<br />
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象， Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。<br />
<br />
<a href="http://gceclub.sun.com.cn/yuanchuang/week-14/iterator.html">http://gceclub.sun.com.cn/yuanchuang/week-14/iterator.html</a> <br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script><script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
 <img src ="http://www.blogjava.net/EvanLiu/aggbug/224453.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-08-31 19:44 <a href="http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>物化视图(Materialized View)基础</title><link>http://www.blogjava.net/EvanLiu/archive/2008/08/09/218295.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sat, 09 Aug 2008 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/08/09/218295.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/218295.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/08/09/218295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/218295.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/218295.html</trackback:ping><description><![CDATA[物化视图（实体化视图）是包括一个查询结果的数据库对象，它是远程<clk>数据的的本地副本，或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据，也可以称为快照。<br />
所以物化视图和视图的最大区别是，物化视图在本地保存数据，而视图只是一些SQL语句而已。视图的好处是简化使用过程，物化视图的好处提高性能，当然也可以简化使用过程。提高查询速度的代价就是放弃一定的数据实时性。<br />
</clk>物化视图可以查询表，视图和其它的物化视图。<br />
<br />
创建物化视图，应先在对于的基础表上创建存储的日志空间：<br />
<span style="color: #0000ff">create materialized view log on tablex</span><br />
<span style="color: #0000ff">tablespace mytestspace</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- 日志空间<br />
<span style="color: #0000ff">with rowid;</span><br />
<br />
然后再创建物化视图：<br />
<span style="color: #0000ff">create materialized vew myfirstmv</span><br />
<span style="color: #0000ff">on prebuild tabley&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- 将物化视图建立在一个已经存在的表上，也可不加这句<br />
<span style="color: #0000ff">tablespace mytestspace</span><br />
<span style="color: #0000ff">build deffered&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- buld clause子句，deffered表示创建时不生成数据，默认为build immediate<br />
<span style="color: #0000ff">refresh fast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- refresh 子句。fast表示只刷新上次刷新之后所作的修改。相对为complete。默认为force<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp; on commit&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- 对基表的DML操作提交的同时进行刷新。默认为on demand<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff">start with to_date('2008-08-08 20:00:00', 'yyyy-mm-dd hh24:mi:ss')&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --第一次刷新时间<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff">next TRUNC(SYSDATE+1)+18/24&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --刷新时间间隔。每两天刷新一次，时间为下午6点<br />
<span style="color: #0000ff">as<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select x1, x2, x3 from tablex</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
删除时，删除物化视图和物化视图日志无顺序要求，不过先删除日志，会使删除物化视图的速度加快很多。<br />
<span style="font-family: 宋体"><font size="3">如果物化视图日志存在的话，物化视图在删除的时候，需要将物化视图日志中所有当前物化视图需要刷新的记录删除掉。这意味着一个DDL的语句中包含着DML的部分。<br />
<br />
以上都没经过实际操作，以后有时间再说<br />
</font></span><br />
<br />
<a href="http://xznsoft.javaeye.com/blog/124000">http://xznsoft.javaeye.com/blog/124000</a><br />
<clk></clk><br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script><script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script><img src ="http://www.blogjava.net/EvanLiu/aggbug/218295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-08-09 15:53 <a href="http://www.blogjava.net/EvanLiu/archive/2008/08/09/218295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JMS简单不完全实现</title><link>http://www.blogjava.net/EvanLiu/archive/2008/08/03/219721.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sun, 03 Aug 2008 10:04:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/08/03/219721.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/219721.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/08/03/219721.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/219721.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/219721.html</trackback:ping><description><![CDATA[如前所述，JMS分两大类：PTP和Pub/Sub<br />
<br />
主要的几个对象：ConnectionFactory、Connection、Destination、Session、MessageProducer、MessageConsumer<br />
其相互关系如下图：<br />
<img height="317" alt="" src="http://www.blogjava.net/images/blogjava_net/evanliu/JMS-OBJECT-OVERVIEW.JPG" width="500" /><br />
<span style="color: #008080"><strong style="font-size: 14pt">1.PTP:</strong></span><br />
简单回顾7个对象：QueueConnectionFactory、QuequeConnection、Queue、QueueSession、QueueSender、QueueReceiver、QueueBrowser<br />
<span style="color: #008080">&nbsp;&nbsp;&nbsp;&nbsp;1)&nbsp;Sender</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366ff">try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//具体怎么得到就不写了，各个系统肯定都不一样，但终究都是通过jdni来获得<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Context&nbsp;jndiContext&nbsp;=&nbsp;new&nbsp;InitialContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueConnectionFactory&nbsp;factory&nbsp;=&nbsp;jndiContext.lookup("**Factory");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue&nbsp;queue&nbsp;=&nbsp;jndiContext.lookup("**Queue");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueConnection&nbsp;connection&nbsp;=&nbsp;factory.createQueueConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;transaction&nbsp;=&nbsp;true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueSession&nbsp;session&nbsp;=&nbsp;connection.createQueueSession(transaction&nbsp;,&nbsp;Session.AUTO_ACKNOWLEDGE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Message&nbsp;objMessage&nbsp;=&nbsp;session.createObjectMessage();&nbsp;&nbsp;//或session.createTextMessage("...");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objMessage.setObject((Serializable)obj);&nbsp;//obj为要传输的对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueSender&nbsp;sender&nbsp;=&nbsp;session.createSender(queue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher.setTimeToLive(timeout);&nbsp;//long&nbsp;timeout&nbsp;=&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sender.send(objMessage);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//or<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sender&nbsp;=&nbsp;session.createSender(null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sender.send(queue,&nbsp;message);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果不用了，就收拾干净<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;finally&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher&nbsp;=&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;=&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection&nbsp;=&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080">2)&nbsp;Receiver/Browser</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.主动接收，synchronously<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366ff">try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueReceiver&nbsp;receiver&nbsp;=&nbsp;session.createReceiver(queue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;receiver.receiveNoWait();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueBrowser&nbsp;browser&nbsp;=&nbsp;session.createBrowser(queue);&nbsp;//QueueBrowser只会取消息，但不会取走消息<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enumeration&nbsp;elements&nbsp;=&nbsp;browser.getEnumeration();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(elements.hasMoreElements)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Message&nbsp;message&nbsp;=&nbsp;elements.nextElement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.消息侦听，也是最主要的应用，asynchronously<span style="color: #3366ff"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageListener&nbsp;myListener&nbsp;=&nbsp;new&nbsp;MyListener();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueueReceiver&nbsp;receiver&nbsp;=&nbsp;session.createReceiver(queue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;receiver.setMessageListener(myListener);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&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;public&nbsp;class&nbsp;MyListener&nbsp;impelments&nbsp;MessageListner&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onMessage(Message&nbsp;message)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(message&nbsp;instanceof&nbsp;TextMessage)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(message&nbsp;instanceof&nbsp;ObjectMessage)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
<span style="color: #008080"><strong style="font-size: 14pt">2.Pub/Sub:</strong></span><br />
简单回顾6个对象：TopicConnectionFactory、TopicConnection、Topic、TopicSession、TopicPublisher、TopicSubscriber<br />
<span style="color: #008080">&nbsp;&nbsp;&nbsp;&nbsp;1)&nbsp;Publisher</span><br />
&nbsp;&nbsp;<span style="color: #3366ff">&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//具体怎么得到就不写了，各个系统肯定都不一样，但终究都是通过jdni来获得<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Context&nbsp;jndiContext&nbsp;=&nbsp;new&nbsp;InitialContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicConnectionFactory&nbsp;factory&nbsp;=&nbsp;jndiContext.lookup("**Factory");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Topic&nbsp;topic&nbsp;=&nbsp;jndiContext.lookup("**Topic");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicConnection&nbsp;connection&nbsp;=&nbsp;factory.createTopicConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicSession&nbsp;session&nbsp;=&nbsp;connection.createTopicSession(false,&nbsp;Session.AUTO_ACKNOWLEDGE);&nbsp;&nbsp;//false表示不使用事务<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Message&nbsp;objMessage&nbsp;=&nbsp;session.createObjectMessage();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objMessage.setObject((Serializable)obj);&nbsp;//obj为要传输的对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicPublisher&nbsp;publisher&nbsp;=&nbsp;session.createPublisher(topic);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher.setTimeToLive(100000);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher.publish(message);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//or<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher&nbsp;=&nbsp;session.createPublisher(null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publiser.publish(topic,&nbsp;message);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publisher.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//TODO<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
<span style="color: #008080">&nbsp;&nbsp;&nbsp;&nbsp;2)&nbsp;Subscriber</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.主动接收，比如上面发送完后，接收回应消息，相当于同步接收了<br />
<span style="color: #3366ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicSubscriber&nbsp;subscriber&nbsp;=&nbsp;session.createSubScriber(topic);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message&nbsp;=&nbsp;subscriber.receiver(timeout);&nbsp;//long&nbsp;timeout&nbsp;=&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subscriber.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.消息侦听，asynchronously<br />
<span style="color: #3366ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TopicSubscriber&nbsp;subscriber&nbsp;=&nbsp;session.createSubScriber(topic);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageListener&nbsp;listener&nbsp;=&nbsp;new&nbsp;MyListener();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subscriber.setMessageListener(listener);&nbsp;//关键在于这个listener<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(JMSException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyListener实现同上 
<br />
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script><script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script><img src ="http://www.blogjava.net/EvanLiu/aggbug/219721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-08-03 18:04 <a href="http://www.blogjava.net/EvanLiu/archive/2008/08/03/219721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JMS基本概念（转）</title><link>http://www.blogjava.net/EvanLiu/archive/2008/08/03/213934.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sun, 03 Aug 2008 09:51:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/08/03/213934.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/213934.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/08/03/213934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/213934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/213934.html</trackback:ping><description><![CDATA[<h3><span style="color: #3064ff;">1.JMS概述</span></h3>
JAVA 消息服务(JMS)定义了Java 中访问消息中间件的接口。JMS只是接口，并没有给予实现，实现JMS接口的消息中间件称为JMS
Provider<br />
<br />
消息中间件提供企业数据的异步传输，通过消息中间件，一些原本互相孤立的业务组件可以组合成一个可靠的、灵活的系统。也可以模拟实现同步传输，但其实质仍然是异步的。<br />
<br />
<p>JMS 支持两种消息类型PTP （Point-to-Point）和Pub/Sub（Publish-Subscribe），分别称作：PTP Domain 和Pub/Sub
Domain。<br />
PTP的主要特点是：<br />
1）一条消息只有一个使用者<br />
2）不存在时间限制<br />
Pub/Sub主要特点有：<br />
1）一条消息可以有多个使用者<br />
2）存在时间限制。订阅者可以使用持久方式来订阅消息，但是也会过期或者取消订阅<br />
</p>
<p>这两种接口都继承统一的JMS Parent 接口，JMS 主要接口如下所示：</p>
<div>
<table border="1">
    <colgroup><col><col><col></colgroup>
    <tbody>
        <tr>
            <td><strong>JMS Parent </strong></td>
            <td><strong>PTPDomain</strong></td>
            <td><strong>Pub/Sub Domain </strong></td>
        </tr>
        <tr>
            <td>ConnectionFactory</td>
            <td>QueueConnectionFactory</td>
            <td>TopicConnectionFactory</td>
        </tr>
        <tr>
            <td>Connection</td>
            <td>QueueConnection</td>
            <td>TopicConnection</td>
        </tr>
        <tr>
            <td>Destination</td>
            <td>Queue</td>
            <td>Topic</td>
        </tr>
        <tr>
            <td>Session</td>
            <td>QueueSession</td>
            <td>TopicSession</td>
        </tr>
        <tr>
            <td>MessageProducer</td>
            <td>QueueSender</td>
            <td>TopicPublisher</td>
        </tr>
        <tr>
            <td>MessageConsumer</td>
            <td>QueueReceiver,QueueBrowser</td>
            <td>TopicSubscriber</td>
        </tr>
    </tbody>
</table>
</div>
<p>以下是对这些接口的简单描述：</p>
<p>ConnectionFactory ：连接工厂，JMS 用它创建连接</p>
<p>Connection ：JMS 客户端到JMS Provider 的连接</p>
<p>Destination ：消息的目的地</p>
<p>Session： 一个发送或接收消息的线程</p>
<p>MessageProducer： 由Session 对象创建的用来发送消息的对象</p>
<p>MessageConsumer： 由Session 对象创建的用来接收消息的对象</p>
<p><br />
</p>
<h3><span style="color: #3064ff;">2.JMS消息模型</span></h3>
<p>JMS 消息由以下几部分组成：消息头，属性，消息体。</p>
<p><span><strong>消息头(Header)
</strong></span>-消息头包含消息的识别信息和路由信息，消息头包含一些标准的属性如：JMSDestination,JMSMessageID等。</p>
<div>
<table border="1">
    <colgroup><col><col></colgroup>
    <tbody>
        <tr>
            <td><strong>消息头</strong></td>
            <td><strong>由谁设置</strong></td>
        </tr>
        <tr>
            <td>JMSDestination</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSDeliveryMode</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSExpiration</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSPriority</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSMessageID</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSTimestamp</td>
            <td>send 或 publish 方法</td>
        </tr>
        <tr>
            <td>JMSCorrelationID</td>
            <td>客户</td>
        </tr>
        <tr>
            <td>JMSReplyTo</td>
            <td>客户</td>
        </tr>
        <tr>
            <td>JMSType</td>
            <td>客户</td>
        </tr>
        <tr>
            <td>JMSRedelivered</td>
            <td>JMS Provider</td>
        </tr>
    </tbody>
</table>
</div>
<p><strong>属性(Properties)</strong>
-除了消息头中定义好的标准属性外，JMS提供一种机制增加新属性到消息头中，这种新属性包含以下几种：</p>
<div>
<ol type="1">
    <li>
    <p>应用需要用到的属性;</p>
    </li>
    <li>
    <p>消息头中原有的一些可选属性;</p>
    </li>
    <li>
    <p>JMS Provider 需要用到的属性。</p>
    </li>
</ol>
</div>
<p>标准的JMS 消息头包含以下属性：</p>
<p>JMSDestination --消息发送的目的地。</p>
<p>JMSDeliveryMode
--传递模式，
有两种模式：PERSISTENT和NON_PERSISTENT，PERSISTENT表示该消息一定要被送到目的地，否则会导致应用错误。
NON_PERSISTENT表示偶然丢失该消息是被允许的，这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到平衡点。</p>
<p>JMSMessageID 唯一识别每个消息的标识，由JMS Provider 产生。</p>
<p>JMSTimestamp 一个消息被提交给JMS Provider 到消息被发出的时间。</p>
<p>JMSCorrelationID 用来连接到另外一个消息，典型的应用是在回复消息中连接到原消息。</p>
<p>JMSReplyTo 提供本消息回复消息的目的地址。</p>
<p>JMSRedelivered如果一个客户端收到一个设置了JMSRedelivered属性的消息，则表示可能该客户端曾经在早些时候收到过该消息，但并没有签收(acknowledged)。</p>
<p>JMSType 消息类型的识别符。</p>
<p>JMSExpiration 消息过期时间，等于QueueSender
的send方法中的timeToLive值或TopicPublisher 的publish
方法中的timeToLive值加上发送时刻的GMT时间值。如果timeToLive值等于零，则JMSExpiration被设为零，表示该消息永不过期。如果发送后，在消息过期时间之后消息还没有被发送到目的地，则该消息被清除。</p>
<p>JMSPriority 消息优先级，从0-9 十个级别，0-4 是普通消息，5-9 是加急消息。JMS 不要求JMS
Provider严格按照这十个优先级发送消息，但必须保证加急消息要先于普通消息到达。</p>
<p><strong>消息体(Body)</strong> - JMS
API定义了5种消息体格式，也叫消息类型，你可以使用不同形式发送接收数据并可以兼容现有的消息格式，下面描述这5种类型：</p>
<div>
<table border="1">
    <colgroup><col><col></colgroup>
    <tbody>
        <tr>
            <td><strong>消息类型</strong></td>
            <td><strong>消息体</strong></td>
        </tr>
        <tr>
            <td>TextMessage</td>
            <td>java.lang.String对象，如xml文件内容</td>
        </tr>
        <tr>
            <td>MapMessage</td>
            <td>名/值对的集合，名是String对象，值类型可以是Java任何基本类型</td>
        </tr>
        <tr>
            <td>BytesMessage</td>
            <td>字节流</td>
        </tr>
        <tr>
            <td>StreamMessage</td>
            <td>Java中的输入输出流</td>
        </tr>
        <tr>
            <td>ObjectMessage</td>
            <td>Java中的可序列化对象</td>
        </tr>
        <tr>
            <td>Message</td>
            <td>没有消息体，只有消息头和属性</td>
        </tr>
    </tbody>
</table>
</div>
<p>Message是以上5类的基础。最常用的是ObjectMessage和TextMessage<br />
</p>
<h3><span style="color: #3064ff;">3.消息的同步异步接收</span></h3>
<p><strong>消息的同步接收</strong></p>
<p>同步接收是指客户端主动去接收消息，JMS
客户端可以采用MessageConsumer的receive方法去接收下一个消息。</p>
<p><strong>消息的异步接收</strong></p>
<p>异步接收是指当消息到达时，主动通知客户端。JMS客户端可以通过注册一个实现MessageListener接口的对象到MessageConsumer，这样，每当消息到达时，JMS
Provider 会调用MessageListener中的onMessage 方法。</p>
<h3><span style="color: #3064ff;">4.PTP模型</span></h3>
<p>PTP(Point-to-Point)模型是基于队列的，发送方发消息到队列，接收方从队列接收消息，队列的存在使得消息的异步传输成为可能。和邮件系统中的邮箱一样，队列可以包含各种消息，JMS
Provider 提供工具管理队列的创建、删除。JMS
PTP模型定义了客户端如何向队列发送消息，从队列接收消息，浏览队列中的消息。</p>
<p>下面描述JMS PTP 模型中的主要概念和对象：</p>
<div>
<table border="1">
    <colgroup><col><col></colgroup>
    <tbody>
        <tr>
            <td><strong>名称</strong></td>
            <td><strong>描述</strong></td>
        </tr>
        <tr>
            <td>Queue</td>
            <td>由JMS Provider
            管理，队列由队列名识别，客户端可以通过JNDI接口用队列名得到一个队列对象。</td>
        </tr>
        <tr>
            <td>TemporaryQueue</td>
            <td>由QueueConnection 创建，而且只能由创建它的QueueConnection 使用。</td>
        </tr>
        <tr>
            <td>QueueConnectionFactory</td>
            <td>客户端用QueueConnectionFactory 创建QueueConnection 对象。</td>
        </tr>
        <tr>
            <td>QueueConnection</td>
            <td>一个到JMS PTP provider
            的连接，客户端可以用QueueConnection创建QueueSession来发送和接收消息。</td>
        </tr>
        <tr>
            <td>QueueSession</td>
            <td>提
            供一些方法创建QueueReceiver、QueueSender、QueueBrowser和TemporaryQueue。如果在
            QueueSession关闭时，有一些消息已经被收到，但还没有被签收(acknowledged)，那么，当接收者下次连接到相同的队列时，这些消息
            还会被再次接收。</td>
        </tr>
        <tr>
            <td>QueueReceiver</td>
            <td>客户端用QueueReceiver接收队列中的消息，如果用户在QueueReceiver中设定了消息选择条件，那么不符合条件的消息会留在队列中，不会被接收到。</td>
        </tr>
        <tr>
            <td>QueueSender</td>
            <td>客户端用QueueSender 发送消息到队列。</td>
        </tr>
        <tr>
            <td>QueueBrowser</td>
            <td>客户端可以QueueBrowser 浏览队列中的消息，但不会收走消息。</td>
        </tr>
        <tr>
            <td>QueueRequestor</td>
            <td>JMS
            提供QueueRequestor类简化消息的收发过程。QueueRequestor的构造函数有两个参数：QueueSession和queue，QueueRequestor
            通过创建一个临时队列来完成最终的收发消息请求。</td>
        </tr>
        <tr>
            <td>可靠性(Reliability)</td>
            <td>队列可以长久地保存消息直到接收者收到消息。接收者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态，充分体现了异步传输模式的优势。</td>
        </tr>
    </tbody>
</table>
</div>
<br />
<h3><span style="color: #3064ff;">4.Pub/Sub模型</span></h3>
<p>JMS Pub/Sub 模型定义了如何向一个内容节点发布和订阅消息，这些节点被称作主题(topic)。</p>
<p>主题可以被认为是消息的传输中介，发布者(publisher)发布消息到主题，订阅者(subscribe)从主题订阅消息。主题使得消息订阅者和消息发布者保持互相独立，不需要接触即可保证消息的传送。</p>
<p>下面描述JMS Pub/Sub 模型中的主要概念和对象：</p>
<div>
<table border="1">
    <colgroup><col><col></colgroup>
    <tbody>
        <tr>
            <td><strong>名称 </strong></td>
            <td><strong>描述</strong></td>
        </tr>
        <tr>
            <td>订阅(subscription)</td>
            <td>消息订阅分为非持久订阅(non-durable
            subscription)和持久订阅(durablesubscrip-tion)，非持久订阅只有当客户端处于激活状态，也就是和JMS
            Provider保持连接状态才能收到发送到某个主题的消息，而当客户端处于离线状态，这个时间段发到主题的消息将会丢失，永远不会收到。持久订阅时，客户端向JMS注册一个识别自己身份的ID，当这个客户端处于离线时，JMS
            Provider 会为这个ID 保存所有发送到主题的消息，当客户再次连接到JMS
            Provider时，会根据自己的ID得到所有当自己处于离线时发送到主题的消息。</td>
        </tr>
        <tr>
            <td>Topic</td>
            <td>主题由JMS Provider
            管理，主题由主题名识别，客户端可以通过JNDI接口用主题名得到一个主题对象。JMS没有给出主题的组织和层次结构的定义，由JMS
            Provider 自己定义。</td>
        </tr>
        <tr>
            <td>TemporaryTopic</td>
            <td>临时主题由TopicConnection创建，而且只能由创建它的TopicConnection使用。临时主题不能提供持久订阅功能。</td>
        </tr>
        <tr>
            <td>TopicConnectionFactory</td>
            <td>客户端用TopicConnectionFactory 创建TopicConnection 对象。</td>
        </tr>
        <tr>
            <td>TopicConnection</td>
            <td>TopicConnection 是一个到JMS Pub/Sub
            provider的连接，客户端可以用TopicConnection创建TopicSession来发布和订阅消息。</td>
        </tr>
        <tr>
            <td>TopicSession</td>
            <td>TopicSession提供一些方法创建TopicPublisher、TopicSubscriber、TemporaryTopic。它还提供unsubscribe方法取消消息的持久订阅。</td>
        </tr>
        <tr>
            <td>TopicPublisher</td>
            <td>客户端用TopicPublisher 发布消息到主题。</td>
        </tr>
        <tr>
            <td>TopicSubscriber</td>
            <td>客户端用TopicSubscriber接收发布到主题上的消息。可以在TopicSubscriber中设置消息过滤功能，这样，不符合要求的消息不会被接收。</td>
        </tr>
        <tr>
            <td>Durable TopicSubscriber</td>
            <td>如果一个客户端需要持久订阅消息，可以使用Durable
            TopicSubscriber，TopSession提供一个方法createDurableSubscriber创建Durable
            TopicSubscriber 对象。</td>
        </tr>
        <tr>
            <td>恢复和重新派送(Recovery and Redelivery)</td>
            <td>非持久订阅状态下，不能恢复或重新派送一个未签收的消息。只有持久订阅才能恢复或重新派送一个未签收的消息。</td>
        </tr>
        <tr>
            <td>TopicRequestor</td>
            <td>JMS
            提供TopicRequestor类简化消息的收发过程。TopicRequestor的构造函数有两个参数：TopicSession和topic。TopicRequestor
            通过创建一个临时主题来完成最终的发布和接收消息请求。</td>
        </tr>
        <tr>
            <td>可靠性(Reliability)</td>
            <td>当所有的消息必须被接收，则用持久订阅模式。当丢失消息能够被容忍，则用非持久订阅模</td>
        </tr>
    </tbody>
</table>
</div>
<p><br />
</p>
<br />
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
 <img src ="http://www.blogjava.net/EvanLiu/aggbug/213934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-08-03 17:51 <a href="http://www.blogjava.net/EvanLiu/archive/2008/08/03/213934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAAS学习</title><link>http://www.blogjava.net/EvanLiu/archive/2008/08/02/212749.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sat, 02 Aug 2008 05:52:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/08/02/212749.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/212749.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/08/02/212749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/212749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/212749.html</trackback:ping><description><![CDATA[JAAS：Java Authentication and Authorization Service Java认证和授权服务，从jdk1.4开始就集成JAAS。<br />
目前流行的Acegi中也提供了JAAS<br />
JAAS的几个核心类和接口：<br />
&nbsp; 1.Subject: 实际被认证的人或者服务<br />
&nbsp; 2.Principal (interface): Subject的唯一标识。一个Subject含有一个或多个Pricipal，比如一个人有身份证、护照等Pricipal<br />
&nbsp; 3.LoginContext<br />
&nbsp; 4.LoginModule (interface)<br />
&nbsp; 5.CallbackHandler (interface)<br />
还有两个配置文件：&#215;&#215;&#215;.conf（或config） 和 &#215;&#215;&#215;..policy<br />
JAAS首先使用一个LoginContext类来查找配置文件中的内容，这些内容可以用来对LoginModules进行初始化。所有
LoginContext没有指定的初始化参数都会包含在配置文件中。LoginContext向LoginModule传递一个CallbackHandler对象和一个Subject，如果LoginModule还需要其他认证信息，它就会用CallbackHandler回调适当的应用程序，从而获得这些信息。<br />
<br />
在应用程序中，一般这样使用LoginContext:<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoginContext loginContext = new LoginContext("Sample", callbackHandler );&nbsp; //"Sample"定义在相关的conf文件中; callbackHandler见下面<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loginContext.login();&nbsp; //如果认证失败，则抛出异常<br />
&nbsp;&nbsp;&nbsp; } catch (LoginException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do sth.<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
我们要使用JAAS，就需要实现上述接口，以及配置好文件<br />
上面的代码，只是在应用时，这样写就够了。当然，在这之前，还需要设置callbackHandler：<br />
&nbsp;&nbsp;&nbsp; SampleCallbackHandler callbackHandler = new SampleCallbackHandler();<br />
&nbsp;&nbsp;&nbsp; // 设置用户名、密码等需要验证的信息到callbackHandler里。具体怎么设，看自己的SampleCallbackHandler怎么设计了<br />
&nbsp;&nbsp;&nbsp;&nbsp; ......<br />
<br />
举例：<br />
&nbsp;&nbsp;&nbsp; public class SampleCallbackHandler implements CallbackHandler {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected String username;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected String password;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void handle(Callback[] callbacks)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws UnsupportedCallbackException {&nbsp;&nbsp;&nbsp; //这个方法是必须实现的,用来设置username和password到对应的Callback变量中<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;index&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;callbacks.length;&nbsp;index</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(callbacks[index]&nbsp;</span><span style="color: #0000ff;">instanceof</span><span style="color: #000000;">&nbsp;NameCallback)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NameCallback&nbsp;ncb&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(NameCallback)&nbsp;callbacks[index];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ncb.setName(username);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else </span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(callbacks[index]&nbsp;</span><span style="color: #0000ff;">instanceof</span><span style="color: #000000;">&nbsp;PasswordCallback)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PasswordCallback&nbsp;pcb&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(PasswordCallback)&nbsp;callbacks[index];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pcb.setPassword(password.toCharArray());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if() {&nbsp; //如果还有其他需要验证的信息<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //其他方法，诸如设置username和password<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; 然后来说前面的"Sample"。这里的"Sample"对应一个Sample.conf文件，这个文件的具体位置可以自己设置。conf文件中配置了对应的LoginModule类，可以是一个或多个，用来做不同的验证。<br />
&nbsp;&nbsp;&nbsp; <span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;SampleLoginModule&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;LoginModule&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....<br />
&nbsp;&nbsp;&nbsp; }<br />
</span>LoginModule有5个方法需要实现，简单点写个方法名得了：<br />
public void initialize(Subject subject, CallbackHandler callbackHandler, Map arg2, Map arg3);<br />
public boolean login() throws LoginException;<br />
public boolean commit() throws LoginException;<br />
public boolean abort() throws LoginException;<br />
public boolean logout() throws LoginException;<br />
业务逻辑主要在login()中实现，步骤包括了从callbackHandler中读取用户名密码，然后该从数据库验证就从数据库验证，该从配置文件验证就从配置文件验证，该从其他系统中验证就从其他系统中验证...<br />
<br />
Pricipal的实现就不写了，下面链接中的例子写得很详细。我的只是给自己理一个大概步骤，以后回顾起来也方便<br />
不过Subject和Pricipal应该有更重要的用处，比如在Authorization中，把pricipal和要可以执行的相关操作对应起来。这个还没看下去，接触的代码中也没用到。放到以后补充<br />
<br />
更多内容，可直接查看sun的JDK文档<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html">http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html</a><br />
实例：<a href="http://www.blogjava.net/fastunit/archive/2008/01/28/178204.html">http://www.blogjava.net/fastunit/archive/2008/01/28/178204.html</a><br />
<br />
<br />
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
<img src ="http://www.blogjava.net/EvanLiu/aggbug/212749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-08-02 13:52 <a href="http://www.blogjava.net/EvanLiu/archive/2008/08/02/212749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts validate之ApplicationResources.properties内容读取乱码</title><link>http://www.blogjava.net/EvanLiu/archive/2008/06/16/208276.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Mon, 16 Jun 2008 04:42:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/06/16/208276.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/208276.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/06/16/208276.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/208276.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/208276.html</trackback:ping><description><![CDATA[JSP页面用UTF-8编码<br />
编码过滤器设置成UTF-8编码<br />
配置都正确，在jdk\bin目录下，用native2ascii ApplicationResources.properties ApplicationResources2.properties <br />
结果JSP页面显示提示信息时，提示信息成了乱码。<br />
<br />
解决办法：native2ascii -encoding UTF-8 ApplicationResources.properties ApplicationResources2.properties <br />
<br />
感谢<a href="http://kenshinlk.javaeye.com/blog/59080">http://kenshinlk.javaeye.com/blog/59080</a><br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>


<img src ="http://www.blogjava.net/EvanLiu/aggbug/208276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-06-16 12:42 <a href="http://www.blogjava.net/EvanLiu/archive/2008/06/16/208276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts validate之ValidatorActionForm</title><link>http://www.blogjava.net/EvanLiu/archive/2008/06/15/207964.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sat, 14 Jun 2008 16:58:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/06/15/207964.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/207964.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/06/15/207964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/207964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/207964.html</trackback:ping><description><![CDATA[用Struts Validate机制，因为一个form需要在多个页面进行操作，不同页面会有不同的验证需求，所以我采用了ValidatorActionForm<br />
<br />
代码如下：<br />
public class UserForm extends ValidatorActionForm {<br />
&nbsp;&nbsp;&nbsp; private Integer id;<br />
&nbsp;&nbsp;&nbsp; private String name;<br />
&nbsp;&nbsp;&nbsp; private String password;<br />
&nbsp;&nbsp;&nbsp; private String confirmpwd;<br />
&nbsp;&nbsp;&nbsp; private String email;<br />
&nbsp;&nbsp;&nbsp; private Integer sex;<br />
&nbsp;&nbsp;&nbsp; public String getName() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setName(String name) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.name = name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; ...<br />
}<br />
Action类略过<br />
validation.xml:<br />
&lt;formset&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;form name="/register/register"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;field property="name" depends="required"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;arg0 key="user.name"/&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/field&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;field property="confirmpwd" depends="required"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;arg0 key="user.confirmpwd"/&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/field&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/form&gt;<br />
&nbsp;&nbsp;&nbsp; ...<br />
<br />
ApplicationContext.properties:<br />
user.name = {0}\u6d93\u5d88\u5158\u6d93\u8679\u2516<br />
&nbsp;&nbsp;&nbsp; ...<br />
<br />
编译后，ApplicationContext.properties能在WEB-INF\classes下找到，且struts-config.xml里也已添加<br />
<br />
JSP页面：<br />
&nbsp;&nbsp;&nbsp; ...<br />
&lt;html:form action="/register/register" method="post" enctype="multipart/form-data"&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;input type="hidden" name="method" value="register" /&gt;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;div class="reg03"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;html:text property="name" styleId="name" style="width:245px" /&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;font color="red"&gt;&lt;html:errors property="name"/&gt;&lt;/font&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />
&nbsp; &nbsp; ...<br />
<br />
结果：验证起作用，但是提示信息打印不出来。&nbsp; <br />
HELP！！！<br />
<br />
<span style="color: #0817ff;">已解决<br />
需要修改validation.xml和ApplicationContext.properties<br />
validation.xml:<br />
&nbsp;&nbsp;&nbsp; ...<br />
&lt;field property="name" depends="required"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;msg name="required" key="user.required"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;arg0 key="user.name"/&gt;<br />
&nbsp;&nbsp;&nbsp; ...<br />
<br />
ApplicationContext.properties （未转码前）<br />
&nbsp;&nbsp;&nbsp; ...<br />
user.name=姓名<br />
user.required={0}不能为空<br />
&nbsp;&nbsp;&nbsp; ...<br />
<br />
</span><br />
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
<img src ="http://www.blogjava.net/EvanLiu/aggbug/207964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-06-15 00:58 <a href="http://www.blogjava.net/EvanLiu/archive/2008/06/15/207964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>foxmail下邮件CSS乱了的问题</title><link>http://www.blogjava.net/EvanLiu/archive/2008/05/13/200189.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Tue, 13 May 2008 05:32:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/05/13/200189.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/200189.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/05/13/200189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/200189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/200189.html</trackback:ping><description><![CDATA[今天做一个邮件程序，测试时，发现用foxmail收邮件时，CSS乱了。后来看源码，发现&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;这段声明在显示的时候被过滤掉了。在&lt;!DOCTYPE 前加了字符，然后会跳过字符，把&lt;!DOCTYPE 过滤。后来<span style="color: red;">写了两行&lt;!DOCTYPE 声明</span>，CSS就正常了。应该是foxmail的规则是只过滤第一行声明。<br />
<br />
另外，用outlook2007收邮件的时候，当图片是写在css里的时候，不能下载图片。在&#8220;工具-信任中心-自动下载&#8221;那里取消了禁止自动下载功能，仍然不能显示。目前仍未解决<br />
<br />
<br />
<script type="text/JavaScript">
alimama_pid="mm_10891533_910884_1874773";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="15";
alimama_width=950;
alimama_height=90;
alimama_type=2;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
<img src ="http://www.blogjava.net/EvanLiu/aggbug/200189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/EvanLiu/" target="_blank">EvanLiu</a> 2008-05-13 13:32 <a href="http://www.blogjava.net/EvanLiu/archive/2008/05/13/200189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>