﻿<?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>Sat, 30 Aug 2008 14:18:34 GMT</lastBuildDate><pubDate>Sat, 30 Aug 2008 14:18:34 GMT</pubDate><ttl>60</ttl><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><item><title>String StringBuffer</title><link>http://www.blogjava.net/EvanLiu/archive/2008/04/08/189602.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Tue, 08 Apr 2008 12:59:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/04/08/189602.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/189602.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/04/08/189602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/189602.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/189602.html</trackback:ping><description><![CDATA[<br />
先看一个简单的例子：<br />
public class Test1 {<br />
&nbsp;&nbsp;&nbsp; public static void operateString(String s) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s.replace("j", "i");<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void operateStringBuffer(StringBuffer sb) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sb.append("C");<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String sa = new String("java");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuffer sba = new StringBuffer("java");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; operateString(sa);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; operateStringBuffer(sba);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(sa);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(sba);<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
答案很简单： <br />
java<br />
javaC<br />
<br />
原则：<br />
1.String是不可变对象：<span class="tpc_content">public final class String extends Object</span><br />
2.java中只有值传递<span class="tpc_content"><br />
<br />
replace函数源码中：<br />
public String replace(char oldChar, char newChar) {<br />
<em>&nbsp;&nbsp;&nbsp;&nbsp; ...<br />
&nbsp;&nbsp;&nbsp;&nbsp; return new String(0, len, buf);<br />
}<br />
返回的是另一个String对象。<br />
而在上面的</em></span>operateString方法中，是无返回值的，新产生的String对象被丢弃了，而sa仍然指向最初的那个String对象。<br />
<br />
<br />
第二个例子：<br />
public class Test2 {<br />
&nbsp;&nbsp;&nbsp; public static void operate(StringBuffer x, StringBuffer y) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; x.append(y);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; y = x;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuffer buffA = new StringBuffer("a");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuffer buffB = new StringBuffer("b");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; operate(buffA, buffB);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(buffA + "," + buffB);&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
答案是：<br />
ab,b<br />
<br />
开始时a、x指向同一个StringBuffer对象(这里称它为对象1)，它的值是"a"；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b、y指向同一个StringBuffer对象，它的值是"b"。<br />
执行x.append(y)时，对象1的值被改变，变为"ab"；<br />
而执行y=x时，变量y指向被改变，指向了和x同一个StringBuffer对象。但是变量b的指向还是没有改变，所以仍然为"b"<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/189602.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-04-08 20:59 <a href="http://www.blogjava.net/EvanLiu/archive/2008/04/08/189602.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle分页SQL</title><link>http://www.blogjava.net/EvanLiu/archive/2008/03/23/188042.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Sun, 23 Mar 2008 08:22:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/03/23/188042.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/188042.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/03/23/188042.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/188042.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/188042.html</trackback:ping><description><![CDATA[以前记在笔记上的一点东西，贴上来，省得以后丢了笔记,忘记了
<br />
Oracle 分页 <br />
<span style="color: #1852ff;">select a.*, rownum r<br />
&nbsp; from (select * from lg_order o order by o.order_id) a<br />
&nbsp;where rownum &lt;= 20<br />
&nbsp;&nbsp; and rownum &gt;= 10<br />
<br />
select *<br />
&nbsp; from (select a.*, rownum r<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from (select * from lg_order o order by o.order_id) a<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where rownum &lt;= 20) b<br />
&nbsp;where r &gt;= 10<br />
<br />
</span><strong><span style="color: #9428ff;">select *<br />
&nbsp; from (select rid<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from (select rownum rn, rid<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from (select rowid rid from lg_order o order by o.order_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where rownum &lt;= 20)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where rn &gt;= 10) t1,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lg_order t2<br />
&nbsp;where t2.rowid = t1.rid</span></strong><span style="color: #1852ff;"><br />
</span>
<br />
第一句是错误的 由于rownum是一个总是从1开始的伪列，Oracle 认为这种条件不成立，查不到记录
<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/188042.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-03-23 16:22 <a href="http://www.blogjava.net/EvanLiu/archive/2008/03/23/188042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JS方法收集</title><link>http://www.blogjava.net/EvanLiu/archive/2008/02/28/182690.html</link><dc:creator>EvanLiu</dc:creator><author>EvanLiu</author><pubDate>Thu, 28 Feb 2008 06:47:00 GMT</pubDate><guid>http://www.blogjava.net/EvanLiu/archive/2008/02/28/182690.html</guid><wfw:comment>http://www.blogjava.net/EvanLiu/comments/182690.html</wfw:comment><comments>http://www.blogjava.net/EvanLiu/archive/2008/02/28/182690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/EvanLiu/comments/commentRss/182690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/EvanLiu/services/trackbacks/182690.html</trackback:ping><description><![CDATA[<br />
<br />
1.document.referrer 查询链接来源，只对浏览器点击的来源有效<br />
<br />
<p><span style="font-size: 9pt; color: black; font-family: 宋体;">2.JS</span><span style="font-size: 9pt; color: black; font-family: 宋体;">去除前后空格</span></p>
<p>(/(^"s*)|("s*$)/g, "");</p>
<br />
<p>&lt;head&gt;<br />
&lt;script type='text/javascript'&gt;<br />
function init() {<br />
// 跳转处理<br />
var handler = function(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;  var host = document.location.href;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  if(host.indexOf('jx163.cn') &gt;= 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  document.location = "/";<br />
&nbsp;&nbsp;&nbsp;&nbsp;  else ;<br />
};<br />
<br />
// 添加监听<br />
if (window.addEventListener) {<br />
&nbsp;&nbsp;&nbsp;  window.addEventListener('DOMContentLoaded', handler, false);<br />
&nbsp;&nbsp;&nbsp;  window.addEventListener('load', handler, false);<br />
} else if (window.attachEvent)<br />
&nbsp;&nbsp;&nbsp;  window.attachEvent('onload', handler);<br />
else<br />
&nbsp;&nbsp;&nbsp;  window.onload = handler;<br />
} // end init<br />
<br />
init();<br />
&lt;/script&gt;<br />
<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
－－－－－－－－－－－－－－－－－－－－</p>
<p>window和firefox下的event</p>
<p>－－－－－－－－－－－－－－－－－－－－</p>
<p>&lt;SCRIPT LANGUAGE="JavaScript"&gt;<br />
&lt;!--<br />
function hh(e)<br />
{<br />
alert(arguments[0]);<br />
e=window.event||e;<br />
var el=e.srcElement||e.target;<br />
alert(el.value);<br />
}<br />
//--&gt;<br />
&lt;/SCRIPT&gt;<br />
&lt;INPUT id ="button2"&nbsp;&nbsp;  value ="hahahahah" TYPE="button" onclick="hh(event);"&gt;</p>
<p>－－－－－－－－－－－－－－－－－－－－</p>
<p>test</p>
<p>－－－－－－－－－－－－－－－－－－－－</p>
<p>if(WebComm.getOS() == "MSIE")<br />
&nbsp;&nbsp;&nbsp;  {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  obj.setCapture ();<br />
&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;  else<br />
&nbsp;&nbsp;&nbsp;  {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  document.addEventListener("mousemove",WebComm.MoveDiv,false);<br />
&nbsp;&nbsp;&nbsp;  }</p>
<p>if(WebComm.getOS() == "MSIE")<br />
&nbsp;&nbsp;&nbsp;  {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  obj.releaseCapture ();<br />
&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;  else<br />
&nbsp;&nbsp;&nbsp;  {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  document.removeEventListener("mousemove",WebComm.MoveDiv,false);<br />
&nbsp;&nbsp;&nbsp;  }</p>
<p>－－－－－－－－－－－－－－－－－－</p>
<p>1.火狐不能对innerText支持，也不知道为什么。火狐支持innerHTML但却不支持innerText，所以上网查了一
下，原来它改支持textContent来实现innerText，不过实现得没有那么好，默认把多余的空格也保留了。如果不用textContent，
如果字符串里面不包含HTML代码也可以用innerHTML代替<br />
<br />
2.禁止选取网页内容：<br />
在IE中一般用js：obj.onselectstart=function(){return false;}<br />
而火狐用CSS:-moz-user-select:none<br />
<br />
3.滤镜的支持(例：透明滤镜)：<br />
IE:filter：alpha(opacity=10);<br />
火狐：-moz-opacity:.10;<br />
<br />
4.捕获事件：<br />
IE：obj.setCapture() 、obj.releaseCapture()<br />
火狐： document.addEventListener("mousemove",mousemovefunction,true);<br />
document.removeEventListener("mousemove",mousemovefunction,true);<br />
<br />
5.获取鼠标位置：<br />
IE:event.clientX、event.clientY<br />
火狐：需要事件函数传递事件对象<br />
obj.onmousemove=function(ev){<br />
X= ev.pageX;Y=ev.pageY;<br />
}<br />
<br />
6.DIV等元素的边界问题：<br />
比如：设置一个div的CSS:：{width:100px;height:100px;border:#000000 1px solid;}<br />
IE中：div的宽度（包括边框宽度）：100px，div的高度（包括边框宽度）：100px；<br />
而火狐：div的宽度（包括边框宽度）：102px，div的高度（包括边框宽度）：102px；<br />
<br />
<br />
所以在做这个兼容IE和火狐的拖动窗口时，在js和css的写法上要动点脑筋，给大家两个小技巧.<br />
一.判断浏览器类型：<br />
var isIE=document.all? true:false;<br />
我写了一个变量，如果支持document.all语法那么isIE=true，否则isIE=false<br />
<br />
二.在不同浏览器下的CSS处理：<br />
一般可以用!important来优先使用css语句（仅火狐支持）<br />
比如：{border-width:0px!important;border-width:1px;}<br />
在火狐下这个元素是没有边框的，在IE下边框宽度是1px<br />
<br />
又发现几处XHTML与正常状态下的JS、CSS的区别,前阶段写了兼容IE/火狐的拖动窗口发现了这两个浏览器的几处区别。今天又写了兼容XHTML的
版本，因为现在不是流行web标准嘛，偶不能落后啊！再说现在ASP.NET中的所有页面都是应用XHTML标准的，如果在布局页面中删了这句标准代码，
里面的布局和控件visual studio就不显示了。</p>
<p>呵呵，在网页开头加了这个代码就是所谓的XHTML标准了&lt;!DOCTYPE html PUBLIC "-//W3C//DTD
XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br />
<br />
改了一下JS和CSS，调试了N次，发现了XHTML标准下的几个不同点：<br />
1.document.documentElement 与 document.body<br />
代码中设置页面的CSS时一定要用：document.documentElement <br />
比如：document.documentElement.style.overflow='hidden';<br />
overflow-X、overflow-Y 这两个分坐标属性XHTML是不支持的；<br />
<br />
2.在取得网页窗口区域和获取滚动条位移距离时也要用document.documentElement <br />
即这四个属性（clientWidth、clientHeight、scrollLeft、scrollTop）一定要用document.documentElement <br />
但是document.body.appendChild()和document.body.removeChild()却是可以用的，而且用
document.documentElement.appendChild()和
document.documentElement.removeChild()代替却会报错；<br />
<br />
所以我总结了一下仅clientWidth、clientHeight、scrollLeft、scrollTop和document.documentElement.style时才用document.documentElement<br />
<br />
3.呵呵，加了这个标准以后IE的边框问题也出现了变化，现在和火狐趋于一致了，是不是这个就是XHTML的优点——跨浏览器的标准<br />
上篇文章提到：<br />
设置一个div的CSS:：{width:100px;height:100px;border:#000000 1px solid;}<br />
IE中（正常情况）：div的宽度（包括边框宽度）：100px，div的高度（包括边框宽度）：100px；<br />
<a href="http://firefox.sun-sky.com.cn/"><font color="#810081">火狐</font></a>（正常情况）：：div的宽度（包括边框宽度）：102px，div的高度（包括边框宽度）：102px；<br />
<br />
加了XHTML标准后的（IE和火狐打和了，^_^）：<br />
IE中（XHTML）：div的宽度（包括边框宽度）：102px，div的高度（包括边框宽度）：102px；<br />
火狐（XHTML）：：div的宽度（包括边框宽度）：102px，div的高度（包括边框宽度）：102px；</p>
<p>－－－－－－－－－－－－－－－－－－－－</p>
<p>对于IE的attachEvent方法可能大家都比较熟，现在说说FireFox的addEventListener的用法。</p>
<p>addEventListener的参数一共有三个，语法为：</p>
<p class="code_js">element.addEventListener(type,listener,useCapture)</p>
<p>下面是详解</p>
<ul>
    <li>其中element是要绑定函数的对象。</li>
    <li>type是事件名称，要注意的是"onclick"要改为"click","onblur"要改为"blur",也就是说事件名不要带"on"。</li>
    <li>listener当然就是绑定的函数了，记住不要跟括号</li>
    <li>最后一个参数是个布尔值，表示该事件的响应顺序,下面重点介绍一下addEventListener的第3个参数(useCapture)。</li>
</ul>
<p>userCapture若为true,则浏览器采用Capture,若为false则采用bubbing方式。建议用false,看个例子吧。</p>
<p>html代码</p>
<p class="code_html">&lt;div id="div_test"&gt; &lt;input type="button" id="btn_test" value="se4.cn技术基地" /&gt; &lt;/div&gt;</p>
<p>window.onload=function(){
document.getElementById("div_test").addEventListener("click",test1,false);
document.getElementById("btn_test").addEventListener("click",test2,false);
} function test1(){ alert("外层div触发") } function test2(){
alert("内层input触发") }</p>
<p>如果userCapture是true则test1先触发，如果userCapture是false则test2先触发。</p>
<p><br />
</p>
<!-- 广告位 -->
<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/182690.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-02-28 14:47 <a href="http://www.blogjava.net/EvanLiu/archive/2008/02/28/182690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>