<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
    <title>Philipz學習日誌</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/" />
    
    <id>tag:server.everfine.com.tw,2008-10-20:/blog//1</id>
    <updated>2012-01-05T08:08:00Z</updated>
    <subtitle>此Blog是為了將每天的學習心得、偶然的發現跟突發奇想記錄下來，並與大家分享，以免白白將突然的想法或發現隨時間淡忘掉。</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.34-en</generator>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/philipz_blog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="philipz_blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">philipz_blog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><entry>
    <title>Using Smack XMPP API to send Facebook Chat Messages</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2012/01/using-smack-xmpp-api-to-send-facebook-chat-messages.html" />
    <id>tag:server.everfine.com.tw,2012:/blog//1.354</id>

    <published>2012-01-05T03:02:37Z</published>
    <updated>2012-01-05T08:08:00Z</updated>

    <summary> 之前說到XMPP已經成為即時訊息的標準，那就利用Facebook手機即時通的便捷快速來送Facebook Chat訊息。 其實只要拿之前GTalk的程式碼，稍微修改一下，就可發送了。其中差異在於DIGEST-MD5的認證機制。在Smack討論區已經有人實作出XMPP DIGEST-MD5的物件。只要將login部份加上DIGEST-MD5認證。 ※注意：facebook chat發送對象的帳號是-XXXXX@@chat.facebook.com，而XXXXX是一組數字，必須由c.displayBuddyList();列出才會知道。 完整程式碼如下： package messenger;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Collection;import org.jivesoftware.smack.Chat;import org.jivesoftware.smack.ConnectionConfiguration;import org.jivesoftware.smack.MessageListener;import org.jivesoftware.smack.Roster;import org.jivesoftware.smack.RosterEntry;import org.jivesoftware.smack.SASLAuthentication;import...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>
之前說到<a href="http://server.everfine.com.tw/blog/archives/2012/01/xmpp.html">XMPP已經成為即時訊息的標準</a>，那就利用Facebook手機即時通的便捷快速來送<a href="http://developers.facebook.com/docs/chat/">Facebook Chat</a>訊息。<br />
其實只要拿<a href="http://server.everfine.com.tw/blog/archives/2009/06/smack-api.html">之前GTalk的程式碼</a>，稍微修改一下，就可發送了。其中差異在於DIGEST-MD5的認證機制。在<a href="http://community.igniterealtime.org/thread/41080">Smack討論區</a>已經有人實作出<a href="http://server.everfine.com.tw/blog/MySASLDigestMD5Mechanism.java">XMPP DIGEST-MD5的物件</a>。只要將login部份加上DIGEST-MD5認證。<br />
※注意：facebook chat發送對象的帳號是-XXXXX@@chat.facebook.com，而XXXXX是一組數字，必須由c.displayBuddyList();列出才會知道。<br />
完整程式碼如下：</p>
<code class="c">
<p></p><p>package messenger;</p><p><br /></p><p>import java.io.BufferedReader;</p><p>import java.io.IOException;</p><p>import java.io.InputStreamReader;</p><p>import java.util.Collection;</p><p><br /></p><p>import org.jivesoftware.smack.Chat;</p><p>import org.jivesoftware.smack.ConnectionConfiguration;</p><p>import org.jivesoftware.smack.MessageListener;</p><p>import org.jivesoftware.smack.Roster;</p><p>import org.jivesoftware.smack.RosterEntry;</p><p>import org.jivesoftware.smack.SASLAuthentication;</p><p>import org.jivesoftware.smack.XMPPConnection;</p><p>import org.jivesoftware.smack.XMPPException;</p><p>import org.jivesoftware.smack.packet.Message;</p><p><br /></p><p>public class facebook implements MessageListener {</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>XMPPConnection connection;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private volatile static facebook fclient;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static String username = "xxxxxxxx";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static String password = "xxxxxxxx";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private facebook(){}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static facebook getInstance(){</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>if (fclient == null) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>synchronized (facebook.class){</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>if (fclient == null) {</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>fclient = new facebook();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return fclient;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void login(String userName, String password) throws XMPPException {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>SASLAuthentication.registerSASLMechanism("DIGEST-MD5", MySASLDigestMD5Mechanism.class);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>ConnectionConfiguration config = new ConnectionConfiguration(</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>"chat.facebook.com", 5222, "chat.facebook.com");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>config.setCompressionEnabled(true);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>config.setSASLAuthenticationEnabled(true);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>connection = new XMPPConnection(config);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>connection.connect();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>connection.login(userName, password);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void sendMessage(String message, String to) throws XMPPException {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Chat chat = connection.getChatManager().createChat(to, this);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>chat.sendMessage(message);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void displayBuddyList() {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Roster roster = connection.getRoster();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Collection&lt;RosterEntry&gt; entries = roster.getEntries();</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("\n\n" + entries.size() + " buddy(ies):");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>for (RosterEntry r : entries) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>System.out.println(r.getUser());</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void addRoster(String bot, String email, String input){</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>facebook c = facebook.getInstance();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>addRoster(bot,input);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>c.sendMessage(input, email);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (XMPPException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void addRoster(String bot,String input){</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>facebook c = facebook.getInstance();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>c.login(username, password);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>Roster roster = connection.getRoster();</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>roster.createEntry(input, null, null);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (XMPPException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>c.disconnect();</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void disconnect() {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>connection.disconnect();</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void processMessage(Chat chat, Message message) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>if (message.getType() == Message.Type.chat)</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>System.out.println(chat.getParticipant() + " says: "</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>+ message.getBody());</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String args[]) throws XMPPException, IOException {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// declare variables</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>facebook c = facebook.getInstance();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>BufferedReader br = new BufferedReader(new InputStreamReader(System.in));</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String msg;</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// turn on the enhanced debugger</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>XMPPConnection.DEBUG_ENABLED = false;</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// provide your login information here</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>c.login(username, password);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>c.displayBuddyList();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("-----");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("Enter your message in the console.");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("All messages will be sent to abhijeet.maharana");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("-----\n");</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>while (!(msg = br.readLine()).equals("bye")) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// your buddy's gmail address goes here</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>c.sendMessage(msg, "-xxxxxxxx@chat.facebook.com");</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>c.disconnect();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.exit(0);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void alert(String bot,String email, String msg) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>facebook c = facebook.getInstance();</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// turn on the enhanced debugger</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>XMPPConnection.DEBUG_ENABLED = false;</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// provide your login information here</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>c.login(username, password);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>c.sendMessage(msg, email);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (XMPPException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>c.disconnect();</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p>}</p><p></p>
</code>]]>
        
    </content>
</entry>

<entry>
    <title>XMPP協定已一統即時訊息協定標準</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2012/01/xmpp.html" />
    <id>tag:server.everfine.com.tw,2012:/blog//1.353</id>

    <published>2012-01-03T02:22:28Z</published>
    <updated>2012-01-03T02:50:51Z</updated>

    <summary>從自由軟體鑄造場得知Microsoft 打開 Messenger 大門 開始支援 XMPP，因此目前主流即時訊息都支援XMPP，包括Facebook chat。 既然如此，當然找看看熟悉的Smack套件是否也有MSN的sample code。果然Github上有MS放出的LiveSDK，便有JAVA跟Android的程式碼。有空再把拿token那程式改成用httpclient。 JAVA程式碼如下： package messenger;import java.net.URL;import java.net.URLDecoder;import javax.swing.JOptionPane;import org.jivesoftware.smack.ConnectionConfiguration;import org.jivesoftware.smack.PacketListener;import org.jivesoftware.smack.Roster;import org.jivesoftware.smack.RosterEntry;import org.jivesoftware.smack.SASLAuthentication;import...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>從<a href="http://www.openfoundry.org/">自由軟體鑄造場</a>得知<a href="http://www.openfoundry.org/tw/worldwide-news/8568-microsoft-opens-up-messenger-to-xmpp">Microsoft 打開 Messenger 大門 開始支援 XMPP</a>，因此目前主流即時訊息都支援XMPP，包括<a href="http://developers.facebook.com/docs/chat/">Facebook chat</a>。</p>

<p>既然如此，當然找看看熟悉的<a href="http://server.everfine.com.tw/blog/archives/2009/06/smack-api.html">Smack套件</a>是否也有MSN的sample code。果然<a href="https://github.com/">Github</a>上有MS放出的<a href="https://github.com/liveservices/LiveSDK">LiveSDK</a>，便有<a href="https://github.com/liveservices/LiveSDK/blob/master/Samples/XMPP-Samples/Java/src/com/ms/wlm/XmppClient.java">JAVA</a>跟<a href="https://github.com/liveservices/LiveSDK/blob/master/Samples/XMPP-Samples/Android/src/com/ms/wlm/XmppClient.java">Android</a>的程式碼。有空再把拿token那程式改成用<a href="http://server.everfine.com.tw/blog/archives/2010/11/call-plurk-api.html">httpclient</a>。<br />
JAVA程式碼如下：<br /></p>
<code class="c">
<p><p>package messenger;</p><p><br /></p><p>import java.net.URL;</p><p>import java.net.URLDecoder;</p><p><br /></p><p>import javax.swing.JOptionPane;</p><p><br /></p><p>import org.jivesoftware.smack.ConnectionConfiguration;</p><p>import org.jivesoftware.smack.PacketListener;</p><p>import org.jivesoftware.smack.Roster;</p><p>import org.jivesoftware.smack.RosterEntry;</p><p>import org.jivesoftware.smack.SASLAuthentication;</p><p>import org.jivesoftware.smack.XMPPConnection;</p><p>import org.jivesoftware.smack.XMPPException;</p><p>import org.jivesoftware.smack.filter.MessageTypeFilter;</p><p>import org.jivesoftware.smack.filter.PacketFilter;</p><p>import org.jivesoftware.smack.filter.PacketTypeFilter;</p><p>import org.jivesoftware.smack.packet.Message;</p><p>import org.jivesoftware.smack.packet.Packet;</p><p>import org.jivesoftware.smack.packet.Presence;</p><p>import org.jivesoftware.smack.util.StringUtils;</p><p><br /></p><p>/**</p><p>&nbsp;* XmppClient class has all the XMPP specific logic. This class uses smack</p><p>&nbsp;* library to connect to windows live messenger service. For Windows Live Xmpp</p><p>&nbsp;* documentation see &lt;link&gt;</p><p>&nbsp;*/</p><p>public class msn {</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static final String Host = "xmpp.messenger.live.com";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static final int Port = 5222;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static final String Service = "messenger.live.com";</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private String accessToken;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private XMPPConnection connection;</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * This block initializes smack with SASL mechanism used by Windows Live.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>SASLAuthentication.registerSASLMechanism("X-MESSENGER-OAUTH2",</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>XMessengerOAuth2.class);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>SASLAuthentication.supportSASLMechanism("X-MESSENGER-OAUTH2");</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String[] args) throws InterruptedException {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">		</span> * 1. Set up a string with the path to the website.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span> * 2. Create a desktop variable. &nbsp;The desktop class uses the computer's default browser to open the URL.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span> * 3. Load the URL.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span> * 4. Browse to the URL.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span> */</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>//TODO put your own clientId here.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>//String clientId = "000000004807AE0A";</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>//String scopes = "wl.messenger";</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>//String signInUrl = "https://oauth.live.com/authorize?client_id=" + clientId + "&amp;redirect_uri=https://oauth.live.com/desktop&amp;response_type=token&amp;scope=" + scopes;</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// launch a web browser to take the user through the OAuth 2.0 consent flow</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>//BareBonesBrowserLaunch.browse(signInUrl);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// pop a dialog that tells the developer to copy and paste the URL and put it into a text box in the dialog</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>//String returnUrlString = (String)JOptionPane.showInputDialog("After completing the OAuth consent flow in the browser, copy and paste the return URL into this dialog box");</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String returnUrlString = "https://oauth.live.com/desktop#access_token=EwAoAq1DBAAUlbRWyAJjK5w968Ru3Cyt%2f6GvwXwAAcQc5qjgPRbE4InoTBM3bsPTd0eAZIcSZiRxdNSMn3K8jSLvqJjDBfhjf3fd71C%2fBlGBFqDAs%2fFZYb1WYDPUfbL239Y3sXKA8ZFZgMOKIWWb%2beib%2fyTpNIW6m4O4SUMhAu5GYe3DAiC7JsXAnLgu%2bUFeUpF%2fEMjmrdRGzVDUjNNuwfKgdqpgvBD5kWAU1A3NNGhwxJZZhwOpKcogIcWZ%2fR7eKdFsYjGN9riWjBh2gcmk%2bGiEMifAxI0PoqeECqq9otHAZ1fz9NxCUbFssIQuy5mxlzjPu%2fWl9wmwRvZnHkDY4EiuDrfUw6SHflWirQ74nQ2fjv7Ew7Dk4nl%2fvvTymxcDZgAACPsOZ%2fNUm4kh%2bABDsVcnU0eMbHeEikN9WrYIwYTrTQKy2WtThAVuuNwsJOiqgyP%2fInBCWZMudPy0qGOlFoJriKm16OiYrgf44t9aua6MO7Lq0hJchmmbBm9%2fEsSquOhKaLOrNgx%2fVPs%2bqycd6sBkqzPJMD69eIztb%2fPnllMbX%2f4qDz1cUU1ySkE%2f3%2bMlENfPDKiNARAvKxSpljsM6yjMgwPCTawChrUgExYjbeGxAR16vY1N7ibTmwcgIB9ewoyghGeNBI7GHBdpOMzBbp%2b6YZQYBDHwPc7SXYoxPq1s8TAlfdXrrpj2J2kEpxuwPGM6VnBJN1yOdFsolRENflmAkTCh4gAA&amp;token_type=bearer&amp;expires_in=3600&amp;scope=wl.messenger";</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// take the string URL from the dialog and programmatically cram it into the access token parameter</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String accessToken = urlTokenizerHelper(returnUrlString);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// log in using the access token</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>msn client = new msn(accessToken);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>client.logIn();</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>Roster r = client.getRoster();</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>System.out.println(r.toString());</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// make sure the program hasn't already closed before the login has completed</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// in a real XMPP client, this would be replaced with waiting on UI events and Xmpp events&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>Thread.sleep(1000000);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (Exception e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>System.out.println(e);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * This function helps to extract the access_token query string parameter from the return URL.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static String urlTokenizerHelper(String urlString) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>URL returnUrl = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try{</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>returnUrl = new URL(urlString);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}catch(Exception e){}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String queryParameters = returnUrl.getRef();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>queryParameters = queryParameters.substring(queryParameters.indexOf("access_token"));</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>queryParameters = queryParameters.substring(queryParameters.indexOf("=")+1);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String encodedAccessToken = queryParameters.substring(0, queryParameters.indexOf("&amp;"));</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return URLDecoder.decode(encodedAccessToken);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Constructor</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param accessToken</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The OAuth2.0 access token to be used for login.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public msn(String accessToken) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>this.accessToken = accessToken;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Get the Roster for this client instance.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @return The full Roster for the client.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public Roster getRoster() {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return this.connection.getRoster();</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Get the Jid for this client instance.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public String getLocalJid() {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return StringUtils.parseBareAddress(this.connection.getUser());</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Log in the client to the messenger service.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void logIn() {</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// Create a connection. We use service name in config and asmack will do</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// SRV look up locate the xmpp server.</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>ConnectionConfiguration connConfig = new ConnectionConfiguration(</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>msn.Service);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>connConfig.setRosterLoadedAtLogin(true);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>this.connection = new XMPPConnection(connConfig);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>this.connection.connect();</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// We do not need user name in this case.</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>this.connection.login("", this.accessToken);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (XMPPException ex) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>this.connection = null;</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>return;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println(String.format("Logged in as %s",</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>this.connection.getUser()));</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// set the message and presence handlers</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>this.setPacketFilters();</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// Set the status to available</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Presence presence = new Presence(Presence.Type.available);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>this.connection.sendPacket(presence);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Send a text message to the buddy.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param to</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The Buddy Jid.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param text</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The text message to be sent.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public void sendMessage(String to, String text) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Message msg = new Message(to, Message.Type.chat);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>msg.setBody(text);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>this.connection.sendPacket(msg);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Set the packet filters for handling incoming stanzas.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private void setPacketFilters() {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>if (this.connection != null) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>PacketFilter presenceFilter = new PacketTypeFilter(Presence.class);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>this.connection.addPacketListener(new PacketListener() {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>public void processPacket(Packet packet) {</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>Presence presence = (Presence) packet;</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>handlePresenceReceived(presence);</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}, presenceFilter);</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">			</span>PacketFilter messageFilter = new MessageTypeFilter(</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>Message.Type.chat);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>this.connection.addPacketListener(new PacketListener() {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>public void processPacket(Packet packet) {</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>Message message = (Message) packet;</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>if (message.getBody() != null) {</p><p><span class="Apple-tab-span" style="white-space:pre">						</span>handleMessageReceived(message);</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}, messageFilter);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Handle the presence stanza received.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param presence</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The received presence stanza.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private void handlePresenceReceived(Presence presence) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String from = StringUtils.parseBareAddress(presence.getFrom());</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println(String.format(</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>"Presence received from Jid: %s, Name: %s", from,</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>this.getContactName(from)));</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Handle the message stanza received.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param message</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The received message stanza.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private void handleMessageReceived(Message message) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String from = StringUtils.parseBareAddress(message.getFrom());</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println(String.format(</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>"Message received from Jid: %s, Name: %s", from,</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>this.getContactName(from)));</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>/**</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * Get friendly name of a contact given the jid.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @param jid</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Jid for the target contact.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> * @return The friendly name by looking up roster.</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> */</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private String getContactName(String jid) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>Roster roster = this.connection.getRoster();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>RosterEntry entry = roster.getEntry(jid);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return entry.getName();</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p>}</p><div><br /></div></p>
</code>]]>
        
    </content>
</entry>

<entry>
    <title>建置程式交易系統(2) - 決定獲利策略</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/07/2--.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.352</id>

    <published>2011-07-24T10:04:52Z</published>
    <updated>2011-07-24T14:16:20Z</updated>

    <summary>相信很多人都有這樣的經驗，用一口去交易時，能穩定獲利，便想用兩口，用十口，試想，原本1點跳動是50塊或200塊，當變成500塊或2000塊，您還能保證用一口會遵循賺錢的策略嗎？少數人也許會嚴守紀律，但大多數一定是賺錢就跑，賠錢死撐。程式交易的好處，在交易口數放大後，依然遵循既定的交易策略（這是廢話，只是1改成10），可以避免掉人性的恐懼跟貪婪，這也是為何要用程式去交易期貨，至於是否有用程式去交易股票，因為股票的波動週期沒有期貨選擇權大，影響變數太多，一則新聞可能就讓股票漲停或跌停，所以散戶沒必要用程式去交易股票（法人在控制期貨盤時，也有會用程式交易現貨股票）。 以下是策略制定步驟： 先確定要賺的波段，是最短的tick交易、當沖賺一天波動，還是有留倉的大趨勢。當然交易系統是可結合多個策略，而一個策略只適合一種波段。針對策略的波段，再訂定進出的頻率。如果是Tick交易，當然是有賺就跑，高頻進出，但這只適合期貨商。一般散戶多為當沖或賺趨勢財，而當沖策略可以參考自由人的台指當沖交易秘訣，大波段的趨勢財就要參考摩台並判斷國際情勢。 天馬行空的策略，相信很多程式交易人員是利用技術分析方法來決定進場跟出場，也一定很多人搞不清楚什麼是布林通道，什麼是MACD，老實說我也搞不懂。因此，筆者以熟悉的影像處理方法(訊號處理技術)來套用到程式交易，這並不是說技術分析不對或不適用，但只局限在技術分析的範疇，何不結合其他領域的方法。且技術分析未嘗不是前人天馬行空後的結果。 決定進場點跟出場點，固定停損或動態停損：您是不是疑惑，為何沒寫固定停利或動態停利？因為如果用固定停利，其實就限制了獲利的範圍，所以應該皆為動態停利。使用技術指標，進場點為指標達到一定數值，可是並非每天交易都適用固定值，所以不妨多個判斷規則來給訂不同數值，亦可使用線性或非線性變數，當然出場也是相同原理，也許是不同指標或多種指標。 期貨程式交易機器人的當沖策略是先利用訊號處理技術過濾tick雜訊，並在一定tick數量上判斷斜率變化及走勢模式(pattern recognition)，再配合摩台期的漲跌來決定進場時機。看盤最常用的K線其實是有盲點，十字線呈現開價跟收價是相同的，可是到底是先上漲後下跌還是先下跌後上漲(部分看盤軟體會呈現紅十字線或綠十字線，就可判斷出來)，另外，若以一分鐘K線來看，一個大紅K或大黑K的前一根或許是十字線，看不出會突然大漲或大跌，所以通常不會只看K線圖，當然還要配合走勢圖才能分辨。以訊號處理領域解釋K線就是一種濾波器filter，每種濾波器都會凸顯一些資訊並遺失一些資訊，沒有一個濾波器是萬能的。 延伸閱讀：幣圖誌-常見的程式交易系統...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>相信很多人都有這樣的經驗，用一口去交易時，能穩定獲利，便想用兩口，用十口，試想，原本1點跳動是50塊或200塊，當變成500塊或2000塊，您還能保證用一口會遵循賺錢的策略嗎？少數人也許會嚴守紀律，但大多數一定是賺錢就跑，賠錢死撐。程式交易的好處，在交易口數放大後，依然遵循既定的交易策略（這是廢話，只是1改成10），可以避免掉人性的恐懼跟貪婪，這也是為何要用程式去交易期貨，至於是否有用程式去交易股票，因為股票的波動週期沒有期貨選擇權大，影響變數太多，一則新聞可能就讓股票漲停或跌停，所以散戶沒必要用程式去交易股票（法人在控制期貨盤時，也有會用程式交易現貨股票）。</p>
<p>以下是策略制定步驟：
<ol><li>先確定要賺的波段，是最短的tick交易、當沖賺一天波動，還是有留倉的大趨勢。當然交易系統是可結合多個策略，而一個策略只適合一種波段。針對策略的波段，再訂定進出的頻率。如果是Tick交易，當然是有賺就跑，高頻進出，但這只適合期貨商。一般散戶多為當沖或賺趨勢財，而當沖策略可以參考自由人的<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010442030">台指當沖交易秘訣</a>，大波段的趨勢財就要參考摩台並判斷國際情勢。</li>
<li>天馬行空的策略，相信很多程式交易人員是利用技術分析方法來決定進場跟出場，也一定很多人搞不清楚什麼是<a href="http://www.google.com.tw/search?q=布林通道">布林通道</a>，什麼是<a href="http://www.google.com.tw/search?q=MACD">MACD</a>，老實說我也搞不懂。因此，筆者以熟悉的影像處理方法(訊號處理技術)來套用到程式交易，這並不是說技術分析不對或不適用，但只局限在技術分析的範疇，何不結合其他領域的方法。且技術分析未嘗不是前人天馬行空後的結果。</li>
<li>決定進場點跟出場點，固定停損或動態停損：您是不是疑惑，為何沒寫固定停利或動態停利？因為如果用固定停利，其實就限制了獲利的範圍，所以應該皆為動態停利。使用技術指標，進場點為指標達到一定數值，可是並非每天交易都適用固定值，所以不妨多個判斷規則來給訂不同數值，亦可使用線性或非線性變數，當然出場也是相同原理，也許是不同指標或多種指標。</li></ol></p>
<p><a href="http://www.plurk.com/futuresbot">期貨程式交易機器人</a>的當沖策略是先利用訊號處理技術過濾tick雜訊，並在一定tick數量上判斷斜率變化及走勢模式(<a href="http://en.wikipedia.org/wiki/Pattern_recognition">pattern recognition</a>)，再配合摩台期的漲跌來決定進場時機。看盤最常用的<a href="http://idd.ccnet.com.tw/ebook/finance.htm">K線</a>其實是有盲點，十字線呈現開價跟收價是相同的，可是到底是先上漲後下跌還是先下跌後上漲(部分看盤軟體會呈現紅十字線或綠十字線，就可判斷出來)，另外，若以一分鐘K線來看，一個大紅K或大黑K的前一根或許是十字線，看不出會突然大漲或大跌，所以通常不會只看K線圖，當然還要配合走勢圖才能分辨。以訊號處理領域解釋K線就是一種濾波器filter，每種濾波器都會凸顯一些資訊並遺失一些資訊，沒有一個濾波器是萬能的。</p>

延伸閱讀：<a href="http://www.bituzi.com/2010/08/blog-post_19.html">幣圖誌-常見的程式交易系統</a>]]>
        
    </content>
</entry>

<entry>
    <title>建置程式交易系統(1) - 準備工作</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/07/1--.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.351</id>

    <published>2011-07-13T07:10:15Z</published>
    <updated>2011-07-14T00:53:39Z</updated>

    <summary>緣起 在四年前接觸了期貨跟選擇權，對於這高風險高獲利的金融商品深深著迷，之後體認到唯有程式交易才能快速反應及嚴守停損停利的規則。所以在2008年時開發了期貨程式交易機器人和選擇權程式交易機器人，並從2009年開始用噗浪記錄每天交易情況。一開始這程式是用來發佈警示訊息，但發現警示後再透過人工下單就已經太慢，便開始研究程式交易，至今。 審視自身條件 由於本篇是著重準備工作，先不會談論到程式技術面，因並非每個人都適合投資高風險的期貨選擇權，建議先審視自己條件後，再投入這期貨交易才能避免把錢丟入大海、肉包子打狗。 心理建設 - 首先要判斷自己的投資心態是長線還是短線，如果您以投資股票的心態來投資期貨，必定虧錢，因為股票可以放著不管，但期貨選擇權每月結算一次，不管就等著斷頭追繳保證金，所以一定調整心態，方向錯就要認賠。習慣不把錢當錢看，一開始交易賠錢可能非常懊惱，並影響家庭生活或作息，如果又留倉，晚上更睡不好，且猛盯美股盤勢，更讓隔天交易畏手畏腳，大賺沒抱緊，大賠卻死抱。這都是人為操盤很難克服的心理因素，所以為何要讓程式自行交易。 具備程式能力 - 既然是要建置程式交易系統，當然要有程式的基礎，至於何種程式語言，則視您的程式交易平台為何？TradeStation就要了解EasyLanguage，MultuChart就要了解PowerLanguage，Excel就要了解VBA，只要有基本程式知識，再去學各種平台都是可行的。 支援API下單的期貨商 - 目前幾乎所有的期貨公司都有提供API讓顧客撰寫程式下單，建議選擇下單大師有支援的期貨商，把精力都花在程式交易規則，下單就交給下單機去處理。 穩定報價源 - 雖然大多數都是使用DDE報價，可是DDE在爆量時，會卡住不動，所以不建議使用DDE報價，可以選擇免費的群益API報價或收費的TOUCHANCE，至於如何介接API報價源，這往後文章將介紹。 模擬測試 - 當完成了一個自動交易程式，千萬別自得意滿，先利用歷史資料回測，如果連歷史資料交易都賠錢，那真實交易也鐵定賠。之後實際交易時，也先用模擬單測試，避免因系統或網路等因素導致大量虧損。下單大師支援模擬下單，既可保留模擬交易紀錄，亦可測試下單API。 上述皆是開發程式交易的必要條件，也是準備工作，如果都具備再進入期貨程式交易這領域，才能避免走很多冤妄路，或還沒賺到就直接血本無歸。...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<big>緣起</big>
<p>在四年前接觸了期貨跟選擇權，對於這高風險高獲利的金融商品深深著迷，之後體認到唯有程式交易才能快速反應及嚴守停損停利的規則。所以在2008年時開發了<a href="http://www.plurk.com/futuresbot">期貨程式交易機器人</a>和<a href="http://www.plurk.com/optionsbot">選擇權程式交易機器人</a>，並從2009年開始用噗浪記錄每天交易情況。一開始這程式是用來發佈警示訊息，但發現警示後再透過人工下單就已經太慢，便開始研究程式交易，至今。</p>
<big>審視自身條件</big>
<p>由於本篇是著重準備工作，先不會談論到程式技術面，因並非每個人都適合投資高風險的期貨選擇權，建議先審視自己條件後，再投入這期貨交易才能避免把錢丟入大海、肉包子打狗。<br/>
<ol><li>心理建設 - 首先要判斷自己的投資心態是長線還是短線，如果您以投資股票的心態來投資期貨，必定虧錢，因為股票可以放著不管，但期貨選擇權每月結算一次，不管就等著斷頭追繳保證金，所以一定調整心態，方向錯就要認賠。習慣不把錢當錢看，一開始交易賠錢可能非常懊惱，並影響家庭生活或作息，如果又留倉，晚上更睡不好，且猛盯美股盤勢，更讓隔天交易畏手畏腳，大賺沒抱緊，大賠卻死抱。這都是人為操盤很難克服的心理因素，所以為何要讓程式自行交易。</li>
<li>具備程式能力 - 既然是要建置程式交易系統，當然要有程式的基礎，至於何種程式語言，則視您的程式交易平台為何？TradeStation就要了解EasyLanguage，MultuChart就要了解PowerLanguage，Excel就要了解VBA，只要有基本程式知識，再去學各種平台都是可行的。</li>
<li>支援API下單的期貨商 - 目前幾乎所有的期貨公司都有提供API讓顧客撰寫程式下單，建議選擇<a href="http://moneyprinter.pixnet.net/blog">下單大師</a>有支援的期貨商，把精力都花在程式交易規則，下單就交給下單機去處理。</li>
<li>穩定報價源 - 雖然大多數都是使用DDE報價，可是DDE在爆量時，會卡住不動，所以不建議使用DDE報價，可以選擇免費的<a href="http://www.capital.com.tw/Service2/Download/api.asp">群益API</a>報價或收費的<a href="http://www.touchance.com/">TOUCHANCE</a>，至於如何介接API報價源，這往後文章將介紹。</li>
<li>模擬測試 - 當完成了一個自動交易程式，千萬別自得意滿，先利用歷史資料回測，如果連歷史資料交易都賠錢，那真實交易也鐵定賠。之後實際交易時，也先用模擬單測試，避免因系統或網路等因素導致大量虧損。下單大師支援模擬下單，既可保留模擬交易紀錄，亦可測試下單API。</li>
</ol>
上述皆是開發程式交易的必要條件，也是準備工作，如果都具備再進入期貨程式交易這領域，才能避免走很多冤妄路，或還沒賺到就直接血本無歸。
</p>
<big>參考資料</big>
<p>
以下是程式交易的相關資料，尤其是程式交易的解決方法和Trading Systems Coding，說明了程式交易的開發流程。<br/>
<a href="http://www.scribd.com/doc/13374233/TWFC-Training">程式交易的解決方法</a><br/>
<a href="http://en.wikipedia.org/wiki/Algorithmic_trading">Algorithmic trading</a><br/>
<a href="http://www.investopedia.com/university/systemcoding/">Trading Systems Coding</a><br/>
<a href="http://preview.collective2.com/">國外交易分享社群 - Collective2</a><br/>
<a href="http://www.algostars.net/">國內交易分享社群 - 策略星</a><br/>
<a href="http://www.programtrading.tw/">國內程式交易論壇 - 程式交易聚寶盆</a>]]>
        
    </content>
</entry>

<entry>
    <title>TestFlight - 封閉式的App版Github</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/06/testflight---ap.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.350</id>

    <published>2011-06-20T03:47:30Z</published>
    <updated>2011-06-20T05:19:09Z</updated>

    <summary> 雖然Title很想寫，TestFlight - 不需有iOS ID也能佈署，但這太小看TestFlight提供的功能，和未來可能的延伸應用。 的確，所有需測試App的人，不免都要申請iOS Dev. ID，也許只是想把玩自己寫的App，花上三千多台幣實在心有不甘，這TestFlight提供的Testing on the fly功能，不只不需申請ID，更可以不用接上USB線來佈署，只要上傳打包好的ipa檔，上傳到TestFlight，用自己或朋友的iOS Device上TestFlight註冊，安裝TestFlight App，就可隨時更新App動態。 再者，對於企業用戶，雖然Apple有提供Enterprise Distribution方法，但是太麻煩也無法作控管，如果利用TestFlight，只要建立好ACL，讓企業內User透過TestFlight App自行下載，除了方便佈署外，更有效管控使用者只可用那些App。當然企業或許因安全考量連ipa檔都不想釋出，TestFlight或許可獨立推出專屬主機服務，避免這部分疑慮。 此外，目前下載App的管道除了Apple App Store，就是需要Jailbreak的Cydia，但Cydia畢竟是檯面下，如果App開發人員，自行收費，省下蘋果稅30%，並只需將ACL設定，就可完成安裝，不須JB，但前提是使用TestFlight App。至於未來Apple是否會防堵這樣付費方式，修改App條款，就不得而知。...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p><a href="http://server.everfine.com.tw/blog/IMG_0783.jpg"><img alt="TestFlight" src="http://server.everfine.com.tw/blog/assets_c/2011/06/IMG_0783-thumb-160x240-38.jpg" width="160" height="240" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a><br />
<p>雖然Title很想寫，TestFlight - 不需有iOS ID也能佈署，但這太小看<a href="http://testflightapp.com/">TestFlight</a>提供的功能，和未來可能的延伸應用。<br />
的確，所有需測試App的人，不免都要申請iOS Dev. ID，也許只是想把玩自己寫的App，花上三千多台幣實在心有不甘，這TestFlight提供的Testing on the fly功能，不只不需申請ID，更可以不用接上USB線來佈署，只要上傳打包好的ipa檔，上傳到TestFlight，用自己或朋友的iOS Device上TestFlight註冊，安裝TestFlight App，就可隨時更新App動態。</p><br />
<p>再者，對於企業用戶，雖然Apple有提供<a href="http://developer.apple.com/library/ios/#featuredarticles/FA_Wireless_Enterprise_App_Distribution/Introduction/Introduction.html">Enterprise Distribution方法</a>，但是太麻煩也無法作控管，如果利用TestFlight，只要建立好ACL，讓企業內User透過TestFlight App自行下載，除了方便佈署外，更有效管控使用者只可用那些App。當然企業或許因安全考量連ipa檔都不想釋出，TestFlight或許可獨立推出專屬主機服務，避免這部分疑慮。</p><br />
<p>此外，目前下載App的管道除了Apple App Store，就是需要Jailbreak的<a href="http://cydia.saurik.com/">Cydia</a>，但Cydia畢竟是檯面下，如果App開發人員，自行收費，省下蘋果稅30%，並只需將ACL設定，就可完成安裝，不須JB，但前提是使用TestFlight App。至於未來Apple是否會防堵這樣付費方式，修改App條款，就不得而知。</p><br />
<a href="http://blog.testflightapp.com/">TestFlight Blog</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>Using OpenCV on iOS</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/04/using-opencv-on.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.349</id>

    <published>2011-04-07T00:30:30Z</published>
    <updated>2012-02-10T09:04:44Z</updated>

    <summary> OpenCV is a powerful library for image processing and computer vision. How to use it on iOS? First, build...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p><a href="http://server.everfine.com.tw/blog/IMG_0765.jpg"><img alt="IMG_0765.jpg" src="http://server.everfine.com.tw/blog/assets_c/2011/04/IMG_0765-thumb-160x240-34.jpg" width="160" height="240" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a><br />
<a href="http://opencv.willowgarage.com/wiki/">OpenCV</a> is a powerful library for image processing and computer vision. How to use it on iOS? First, build the source code, <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.2/">OpenCV-2.2.0.tar.bz2</a>, to get static library file. Then, open your Xcode project and import those static library file.<br />
<a href="http://computer-vision-talks.com/2011/02/building-opencv-for-iphone-in-one-click/">Building OpenCV for iPhone in one click</a> that provide a shell script file to build library for OpenCV cross compile, but the script doesn't include armv6 architecture. I rewrite <a href="http://server.everfine.com.tw/blog/BuildOpenCV.sh">the script</a> to build armv6 and armv7 arch. and lipo together.<br />
Building Step:<br />
1. Download the <a href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.2/">OpenCV Unix source code</a>.<br />
2. Unarchive the file to the folder, trunk/opencv/.<br />
3. Enter: <code class="c">sh BuildOpenCV.sh trunk/opencv/ opencv_ios_build</code><br />
Finally, you will get the include h file and library file in opencv_ios_build folder.<br />
<a href="http://server.everfine.com.tw/blog/BuildOpenCV.sh">Download script file</a></p>

<p>2012-02-10 Update: <a href="http://aptogo.co.uk/2011/09/opencv-framework-for-ios/">Aptogo Blog</a> had build OpenCV iOS Framework.</p>]]>
        
    </content>
</entry>

<entry>
    <title>台灣法拍屋行事曆</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/03/post-8.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.348</id>

    <published>2011-03-11T10:30:11Z</published>
    <updated>2011-03-17T15:49:56Z</updated>

    <summary> 之前的利用Google Fusion Tables + Google Maps呈現台灣法拍屋，是以地理圖資的觀點來呈現法拍屋的資料。 而相同的資料，放到Google Calendar以時間的觀點來呈現另一種角度的法拍屋資料，利用Calendar Data API將資料同步到台灣法拍屋行事曆，方便讓有興趣的人訂閱，並以縣市分類，避免資料過載不易閱讀（其實仍有這樣問題），且使用iPhone或iPad，只要配合使用GooCal App來訂閱讀取，按下Show event on map還能查閱地圖。 以下是各縣市的法拍行事曆連結。 台北市 新北市 基隆市 宜蘭縣...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p><a href="http://server.everfine.com.tw/blog/assets_c/2011/03/iphone3steps-27.html" onclick="window.open('http://server.everfine.com.tw/blog/assets_c/2011/03/iphone3steps-27.html','popup','width=960,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://server.everfine.com.tw/blog/assets_c/2011/03/iphone3steps-thumb-240x120-27.jpg" width="240" height="120" alt="使用iPhone三步驟截圖" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a>
之前的<a href="http://server.everfine.com.tw/blog/archives/2010/10/google-fusion-t.html">利用Google Fusion Tables + Google Maps呈現台灣法拍屋</a>，是以地理圖資的觀點來呈現法拍屋的資料。
而相同的資料，放到<a href="http://www.google.com/calendar/">Google Calendar</a>以時間的觀點來呈現另一種角度的法拍屋資料，利用<a href="http://code.google.com/intl/zh-TW/apis/calendar/data/2.0/developers_guide_java.html">Calendar Data API</a>將資料同步到台灣法拍屋行事曆，方便讓有興趣的人訂閱，並以縣市分類，避免資料過載不易閱讀（其實仍有這樣問題），且使用iPhone或iPad，只要配合使用<a href="http://itunes.apple.com/app/goocal-sync-google-calendar/id377012306">GooCal App<img alt="goocal.png" src="http://server.everfine.com.tw/blog/goocal.png"/></a>來訂閱讀取，按下Show event on map還能查閱地圖。</p>

<p>以下是各縣市的法拍行事曆連結。<br/>
<a href="https://www.google.com/calendar/embed?src=8st8gs788b03mb2tgltea82fa4%40group.calendar.google.com">台北市</a>
        <a href="https://www.google.com/calendar/embed?src=830v34ug58340p0dfknn0js3l4%40group.calendar.google.com">新北市</a>
        <a href="https://www.google.com/calendar/embed?src=sg3g8k0v5f616spvmsrp17p2eg%40group.calendar.google.com">基隆市</a>
        <a href="https://www.google.com/calendar/embed?src=448h1onc9qbm7gtri6mr237jjs%40group.calendar.google.com">宜蘭縣</a>
        <a href="https://www.google.com/calendar/embed?src=8st599lvfffovfdrcik86lvgsg%40group.calendar.google.com">桃園縣</a>
        <a href="https://www.google.com/calendar/embed?src=5grhs8mh97ql2peeuuq20qhj5k%40group.calendar.google.com">新竹縣</a>
        <a href="https://www.google.com/calendar/embed?src=8krel1cecrqvqfpt3enerjt96g%40group.calendar.google.com">苗栗縣</a>
        <a href="https://www.google.com/calendar/embed?src=7m7i143vut8jsfufh7df31h5uk%40group.calendar.google.com">台中市</a>
        <a href="https://www.google.com/calendar/embed?src=boo1a9rb8cas9e7itgsn3lb408%40group.calendar.google.com">彰化縣</a>
        <a href="https://www.google.com/calendar/embed?src=kqg41ct7cd9jnflrkk2tvrcepg%40group.calendar.google.com">南投縣</a>
        <a href="https://www.google.com/calendar/embed?src=8cm2v9r8rp6h63obelilba8sqs%40group.calendar.google.com">嘉義縣</a>
        <a href="https://www.google.com/calendar/embed?src=d1phocjqub9q1i1sfkf0uml9do%40group.calendar.google.com">雲林縣</a>
        <a href="https://www.google.com/calendar/embed?src=5d08alpjkdjto9jqtoed36s2nc%40group.calendar.google.com">台南市</a>
        <a href="https://www.google.com/calendar/embed?src=erdjtcpetpmfq0ng5hbf32i0u0%40group.calendar.google.com">高雄市</a>
        <a href="https://www.google.com/calendar/embed?src=a7ov8ub1cju53bdr5t0tuhl8io%40group.calendar.google.com">屏東縣</a>
        <a href="https://www.google.com/calendar/embed?src=j8n6r1rkjioa98tqolggclfsqs%40group.calendar.google.com">花蓮縣</a>
        <a href="https://www.google.com/calendar/embed?src=1i9kgmtd89f3ptcpvkd1oai604%40group.calendar.google.com">台東縣</a>
        <a href="https://www.google.com/calendar/embed?src=td0m6nn6gdci0n8373vj5be6e0%40group.calendar.google.com">澎湖縣</a>
        <a href="https://www.google.com/calendar/embed?src=one2ok6qnig0gvpjia386papbo%40group.calendar.google.com">連江縣</a>
        <a href="https://www.google.com/calendar/embed?src=n434qm7lfh4n3kdq07ufq59bc8%40group.calendar.google.com">金門縣</a></p>

<p>2011-03-17 Update: 其實亦可使用手機上Web版的<a href="http://www.google.com/calendar/">Google Calendar</a>來點閱。<a href="http://server.everfine.com.tw/blog/MobileGCal.JPG"><img alt="MobileGCal.JPG" src="http://server.everfine.com.tw/blog/assets_c/2011/03/MobileGCal-thumb-160x240-32.jpg" width="160" height="240" class="mt-image-none" style="" /></a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>Using HttpClient 4 for Apache Basic Authentication</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/03/using-httpclien.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.347</id>

    <published>2011-03-11T07:23:35Z</published>
    <updated>2012-01-03T02:48:25Z</updated>

    <summary>private static DefaultHttpClient addAuth(DefaultHttpClient httpclient){ HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() { public void process(final HttpRequest request, final HttpContext context) throws...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<code class="c"><p>private static DefaultHttpClient addAuth(DefaultHttpClient httpclient){<br />
		HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {</p>

<p>			public void process(final HttpRequest request,<br />
					final HttpContext context) throws HttpException,<br />
					IOException {</p>

<p>				String username = "philipz";<br />
				String password = "XXXXXXXX";<br />
				UsernamePasswordCredentials ucreds = new UsernamePasswordCredentials(<br />
						username, password);<br />
				request.addHeader(new BasicScheme().authenticate(ucreds,<br />
						request));<br />
			}</p>

<p>		};</p>

<p>		httpclient.addRequestInterceptor(preemptiveAuth, 0);<br />
		return httpclient;<br />
	}</p></code>]]>
        
    </content>
</entry>

<entry>
    <title>SQL: Update with Subquery</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/01/sql-update-with.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.345</id>

    <published>2011-01-12T09:00:16Z</published>
    <updated>2011-01-12T09:14:46Z</updated>

    <summary>UPDATE Table D SET COL1 = A.COL2 WHERE exists (SELECT 1 FROM Table A INNER JOIN Table B ON A.KEY...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<code class="c">UPDATE Table D SET<br />
COL1 = A.COL2<br />
WHERE exists (SELECT 1<br />
FROM Table A INNER JOIN Table B ON A.KEY = B.KEY<br />
WHERE (B.TITCOD = 'A232  ' OR B.TITCOD = 'A233  ' OR B.TITCOD = 'A243  ' OR  B.TITCOD = 'A9427  ') AND D.KEY = A.KEY) AND D.COL1 &lt;&gt; D.COL2<br />
</code>]]>
        
    </content>
</entry>

<entry>
    <title>如何移除DB2上的全形空白</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2011/01/db2.html" />
    <id>tag:server.everfine.com.tw,2011:/blog//1.344</id>

    <published>2011-01-07T07:46:59Z</published>
    <updated>2011-01-07T07:53:49Z</updated>

    <summary>因Mainframe上的EBCDIC編碼，所以無法直接Replace掉。需先透過vargraphic函數才可以。 Replace(vargraphic(YOURCOL),'　', '')...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>因Mainframe上的EBCDIC編碼，所以無法直接Replace掉。需先透過vargraphic函數才可以。<br />
<code class= 'c'><br />
Replace(vargraphic(YOURCOL),'　', '')<br />
</code></p>]]>
        
    </content>
</entry>

<entry>
    <title>JavaMail + Google App Engine throw "The API package 'mail' or call 'Send()' was not found."</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2010/12/javamail-google.html" />
    <id>tag:server.everfine.com.tw,2010:/blog//1.343</id>

    <published>2010-12-08T07:13:54Z</published>
    <updated>2010-12-09T01:53:34Z</updated>

    <summary>Just like Smartclient forums problem, still need some jar files of GAE. My code is Message msg = new MimeMessage(session);...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[Just like <a href="http://forums.smartclient.com/showthread.php?t=8589">Smartclient forums</a> problem, still need some jar files of GAE.<br />
My code is <br />
<code class="c"><p>
		Message msg = new MimeMessage(session);<br />
		try {<br />
			msg.setFrom(new InternetAddress("xxxx@gmail.com"));<br />
			msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(<br />
					email, false));<br />
			msg.setSubject("ALERT!!!");<br />
			msg.setText("TEXT");<br />
			msg.setSentDate(new Date());<br />
			Transport.send(msg);<br />
		} </p></code><br />
But, it will throw out exception.
<code class="c">
<p>com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'mail' or call 'Send()' was not found.<br />
	at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:70)<br />
	at com.google.appengine.api.mail.MailServiceImpl.doSend(MailServiceImpl.java:96)<br />
	at com.google.appengine.api.mail.MailServiceImpl.send(MailServiceImpl.java:33)<br />
	at com.google.appengine.api.mail.stdimpl.GMTransport.sendMessage(GMTransport.java:247)<br />
	at javax.mail.Transport.send(Transport.java:95)</p>
</code>
<p>So, change the code from static class to instance, like:</p>
<code class="c">
<p>			Transport transport = session.getTransport("smtp");<br />
			transport.connect("smtp.gmail.com", 465, "username", "password");<br />
			transport.sendMessage(message, message.getAllRecipients());<br />
			transport.close();
</p></code>
<p>Maybe Java Reflection mechanism is a major cause of this exception.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Gson Exception: No-args constructor for class XXX does not exit.</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2010/11/gson-exception.html" />
    <id>tag:server.everfine.com.tw,2010:/blog//1.342</id>

    <published>2010-11-27T03:07:48Z</published>
    <updated>2010-11-27T14:07:35Z</updated>

    <summary>Use JDO and RESTful web services at GAE. Usually need to parser JSON format string by Gson. But, some JDO...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[Use <a href="http://code.google.com/intl/en/appengine/docs/java/gettingstarted/usingdatastore.html">JDO</a> and <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services">RESTful web services</a> at <a href="http://code.google.com/intl/en/appengine/">GAE</a>. Usually need to parser JSON format string by <a href="http://code.google.com/p/google-gson/">Gson</a>. But, some JDO class doesn't have No-args constructor, public YourClass(){}, and therefore the gson instance will throw out exception, No-args constructor for class XXX does not exit.<br />
There are two ways to fix this problem:<br />
One, add No-args constructor in the JDO class.<br />
The other is use InstanceCreator to instead a no-argument constructor.<br />
Example:<br />
<code class="c"><p>public class YourClassInstanceCreator implements InstanceCreator&lt;YourClass&gt; {<br /><span class="Apple-tab-span" style="white-space:pre">		</span> &nbsp;public YourClass createInstance(Type type) {<br /><span class="Apple-tab-span" style="white-space:pre">		</span> &nbsp; &nbsp;return new YourClass(null, null, null, null);<br /><span class="Apple-tab-span" style="white-space:pre">		</span> &nbsp;}<br /><span class="Apple-tab-span" style="white-space:pre">	</span>}</p></code>
Then build the gson instance through GsonBuilder, like <br />
<code class="c">
GsonBuilder builder = new GsonBuilder(); <br />
builder.registerTypeAdapter(YourClass.class, new YourClassInstanceCreator());<br />
Gson gson = builder.create();<br />
stoken = gson.fromJson(json, YourClass.class);</code>]]>
        
    </content>
</entry>

<entry>
    <title>Call Plurk API by HttpClient 4</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2010/11/call-plurk-api.html" />
    <id>tag:server.everfine.com.tw,2010:/blog//1.341</id>

    <published>2010-11-24T02:13:23Z</published>
    <updated>2010-11-24T02:25:11Z</updated>

    <summary>之前的噗浪(Plurk)期貨即時訊息文章中，說道IM發噗會有掉噗情況，目前改用Plurk Api後，情況有改善。程式如下： import java.io.IOException;import java.net.URLEncoder;import org.apache.http.HttpHost;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.CookieStore;import org.apache.http.client.methods.HttpGet;import org.apache.http.conn.params.ConnRoutePNames;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;public class PlurkApi { private static final...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>之前的<a href="http://server.everfine.com.tw/blog/archives/2009/07/plurk.html">噗浪(Plurk)期貨即時訊息</a>文章中，說道IM發噗會有掉噗情況，目前改用<a href="http://www.plurk.com/API" >Plurk Api</a>後，情況有改善。程式如下：</p>
<code class = "c"><p><p>import java.io.IOException;</p><p>import java.net.URLEncoder;</p><p><br /></p><p>import org.apache.http.HttpHost;</p><p>import org.apache.http.HttpResponse;</p><p>import org.apache.http.HttpStatus;</p><p>import org.apache.http.client.ClientProtocolException;</p><p>import org.apache.http.client.CookieStore;</p><p>import org.apache.http.client.methods.HttpGet;</p><p>import org.apache.http.conn.params.ConnRoutePNames;</p><p>import org.apache.http.impl.client.DefaultHttpClient;</p><p>import org.apache.http.util.EntityUtils;</p><p><br /></p><p>public class PlurkApi {</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private static final String API_KEY = "KEYSTRING";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static boolean use_proxy = false;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static String PROXY_NAME = "proxy.hinet.net";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static int PROXY_PORT = 80;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static CookieStore cookiestore;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String username= "youraccount";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String password= "yourpassword";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private volatile static PlurkApi plurk;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private PlurkApi(){}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static PlurkApi getInstance(){</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>if (plurk == null) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>synchronized (PlurkApi.class){</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>if (plurk == null) {</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>plurk = new PlurkApi();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return plurk;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><br /></p><p>&nbsp;&nbsp; &nbsp;public static String getApiUri(String uri) {</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return "http://www.plurk.com/API" + uri;</p><p>&nbsp;&nbsp; &nbsp;}</p><p><br /></p><p>&nbsp;&nbsp; &nbsp;public final static void main(String[] args) {</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>PlurkApi p = PlurkApi.getInstance();</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>p.plurkAdd("API測試111111！");</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>p.logout();</p><p>&nbsp;&nbsp; &nbsp;}</p><p>&nbsp;&nbsp; &nbsp;</p><p>&nbsp;&nbsp; &nbsp;public String login() {</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>DefaultHttpClient httpclient = new DefaultHttpClient();</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (use_proxy) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>HttpHost proxy = new HttpHost(PROXY_NAME, PROXY_PORT);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>proxy);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;HttpGet httpget = new HttpGet(getApiUri("/Users/login?"+</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"api_key=" + API_KEY + "&amp;" +</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"username=" + username + "&amp;" +</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"password=" + password</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;));</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;HttpResponse response = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String responseString = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>response = httpclient.execute(httpget);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>cookiestore = httpclient.getCookieStore();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// 如果回傳是 200 OK 的話才輸出</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>//</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>} else {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(response.getStatusLine());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (ClientProtocolException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (IOException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>httpclient.getConnectionManager().shutdown();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return responseString;</p><p>&nbsp;&nbsp; &nbsp;}</p><p>&nbsp;&nbsp; &nbsp;</p><p>&nbsp;&nbsp; &nbsp;public String plurkAdd(String url) {</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>PlurkApi p = PlurkApi.getInstance();</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>if (cookiestore == null)</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">		</span>p.login();</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>DefaultHttpClient httpclient = new DefaultHttpClient();</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (use_proxy) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>HttpHost proxy = new HttpHost(PROXY_NAME, PROXY_PORT);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>proxy);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;httpclient.setCookieStore(cookiestore);</p><p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;HttpResponse response = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String responseString = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String content = URLEncoder.encode(url, "UTF-8");</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>HttpGet httpget = new HttpGet(getApiUri("/Timeline/plurkAdd?"+</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"api_key=" + API_KEY + "&amp;" +</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"content=" + content + "&amp;" +</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"qualifier=" + "says" + "&amp;" +</p><p><span class="Apple-tab-span" style="white-space:pre">	</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"lang=tr_ch"));</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>response = httpclient.execute(httpget);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>cookiestore = httpclient.getCookieStore();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// 如果回傳是 200 OK 的話才輸出</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>//</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>} else {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(response.getStatusLine());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (ClientProtocolException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (IOException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>httpclient.getConnectionManager().shutdown();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return responseString;</p><p>&nbsp;&nbsp; &nbsp;}</p><p><br /></p><p>&nbsp;&nbsp; &nbsp;public String logout() {</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>PlurkApi p = PlurkApi.getInstance();</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>if (cookiestore == null)</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">		</span>p.login();</p><p>&nbsp;&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>DefaultHttpClient httpclient = new DefaultHttpClient();</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (use_proxy) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>HttpHost proxy = new HttpHost(PROXY_NAME, PROXY_PORT);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>proxy);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;httpclient.setCookieStore(cookiestore);</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;HttpResponse response = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String responseString = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span> HttpGet httpget = new HttpGet(getApiUri("/Users/logout?"+</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "api_key=" + API_KEY));</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>response = httpclient.execute(httpget);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>cookiestore = httpclient.getCookieStore();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// 如果回傳是 200 OK 的話才輸出</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>//</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>} else {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(response.getStatusLine());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (ClientProtocolException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (IOException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>// TODO Auto-generated catch block</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>httpclient.getConnectionManager().shutdown();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return responseString;</p><p>&nbsp;&nbsp; &nbsp;}</p><p>}</p></p></code>]]>
        
    </content>
</entry>

<entry>
    <title>如何遠端呼叫需特定權限的Google App Engine service</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2010/11/google-app-engi-2.html" />
    <id>tag:server.everfine.com.tw,2010:/blog//1.340</id>

    <published>2010-11-20T07:26:05Z</published>
    <updated>2010-11-20T08:21:48Z</updated>

    <summary>參考：Accessing a security-enabled Google App Engine service from a Java client 如果您撰寫一個GAE servlet，卻是特定權限，如admin，才能執行的service，透過人工輸入網頁是沒多大問題，但如果要用程式去遠端呼叫，卻需要先取得一個token，利用Google Data API的GoogleAuthTokenFactory，呼叫程式如下： import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.logging.Logger;import...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p>參考：<a href="http://krasserm.blogspot.com/2010/01/accessing-security-enabled-google-app.html">Accessing a security-enabled Google App Engine service from a Java client</a><br />
</p>
<p>
如果您撰寫一個<a href="http://code.google.com/appengine/">GAE</a> servlet，卻是特定權限，如admin，才能執行的service，透過人工輸入網頁是沒多大問題，但如果要用程式去遠端呼叫，卻需要先取得一個token，利用<a href="http://code.google.com/intl/zh-TW/apis/gdata/">Google Data API</a>的<a href="http://code.google.com/intl/zh-TW/apis/gdata/javadoc/com/google/gdata/client/GoogleAuthTokenFactory.html">GoogleAuthTokenFactory</a>，呼叫程式如下：<br /></p>
<code class = "c"><p><p>import java.io.IOException;</p><p>import java.io.UnsupportedEncodingException;</p><p>import java.net.URLEncoder;</p><p>import java.util.logging.Logger;</p><p><br /></p><p>import org.apache.http.HttpHost;</p><p>import org.apache.http.HttpResponse;</p><p>import org.apache.http.HttpStatus;</p><p>import org.apache.http.client.ClientProtocolException;</p><p>import org.apache.http.client.CookieStore;</p><p>import org.apache.http.client.methods.HttpGet;</p><p>import org.apache.http.client.params.ClientPNames;</p><p>import org.apache.http.client.params.CookiePolicy;</p><p>import org.apache.http.conn.params.ConnRoutePNames;</p><p>import org.apache.http.impl.client.DefaultHttpClient;</p><p>import org.apache.http.util.EntityUtils;</p><p><br /></p><p>import com.google.gdata.client.GoogleAuthTokenFactory;</p><p>import com.google.gdata.util.AuthenticationException;</p><p><br /></p><p>public class AppEngineAPI {</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static CookieStore cookiestore;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String loginUrl = "http://yours.appspot.com/_ah/login?continue=";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static boolean use_proxy = false;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static String PROXY_NAME = "proxy.hinet.net";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static int PROXY_PORT = 80;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String serviceUrl = "http://yours.appspot.com/admin/service?";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String username = "your account";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String password = "your password";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final String serviceName = "ah";</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static final GoogleAuthTokenFactory factory = new GoogleAuthTokenFactory(serviceName, "", null);</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>static String token;&nbsp;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>private static final Logger log = Logger.getLogger(AppEngineAPI.class</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>.getName());</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String[] args) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String token = factory.getAuthToken(username, password, null, null, serviceName, "");</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String serviceUrl1 = serviceUrl + "a=a&b=b";</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>String loginUrl1 = loginUrl + URLEncoder.encode(serviceUrl1, "UTF-8") + "&amp;auth=" + token;</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>httpget(loginUrl1);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (AuthenticationException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>log.warning(e.toString());</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (UnsupportedEncodingException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>log.warning(e.toString());</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>e.printStackTrace();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}<span class="Apple-tab-span" style="white-space:pre">		</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">	</span></p><p><span class="Apple-tab-span" style="white-space:pre">	</span>public static String httpget(String url) {</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>DefaultHttpClient httpclient = new DefaultHttpClient();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>if (use_proxy) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>HttpHost proxy = new HttpHost(PROXY_NAME, PROXY_PORT);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,</p><p><span class="Apple-tab-span" style="white-space:pre">					</span>proxy);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>HttpGet httpget = new HttpGet(url);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>// Override the default policy for this request</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>httpget.getParams().setParameter(ClientPNames.COOKIE_POLICY,</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>CookiePolicy.BROWSER_COMPATIBILITY);</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>HttpResponse response = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>String responseString = null;</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>try {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>response = httpclient.execute(httpget);</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>cookiestore = httpclient.getCookieStore();</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>responseString = EntityUtils.toString(response.getEntity());</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// 如果回傳是 200 OK 的話才輸出</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>// System.out.println(responseString);</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>//</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>} else {</p><p><span class="Apple-tab-span" style="white-space:pre">				</span>System.out.println(response.getStatusLine());</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p><p><br /></p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (ClientProtocolException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>log.warning(e.toString());</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>} catch (IOException e) {</p><p><span class="Apple-tab-span" style="white-space:pre">			</span>log.warning(e.toString());</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>httpclient.getConnectionManager().shutdown();</p><p><span class="Apple-tab-span" style="white-space:pre">		</span>return responseString;</p><p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p><p>}</p><div><br /></div></p>
</code>
<p>相關知識：維基百科<a href="http://zh.wikipedia.org/zh-tw/OpenID">OpenID</a>、<a href="http://zh.wikipedia.org/zh-tw/OAuth">OAuth</a>，Google文件<a href="http://code.google.com/intl/zh-TW/apis/accounts/docs/OpenID.html">OpenID</a>、<a href="http://code.google.com/intl/zh-TW/apis/accounts/docs/OAuth.html">OAuth</a>。</p>]]>
        
    </content>
</entry>

<entry>
    <title>Three approaches show Multi-Polygon in Google Maps</title>
    <link rel="alternate" type="text/html" href="http://server.everfine.com.tw/blog/archives/2010/10/three-approache.html" />
    <id>tag:server.everfine.com.tw,2010:/blog//1.339</id>

    <published>2010-10-28T00:36:54Z</published>
    <updated>2011-04-14T04:58:27Z</updated>

    <summary>The simplest method is to include the KML file. But, this KML approach in Google Maps API is not support...</summary>
    <author>
        <name>philipz</name>
        <uri>http://server.everfine.com.tw/blog/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://server.everfine.com.tw/blog/">
        <![CDATA[<p><a href="http://server.everfine.com.tw/blog/multipolygon/kml.html">The simplest method</a> is to include the <a href="http://code.google.com/intl/zh-TW/apis/kml/documentation/">KML</a> file. But, this KML approach in Google Maps API is not support Dynamic KML, it will have no effect. The <a href="http://labs.micromata.de/display/jak/Home">JAK Java API for KML</a> can generate KML file.<br />
<iframe src ="http://server.everfine.com.tw/blog/multipolygon/kml.html" width="500" height="300"><br />
  <p>Your browser does not support iframes.</p><br />
</iframe></p>

<p><a href="http://server.everfine.com.tw/blog/multipolygon/JSON.html">Second method</a> is using JSON data from <a href="http://www.geocodezip.com/v3_polygon_example_california.html">geocodezip.com</a>. This can work very well at dynamic polygon.<br />
<iframe src ="http://server.everfine.com.tw/blog/multipolygon/JSON.html" width="500" height="300"><br />
  <p>Your browser does not support iframes.</p><br />
</iframe></p>

<p><a href="http://server.everfine.com.tw/blog/multipolygon/XML.html">Last method</a> is using XML data from <a href="http://gmaps-samples-v3.googlecode.com/svn/trunk/xmlparsing/">XML Parsing</a> at <a href="http://code.google.com/intl/zh-TW/apis/maps/documentation/javascript/demogallery.html">Google Demo Gallery</a>. This can also work very well at dynamic polygon.<br />
<iframe src ="http://server.everfine.com.tw/blog/multipolygon/XML.html" width="500" height="300"><br />
  <p>Your browser does not support iframes.</p><br />
</iframe></p>]]>
        
    </content>
</entry>

</feed>

