<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2618695401132183697</id><updated>2012-01-21T19:46:38.635+09:00</updated><category term='日付'/><category term='帳票'/><category term='コマンド'/><category term='Fedora'/><category term='DNS'/><category term='JSP'/><category term='SQL'/><category term='パスワード'/><category term='Seasar'/><category term='Hibernate'/><category term='削除'/><category term='api'/><category term='ファイル実行'/><category term='Clob'/><category term='ブラウザ三国志'/><category term='evernote'/><category term='引数'/><category term='カラム一覧'/><category term='UserStore'/><category term='IPTable'/><category term='Flex'/><category term='フラッシュメモリ'/><category term='TitleWindow'/><category term='エンコード'/><category term='limit'/><category term='Assets.swf'/><category term='引数埋込'/><category term='初期化'/><category term='Google+'/><category term='Struts'/><category term='MySQL'/><category term='作成'/><category term='検索'/><category term='FileReference'/><category term='jsunit'/><category term='sequence'/><category term='Dijkstra'/><category term='ResourceBundle'/><category term='URL'/><category term='文字列'/><category term='一覧'/><category term='OpenLDAP'/><category term='ログアウト'/><category term='コンポーネント'/><category term='BPEL'/><category term='Groovy'/><category term='メール受信'/><category term='グラフ'/><category term='Json'/><category term='Tomcat'/><category term='DIGEST'/><category term='RESTful'/><category term='NFS'/><category term='パス'/><category term='iPhone'/><category term='PostgreSQL'/><category term='HMAC-SHA1'/><category term='バージョン管理'/><category term='surpre'/><category term='Tree'/><category term='RoR'/><category term='WindowsPhone'/><category term='Intalio'/><category term='redmine'/><category term='JavaMail'/><category term='マシン名'/><category term='Cursor'/><category term='bit.ly'/><category term='twitter4j'/><category term='JavaScript'/><category term='ChromeExtension'/><category term='Order'/><category term='マップ'/><category term='ネットワーク'/><category term='.NET'/><category term='Meta'/><category term='メール'/><category term='ファイルアップロード'/><category term='再起動'/><category term='パンくず'/><category term='yahoo'/><category term='Twitter'/><category term='OAuth'/><category term='Velocity'/><category term='セッション'/><category term='RadioButton'/><category term='起動'/><category term='Explorer'/><category term='シャットダウン'/><category term='jenkins'/><category term='ActionScript'/><category term='DataGrid'/><category term='アンチウィルス'/><category term='Enhance'/><category term='Papervision3D'/><category term='データベース'/><category term='Oracle'/><category term='環境変数'/><category term='User'/><category term='don-gabacho'/><category term='Taglib'/><category term='localStorage'/><category term='ガツン'/><category term='labelFunction'/><category term='jetty'/><category term='CD-R'/><category term='関連'/><category term='ci'/><category term='Indexes'/><category term='canvas'/><category term='404'/><category term='認証'/><category term='HTTPService'/><category term='Application'/><category term='DataNucleus'/><category term='ユーザ'/><category term='ChromeExtention'/><category term='Efflex'/><category term='ant'/><category term='無線LAN'/><category term='GoogleAnalytics'/><category term='HDD'/><category term='GoogleCode'/><category term='mixi'/><category term='NULL'/><category term='リリース'/><category term='HSQLDB'/><category term='GAE'/><category term='認証情報'/><category term='BPM'/><category term='Java'/><category term='TELNET'/><category term='JDBC'/><category term='C#'/><category term='Slim3'/><category term='RegExp'/><category term='Ruby'/><category term='FormFile'/><category term='更新'/><category term='Linux'/><category term='ユーザ追加'/><category term='Singleton'/><category term='ログファイル'/><category term='BigTable'/><category term='正規表現'/><category term='JDO'/><category term='SVN'/><category term='FlashLite'/><category term='画像'/><title type='text'>大河内教授の憂鬱</title><subtitle type='html'>システムに絶対はない。だからシステム屋は悩み続けなければならん。君の苦悩を私は支持するよ。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default?start-index=101&amp;max-results=100'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>153</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5345078465096921269</id><published>2012-01-21T14:18:00.000+09:00</published><updated>2012-01-21T14:18:15.417+09:00</updated><title type='text'>jQueryでドラッグ＆ドロップ</title><content type='html'>&lt;pre&gt;&lt;br /&gt;自分用のブログエンジンを作っていて、&lt;br /&gt;要素をドラッグ＆ドロップしながら章立てできるようなものにしたいなと思い&lt;br /&gt;要素をどんどん追加していこうと思い、&lt;br /&gt;最初draggable,droppable辺りを利用していたんだけど、&lt;br /&gt;追加したい場所や、追加した要素の順番を変更したりと&lt;br /&gt;sortableが必要だったので少し書いてみる。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;何がしたいか？&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;・ドラッグして要素の追加&lt;br /&gt;・ドラッグしたものは残す&lt;br /&gt;・ドラッグしたものを変更&lt;br /&gt;・ドロップする場所は順序変更が可能&lt;br /&gt;&lt;br /&gt;これによりコンテンツを編集していく感じ&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;ソートの準備&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;まずソートしたい要素に対して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt; $(".content-box").sortable({&lt;br /&gt;  placeholder:'ui-state-highlight',&lt;br /&gt;  connectWith: $('.content-box'),&lt;br /&gt;  axis:'y',&lt;br /&gt;  update : function (event,ui) {&lt;br /&gt;   //順序を変更した後&lt;br /&gt;  },&lt;br /&gt;  receive : function (event,ui) {&lt;br /&gt;   //他から要素が追加された場合&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;と行います。placeholder：移動する場所に対してのスタイルを指定します。これで色の変更などを行なって移動を行いやすくします。connectWith：移動できる場所を自分自身のみにしています。axis：yを指定して縦方向だけ移動できるようにしています。update,receiveはイベントですが、updateは順序を変更した場合のみに発生、receiveは他から要素が入ってきた時です。receive発生時もupdateは発生します。一旦はこれだけでcontent-box内の要素の順序変更ができるようになります。&lt;div class="caption"&gt;ドラッグしてくる側の設定&lt;/div&gt;ここが一番苦労したというか気づかなかったというか。ドラッグする側に対してもsortableで対応しないと、ドラッグできないのではないか？と思ってそうしてたのですが、cloneが効かなかったり、何かとやりたい事に対してうまくいかなかったのですが、まずドラッグしたい要素に対して、ドラッグをできるようにします。&lt;pre name="code" class="js"&gt;&lt;br /&gt; // アイテムのドラッグ&lt;br /&gt; $('.item').draggable({&lt;br /&gt;    cursor: 'move', &lt;br /&gt;    opacity: 0.7,&lt;br /&gt;    connectToSortable: $('.content-box'),&lt;br /&gt;          helper:'clone'&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;cursor：カーソルの変更opacity：移動時の透明度connectToSortable：指定した場所にはsortableの対象として扱ってくれるので上記で指定した「ui-state-highlight」をやってくれます。helper：移動中の表示をコピーにしています。これに対しては実際はfunctionも扱えるので移動する時に表示を変えたい場合はfunctionを指定して戻り値でタグを返します。&lt;div class="caption"&gt;まぁこれで大体できるんだけど、、、&lt;/div&gt;私の場合はitemの部分とcontent-box内の要素が違います。この状態で行うとitemのタグがそのまま配置されてしまうのでreceiveイベントの時に&lt;pre name="code" class="js"&gt;&lt;br /&gt;    var addTag = createContentItem(itemName);&lt;br /&gt;    var dropItem = $(this).children(".item");&lt;br /&gt;    dropItem.after(addTag);&lt;br /&gt;    dropItem.remove();&lt;br /&gt;&lt;/pre&gt;新しくタグを追加してあげて、ドロップした要素を削除しています。当初はどちらもsortableを指定しないと要素の追加場所がわからないのではないか？と思って指定していたのですが、片方をドラッグにしてcloneを行えば良い事に気付いたので後は追加要素を追加削除するだけでした。connectToSortableに気づいたら非常に簡単にできました。ただsortableでhelperにclone指定をした場合にうまく動作しなかったのが少し解せない感じでした。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5345078465096921269?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5345078465096921269/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5345078465096921269' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5345078465096921269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5345078465096921269'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2012/01/jquery.html' title='jQueryでドラッグ＆ドロップ'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8687643170071954046</id><published>2012-01-18T13:12:00.001+09:00</published><updated>2012-01-18T13:12:28.072+09:00</updated><title type='text'>MacでXtionを動作させる</title><content type='html'>&lt;pre&gt;&lt;br /&gt;Macでの動作もしておこうと思ったので&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/kaorun55/20111103/1320362289"&gt;ここ&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;を参考にしました。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;前準備&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;portが1.9だと失敗したので2.0系のupdateから開始&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;sudo port selfupdate&lt;br /&gt;sudo port install libtool&lt;br /&gt;sudo port install libusb-devel +universal&lt;br /&gt;&lt;/pre&gt;かなりインストールに時間がかかりました＞＜。&lt;div class="caption"&gt;ドライバ等&lt;/div&gt;&lt;a href="http://www.openni.org/Downloads/OpenNIModules.aspx"&gt;本家&lt;/a&gt;のunstableからMacOS用のopenni-bin-dev-macosx-v1.5.2.23.tar.bz2nite-bin-macosx-v1.5.2.21.tar.bz2sensor-bin-macosx-v5.1.0.41.tar.bz2をダウンロードしてくる。それぞれinstall.shが存在するのでそれらを実行。これでOKでした。sudoが必要なものはsudoで行なってください。通常のSampleはこれで動作するのですがJava実行だと&lt;pre name="code" class="java"&gt;&lt;br /&gt;java.lang.UnsatisfiedLinkError: no OpenNI.jni in java.library.path&lt;br /&gt;&lt;/pre&gt;が出てしまいます。&lt;pre name="code" class="java"&gt;&lt;br /&gt;java -Djava.library.path=/usr/lib -jar jarファイル&lt;br /&gt;&lt;/pre&gt;で動作しました。Mac miniですが640x480だと重くてデータを飛ばせなかった＞＜。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8687643170071954046?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8687643170071954046/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8687643170071954046' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8687643170071954046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8687643170071954046'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2012/01/macxtion.html' title='MacでXtionを動作させる'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3471390530089480109</id><published>2012-01-09T14:13:00.000+09:00</published><updated>2012-01-18T13:58:08.551+09:00</updated><title type='text'>Xtionがやってきた。</title><content type='html'>&lt;pre&gt;&lt;br /&gt;Xtionがやってきたので、少し触ってみる。&lt;br /&gt;XtionはKinectと同様にOpenNIを利用したモーションキャプチャーです。&lt;br /&gt;Kinectは現状ではハードウェアが商用利用は不可ですが、Xtionは商用利用が可能です。&lt;br /&gt;&lt;br /&gt;特に商用利用が目的ではないのですが、&lt;br /&gt;USBバスで動作するのでこちらを購入したというところが強いのですが、&lt;br /&gt;Kinectで行うとハック感がなくなるかな？というところで、&lt;br /&gt;Xtionにしました。Xtion Pro Liveです。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;OpenNIのインストール&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;まず付属してたDVDだと古そうだったので&lt;br /&gt;&lt;a href="http://www.openni.org/Downloads/OpenNIModules.aspx"&gt;本家&lt;/a&gt;からPackageを入れます。&lt;br /&gt;古い記事だと64ビットだと動作しないみたいな話がありますが&lt;br /&gt;この時点では動作するようです。&lt;br /&gt;&lt;br /&gt;Macについては&lt;a href="http://secondarykey.blogspot.com/2012/01/macxtion.html"&gt;後述&lt;/a&gt;しておきました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;どんなものを作るのか？&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;友人が電子書籍系をやっているのだけど「マイノリティ・リポートやろうぜっ」って感じだったので&lt;br /&gt;そういうものを作ろうと思った。&lt;br /&gt;動かすのはiPadのようなタブレットだった。iPadにOpenNIとか非現実的な事だし、&lt;br /&gt;私自身がxcodeでソレ系のアプリを作る気もないし、&lt;br /&gt;とにかく相手にプッシュする方法が必要だったので、&lt;br /&gt;相手がサーバでこっちがクライアントという選択肢だと、&lt;br /&gt;こっちから接続しなきゃいけないし、何かと不便に感じた。&lt;br /&gt;&lt;br /&gt;ちょうどRFCにWebSocketが載ったところだったのでこっちをサーバにしてWebSocketを実装する事にした。&lt;br /&gt;Javaで動作するものを作ろうと思ったのでJettyでWebSocketサーバを作成して、&lt;br /&gt;そこから何らかのクライントでWebSocketにアクセスしてもらって通信をやろうと思った。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;WebSocketを作る&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/naga_sawa/20111018/1318930805"&gt;ここ&lt;/a&gt;を参考に&lt;br /&gt;サーバサイドは作成した。&lt;br /&gt;&lt;br /&gt;実際はChatRoom的な管理は必要ないわけだけど、&lt;br /&gt;例えばHTML(WebSocketでアクセスできるもの)で資料を作って&lt;br /&gt;それをみんなの端末で見る～。。。なんてI/Fも想定してたりしてなかったり。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;HandTrackerを発見！&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;はじめはサンプルの「UserTracker」を元に作り始めた。&lt;br /&gt;Userを認識してSkeletonCapabilityで骨格を認識させて、&lt;br /&gt;それで手の動きを見ようと考えていたんだけど、&lt;br /&gt;「GestureGenerator」「HandsGenerator」が存在する事を知り&lt;br /&gt;&lt;a href="https://github.com/OpenNI/OpenNI/tree/master/Samples/HandTracker.java/org/OpenNI/Samples/HandTracker"&gt;ココ&lt;/a&gt;に「HandTracker」のサンプルがあるので拝借。&lt;br /&gt;※っていうか最新のパッケージならローカルにも展開されてます。&lt;br /&gt;&lt;br /&gt;サンプル読んだおかげで大体の動作は理解できた。&lt;br /&gt;&lt;br /&gt;・Contextやら読み込んで各Generatorを初期化&lt;br /&gt;・イベントに対してObserverを作成(コールバック)&lt;br /&gt;・ループして&lt;br /&gt;・ノードを更新してノードからデータを取得&lt;br /&gt;・何かやる&lt;br /&gt;&lt;br /&gt;みたいな流れみたい。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;HandsGeneratorでジェスチャーを認識&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;このサンプルにGestureGeneratorに対して"Click"とあり、&lt;br /&gt;これがセンサーに向かって手をpullしたり、調べた限りだと"Wave"などを認識できるようなんだけど&lt;br /&gt;「これにLeftとかRightをかあれば楽？」と考えたりもしたけど&lt;br /&gt;&lt;br /&gt;&lt;a href="http://openni.org/docs2/Tutorial/classxn_1_1_hands_generator.html"&gt;この辺り&lt;/a&gt;を読むと&lt;br /&gt;サンプルの通りGestureGeneratorで認識させてからHandsで行うのが通常の使い方みたい。&lt;br /&gt;サンプルは&lt;br /&gt;&lt;br /&gt;・GestureGeneratorに"Click"を登録&lt;br /&gt;・イベント発生でHandsGeneratorのトラッキングを開始&lt;br /&gt;・Update系のイベントでそのポイントを取得して履歴に残す&lt;br /&gt;・ポイントの履歴を描画&lt;br /&gt;・手の認識が終わったらGestureGeneratorの"Click"を再度登録&lt;br /&gt;&lt;br /&gt;みたいな流れ。&lt;br /&gt;Updateで履歴があるのでこれを使って&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; public static SocketType getType(float modX, float modY, float modZ) {&lt;br /&gt;&lt;br /&gt;  SocketType type = SocketType.NONE;&lt;br /&gt;  if ( Math.abs(modY) &amp;lt; margin ) {&lt;br /&gt;   if ( modX &amp;lt; (movement*-1) ) {&lt;br /&gt;    type = SocketType.LEFT;&lt;br /&gt;   } else if ( modX &amp;gt; movement ) {&lt;br /&gt;    type = SocketType.RIGHT;&lt;br /&gt;   }&lt;br /&gt;  } else if ( Math.abs(modX) &amp;lt; margin ) {&lt;br /&gt;   if ( modY &amp;lt; (movement*-1) ) {&lt;br /&gt;    type = SocketType.DOWN;&lt;br /&gt;   } else if ( modY &amp;gt; movement ) {&lt;br /&gt;    type = SocketType.UP;&lt;br /&gt;   }&lt;br /&gt;  } else {&lt;br /&gt;   if ( modZ &amp;lt; (movement*-1) ) {&lt;br /&gt;    type = SocketType.ZOOMIN;&lt;br /&gt;   } else if ( modZ &amp;gt; movement ) {&lt;br /&gt;    type = SocketType.ZOOMOUT;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return type;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;みたいな座標の移動量を計算させて、どっちに動いているかを判定※SocketTypeってのはオリジナルのEnumです。あとはソケットで送るだけ。まぁこれだと調整値によって認識とかしまくりとか認識しないとかさんざんなのでもう少し何かする必要があるかな？&lt;div class="caption"&gt;感想&lt;/div&gt;何かライブラリ使ってもう少し何かできそうな流れだったけど、自分で理解するのも含めて作ってみた。サンプルを理解したところをもう少し書きたかったんだけど、またそれは別の機会でもあれば。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3471390530089480109?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3471390530089480109/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3471390530089480109' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3471390530089480109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3471390530089480109'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2012/01/xtion.html' title='Xtionがやってきた。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-566527606471183212</id><published>2012-01-06T22:32:00.000+09:00</published><updated>2012-01-06T22:39:14.814+09:00</updated><title type='text'>undefinedという値について</title><content type='html'>引数に「undefined」って指定してあるのなんで？と言っていた人がいた。jQueryの話だったけど、JavaScriptの癖(癌)を利用したトリックだと推測。undefinedはグローバルスコープの変数だから、引数に対してundefinedを代入して、ローカルスコープに持って来てロジックによっては処理を早くしたり、undefinedの値をローカル内で保証できる状況になるという仮説を立てたけど、「引数間違って指定したら失敗するんじゃね？」と思ったので試してみた。&lt;pre name="code" class="js"&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;&lt;br /&gt;function undefinedTest1(arg1) {&lt;br /&gt; if ( arg1 === undefined ) {&lt;br /&gt;  console.log("1");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function undefinedTest2(arg1,undefined) {&lt;br /&gt; if ( arg1 === undefined ) {&lt;br /&gt;  console.log("2");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var val;&lt;br /&gt;console.log("undefined");&lt;br /&gt;undefinedTest1(val);&lt;br /&gt;undefinedTest2(val);&lt;br /&gt;&lt;br /&gt;console.log("変数に値を入れてみる");&lt;br /&gt;undefined = true;&lt;br /&gt;undefinedTest1(val);&lt;br /&gt;undefinedTest2(val);&lt;br /&gt;&lt;br /&gt;console.log("第2引数に値を入れてみる");&lt;br /&gt;undefinedTest2(val,"test");&lt;br /&gt;&lt;br /&gt;// --&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;でコンソールは&lt;pre name="code" class="html"&gt;&lt;br /&gt;undefined&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;変数に値を入れてみる&lt;br /&gt;2&lt;br /&gt;第2引数に値を入れてみる&lt;br /&gt;&lt;/pre&gt;まず、関数が正常に動作している事を確認。グローバルスコープのundefinedに値を代入すると関数１の値は不可能になり、間違って引数指定をすると、undefinedに値が代入されて、関数２もアウト。まぁ十分テストされていれば第２引数の指定はないだろうから危なくはないのかな？思ったとおりの動きだったのでひとまず満足。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-566527606471183212?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/566527606471183212/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=566527606471183212' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/566527606471183212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/566527606471183212'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2012/01/undefined.html' title='undefinedという値について'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5027894644828240901</id><published>2011-12-05T10:42:00.001+09:00</published><updated>2011-12-14T23:26:40.453+09:00</updated><title type='text'>リストボックスを引っ張って更新</title><content type='html'>&lt;pre&gt;&lt;br /&gt;スマートフォンでSNS系のアプリを使っていて&lt;br /&gt;「更新ボタン」を押しているとなんとなく未来感がない。&lt;br /&gt;Twitterの公式アプリ等はそうだが、上側に引っ張るとリストが更新される。&lt;br /&gt;&lt;br /&gt;WindowsPhoneでもこれを行なってみようと思ったら&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/b/shintak/archive/2011/08/06/10193347.aspx"&gt;高橋忍氏のブログ&lt;/a&gt;や&lt;br /&gt;その書籍&lt;a href="http://www.amazon.co.jp/dp/4822294471"&gt;プログラミングWindowsPhone&lt;/a&gt;でも紹介されています。&lt;br /&gt;&lt;br /&gt;んじゃ書く必要ないじゃん。と思いましたけど少し書いてみます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;スタイルを変更&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ListBoxの中身はScrollViewerで構成されているので、&lt;br /&gt;ScrollViewerのVerticalCompressionというVisualStateGroupを利用して&lt;br /&gt;ListBoxの状態を把握しようってことですね。&lt;br /&gt;&lt;br /&gt;上記のブログにはPageごとの設定とありますけど&lt;br /&gt;私的にはアプリケーション内で指定したいのでApp.xmlにApplication.Resoucesとして定義しています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html:collapse"&gt;&lt;br /&gt;    &amp;lt;Application.Resources&amp;gt;&lt;br /&gt;        &amp;lt;Style TargetType="ScrollViewer"&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="VerticalScrollBarVisibility" Value="Auto"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="Background" Value="Transparent"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="Padding" Value="0"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="BorderThickness" Value="1"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="BorderBrush" Value="Transparent"/&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property="Template"&amp;gt;&lt;br /&gt;                &amp;lt;Setter.Value&amp;gt;&lt;br /&gt;                    &amp;lt;ControlTemplate TargetType="ScrollViewer"&amp;gt;&lt;br /&gt;                        &amp;lt;Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"&amp;gt;&lt;br /&gt;                            &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;&lt;br /&gt;                                &amp;lt;VisualStateGroup x:Name="ScrollStates"&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualStateGroup.Transitions&amp;gt;&lt;br /&gt;                                        &amp;lt;VisualTransition GeneratedDuration="00:00:00.5"/&amp;gt;&lt;br /&gt;                                    &amp;lt;/VisualStateGroup.Transitions&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualState x:Name="Scrolling"&amp;gt;&lt;br /&gt;                                        &amp;lt;Storyboard&amp;gt;&lt;br /&gt;                                            &amp;lt;DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/&amp;gt;&lt;br /&gt;                                            &amp;lt;DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalScrollBar"/&amp;gt;&lt;br /&gt;                                        &amp;lt;/Storyboard&amp;gt;&lt;br /&gt;                                    &amp;lt;/VisualState&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualState x:Name="NotScrolling"/&amp;gt;&lt;br /&gt;                                &amp;lt;/VisualStateGroup&amp;gt;&lt;br /&gt;                                &amp;lt;VisualStateGroup x:Name="VerticalCompression"&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualState x:Name="NoVerticalCompression"/&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualState x:Name="CompressionTop"/&amp;gt;&lt;br /&gt;                                    &amp;lt;VisualState x:Name="CompressionBottom"/&amp;gt;&lt;br /&gt;                                &amp;lt;/VisualStateGroup&amp;gt;&lt;br /&gt;                            &amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;&lt;br /&gt;                            &amp;lt;Grid Margin="{TemplateBinding Padding}"&amp;gt;&lt;br /&gt;                                &amp;lt;ScrollContentPresenter x:Name="ScrollContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/&amp;gt;&lt;br /&gt;                                &amp;lt;ScrollBar x:Name="VerticalScrollBar" HorizontalAlignment="Right" Height="Auto" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Opacity="0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" VerticalAlignment="Stretch" Width="5"/&amp;gt;&lt;br /&gt;                                &amp;lt;ScrollBar x:Name="HorizontalScrollBar" HorizontalAlignment="Stretch" Height="5" IsHitTestVisible="False" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Opacity="0" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}" VerticalAlignment="Bottom" Width="Auto"/&amp;gt;&lt;br /&gt;                            &amp;lt;/Grid&amp;gt;&lt;br /&gt;                        &amp;lt;/Border&amp;gt;&lt;br /&gt;                    &amp;lt;/ControlTemplate&amp;gt;&lt;br /&gt;                &amp;lt;/Setter.Value&amp;gt;&lt;br /&gt;            &amp;lt;/Setter&amp;gt;&lt;br /&gt;        &amp;lt;/Style&amp;gt;&lt;br /&gt;    &amp;lt;/Application.Resources&amp;gt;&lt;br /&gt;&lt;/pre&gt;この記述によって、アプリケーションのすべてのScrollViewerで圧縮した場合のイベントの発生が可能になります。※私には縦の必要がないのでVerticalのみです。&lt;div class="caption"&gt;ListBoxから取り出してイベントを登録&lt;/div&gt;上記ブログにある通り(そのままのコード)ListBoxからScrollViewerを取り出して変更があったというイベントに登録します。&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        private void ListBoxCompressionHandling(ListBox targetlistbox)&lt;br /&gt;        {&lt;br /&gt;            VisualStateGroup vgroup = new VisualStateGroup();&lt;br /&gt;&lt;br /&gt;            // ListBox の初めに定義されている ScrollViewerを取り出す &lt;br /&gt;            ScrollViewer ListboxScrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(targetlistbox, 0);&lt;br /&gt;&lt;br /&gt;            // Visual State はコントロールテンプレートの常に最上位に定義されている &lt;br /&gt;            FrameworkElement element = (FrameworkElement)VisualTreeHelper.GetChild(ListboxScrollViewer, 0);&lt;br /&gt;            // Visual State を取り出しその中から 縦横Compression のVisualStateを取り出す &lt;br /&gt;            foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(element))&lt;br /&gt;                if (group.Name == "VerticalCompression") vgroup = group;&lt;br /&gt;&lt;br /&gt;            //縦横Compressionの状態が変わった時のイベントハンドラ &lt;br /&gt;            vgroup.CurrentStateChanging += new EventHandler&amp;lt;VisualStateChangedEventArgs&amp;gt;(ScrollViewer_CurrentStateChanging);&lt;br /&gt;        } &lt;br /&gt;&lt;/pre&gt;でイベントは&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        void ScrollViewer_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            switch (e.NewState.Name) &lt;br /&gt;            { &lt;br /&gt;                case "CompressionTop":&lt;br /&gt;                    break; &lt;br /&gt;                case "CompressionBottom": &lt;br /&gt;                    break;&lt;br /&gt;                case "NoVerticalCompression":&lt;br /&gt;                    break; &lt;br /&gt;                default: &lt;br /&gt;                    break; &lt;br /&gt;            } &lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;で、この関数をLoadなどのイベントで呼び出すのですがLoadは何度も呼び出されるので、画面遷移が多いような画面だったら重複して登録してしまうので一度だけ登録するようにしておくのが良いでしょう。&lt;div class="caption"&gt;で何がしたいか？&lt;/div&gt;これだと高橋忍氏のブログそのまま(アプリで登録した位の違い)です。私的にはスクロールを「グッ」とした時にだけ、更新をしたいのです。このままだと少しでも上にするだけでイベントが発生します。んじゃ、圧縮イベントと圧縮が終わったイベントの時刻で処理してみよう！&lt;div class="caption"&gt;アプローチ&lt;/div&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        DateTime startTopTime = new DateTime(0);&lt;br /&gt;        DateTime startBottomTime = new DateTime(0);&lt;br /&gt;        DateTime endTime = new DateTime(0);&lt;br /&gt;        private void InitCompression()&lt;br /&gt;        {&lt;br /&gt;            startTopTime = new DateTime(0);&lt;br /&gt;            startBottomTime = new DateTime(0);&lt;br /&gt;            endTime = new DateTime(0);&lt;br /&gt;        }&lt;br /&gt;        private Boolean IsCompressionTop() {&lt;br /&gt;            if (!startTopTime.Equals(new DateTime(0)))&lt;br /&gt;            {&lt;br /&gt;                TimeSpan ts = endTime.Subtract(startTopTime);&lt;br /&gt;                System.Diagnostics.Debug.WriteLine(ts.TotalSeconds);&lt;br /&gt;                if (ts.TotalSeconds &amp;gt;= 0.9)&lt;br /&gt;                {&lt;br /&gt;                    return true;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void ScrollViewer_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            switch (e.NewState.Name) &lt;br /&gt;            { &lt;br /&gt;                case "CompressionTop":&lt;br /&gt;                    startTopTime = DateTime.Now;&lt;br /&gt;                    break; &lt;br /&gt;                case "CompressionBottom": &lt;br /&gt;                    startBottomTime = DateTime.Now;&lt;br /&gt;                    break;&lt;br /&gt;                case "NoVerticalCompression":&lt;br /&gt;                    endTime = DateTime.Now;&lt;br /&gt;                    if (IsCompressionTop())&lt;br /&gt;                    {&lt;br /&gt;                        MessageBox.Show("できたよー");&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                    InitCompression();&lt;br /&gt;                    break; &lt;br /&gt;                default: &lt;br /&gt;                    break; &lt;br /&gt;            } &lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;こうしてみると、確かにグッとした後にイベント発生ができるんだけどリストを離して戻った時の判定になってしまう。できれば、グッとしている間にイベントを発生したい。。。。もっといい方法があるような気がする。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5027894644828240901?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5027894644828240901/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5027894644828240901' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5027894644828240901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5027894644828240901'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/12/blog-post.html' title='リストボックスを引っ張って更新'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-800975041044935215</id><published>2011-11-19T09:41:00.001+09:00</published><updated>2011-11-24T16:48:46.924+09:00</updated><title type='text'>WindowsPhoneの初期化と通信でトラブルヽ(´Д`；)ﾉ</title><content type='html'>&lt;pre&gt;&lt;br /&gt;ちょっと失敗したので書いておく。&lt;br /&gt;WindowsPhoneにおいて、通信は非同期処理しかサポートしていない。&lt;br /&gt;ってのは有名な話だと思いますが、&lt;br /&gt;OAuth認可の部分で少し失敗したのでメモしておく。&lt;br /&gt;&lt;br /&gt;Access Tokenが切れていた場合、&lt;br /&gt;Refresh Tokenを用いて再度トークンを取得してくる必要があります。&lt;br /&gt;&lt;br /&gt;私はリフレッシュトークンを実装する前&lt;br /&gt;&lt;br /&gt;・トークンが存在したら、アプリのメニュー画面&lt;br /&gt;・トークンが存在しなかったら、ログイン画面&lt;br /&gt;&lt;br /&gt;としていました。&lt;br /&gt;&lt;br /&gt;これに&lt;br /&gt;・トークンが存在しても、期限が切れていたらリフレッシュトークンで再発行処理&lt;br /&gt;という部分を追加しました。&lt;br /&gt;&lt;br /&gt;しかし、何度やってもResponseが返って来ませんでした。&lt;br /&gt;&lt;br /&gt;結論から言うと既存処理の遷移の為、Defaultの画面が存在しませんでした。&lt;br /&gt;なので画面用のスレッドが作成されず、&lt;br /&gt;そのまま通信を行なってしまって、スレッドが同じになって、&lt;br /&gt;同期処理とみなされていた。(なんかもう少し細かい話がありそうですけど)&lt;br /&gt;&lt;br /&gt;って感じのようです。&lt;br /&gt;Defaultを設定してあげて、そこから再発行をしたらすんなり動きました´ω｀&lt;br /&gt;この画面がよくありがちな、アプリのロゴを出す画面でして&lt;br /&gt;ほぼ見えない画面なのですが、何かしっくりこないです。&lt;br /&gt;&lt;br /&gt;※お陰でBackで終了するという処理も必要になりました。&lt;br /&gt;&lt;a href="http://blogs.msdn.com/b/shintak/archive/2011/07/16/10187146.aspx"&gt;本人が推奨はしてません&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;一旦APIキーのみでアクセスできる検索画面にして、&lt;br /&gt;ユーザにログインボタンを提示する画面を作って無駄のないようにしようと考えています。&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-800975041044935215?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/800975041044935215/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=800975041044935215' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/800975041044935215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/800975041044935215'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/11/windowsphone.html' title='WindowsPhoneの初期化と通信でトラブルヽ(´Д`；)ﾉ'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-708651528689771955</id><published>2011-10-30T14:29:00.004+09:00</published><updated>2011-10-30T14:31:33.019+09:00</updated><title type='text'>objectのjsonデータを変換する。</title><content type='html'>&lt;pre&gt;&lt;br /&gt;Google+のAPIの戻り値に"object"というオブジェクトデータがあり、&lt;br /&gt;これがC#の予約後に引っかかってしまい、NewtonsoftのJSONパーサで解析をしていると無理になります。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://developers.google.com/+/api/latest/activities#resource"&gt;https://developers.google.com/+/api/latest/activities#resource&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;なので&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;            private ObjectData objectValue;&lt;br /&gt;            [Newtonsoft.Json.JsonPropertyAttribute("object")]&lt;br /&gt;            public virtual ObjectData Object&lt;br /&gt;            {&lt;br /&gt;                get&lt;br /&gt;                {&lt;br /&gt;                    return this.objectValue;&lt;br /&gt;                }&lt;br /&gt;                set&lt;br /&gt;                {&lt;br /&gt;                    this.objectValue = value;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;/pre&gt;とすればOKです。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-708651528689771955?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/708651528689771955/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=708651528689771955' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/708651528689771955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/708651528689771955'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/objectjson.html' title='objectのjsonデータを変換する。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6959180723190384211</id><published>2011-10-28T08:58:00.000+09:00</published><updated>2011-10-28T08:58:24.962+09:00</updated><title type='text'>WindowsPhoneで最初の画面を選ぶ</title><content type='html'>&lt;pre&gt;&lt;br /&gt;OAuth認証は基本的に最初の一回でOKのはずです。&lt;br /&gt;なのでアクセストークン(もしくはリフレッシュトークン)を持っていて&lt;br /&gt;通信可能な状態だった場合、別の画面を表示する必要があります。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;画面を作る&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;まず縦向きのページを作成します。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-f4zhqSsbhck/TqnqtkyM7RI/AAAAAAAAAaA/gFbVGbG-SMI/s1600/WS000000.JPG" imageanchor="1" style=""&gt;&lt;img border="0" height="285" width="400" src="http://2.bp.blogspot.com/-f4zhqSsbhck/TqnqtkyM7RI/AAAAAAAAAaA/gFbVGbG-SMI/s400/WS000000.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;分岐を作成する&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;App.xamlに対して、Startupイベントを指定します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;Application &lt;br /&gt;    x:Class="Ziro.PlusPhone.App"&lt;br /&gt;    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"&lt;br /&gt;    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"&lt;br /&gt;    Startup="Application_Startup"&amp;gt;&lt;br /&gt;&lt;/pre&gt;で、App.xzml.csにコードができるので&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        private void Application_Startup(object sender, StartupEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (oauth.Load())&lt;br /&gt;            {&lt;br /&gt;                RootFrame.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                RootFrame.Navigate(new Uri("/LoginPage.xaml", UriKind.Relative));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;という風に条件式を作ってあげて、遷移先を変更してあげます。私の場合、OAuth認証があるかどうかで判断しています。&lt;div class="caption"&gt;デフォルトの画面を読み込ませない&lt;/div&gt;次にプロジェクトの「Properties」内にあるWMAppManifest.xmlのTasksタグにあるDefaultTaskのNavigationPageを削除します。&lt;pre name="code" class="html"&gt;&lt;br /&gt;    &amp;lt;Tasks&amp;gt;&lt;br /&gt;      &amp;lt;DefaultTask Name="_default" NavigationPage="/MainPage.xaml"/&amp;gt;&lt;br /&gt;    &amp;lt;/Tasks&amp;gt;&lt;br /&gt;↓&lt;br /&gt;    &amp;lt;Tasks&amp;gt;&lt;br /&gt;      &amp;lt;DefaultTask Name="_default"/&amp;gt;&lt;br /&gt;    &amp;lt;/Tasks&amp;gt;&lt;br /&gt;&lt;/pre&gt;これをやっておかないと強制的にここが優先されます。これでOKです。&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6959180723190384211?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6959180723190384211/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6959180723190384211' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6959180723190384211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6959180723190384211'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/windowsphone.html' title='WindowsPhoneで最初の画面を選ぶ'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-f4zhqSsbhck/TqnqtkyM7RI/AAAAAAAAAaA/gFbVGbG-SMI/s72-c/WS000000.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8018306697011637372</id><published>2011-10-27T21:41:00.000+09:00</published><updated>2011-10-27T21:48:07.737+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Json'/><category scheme='http://www.blogger.com/atom/ns#' term='WindowsPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>非同期で結果を受け取る</title><content type='html'>&lt;pre&gt;&lt;br /&gt;WindowsPhoneの非同期処理の理念は伝わっているけど、、、&lt;br /&gt;C#の言語理解が足りないから実装方法がわからない。&lt;br /&gt;GoogleのAPIの実装を見た時に「うわっこんな実装になるのか。。。なんで？」って&lt;br /&gt;ところが理解できてなかったと再度思うことになった。&lt;br /&gt;&lt;/pre&gt;&lt;div class="caption"&gt;何がしたいか？&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;WindowsPhoneでGoogle+にアクセスしたい。&lt;br /&gt;そこで処理を書いていくと&lt;br /&gt;&lt;br /&gt;1.OAuthの部分（＋その後の処理）をGUIと切り離したいのでライブラリ化しておきたい。&lt;br /&gt;　－だけどアクセスは非同期処理になるので、データが返ってくるタイミングがわからない。&lt;br /&gt;2.なのでそのデータをどう使うかはPhone側関数の処理にしたい。&lt;br /&gt;3.その関数の引数はJsonの生データ(string)ではなくて、型が決まった状態で受け取りたい。&lt;br /&gt;　－Newtonsoft.JsonのDeserializeObject()を呼び出すのでT型で呼び出したい。&lt;br /&gt;&lt;br /&gt;この位の知識で実装してたら、あれ？あれ？って感じになったのでまとめておく。&lt;br /&gt;&lt;/pre&gt;&lt;div class="caption"&gt;レスポンスデータ取得後の呼び出し&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;最終的にT型で関数を呼び出すという目標に対して、&lt;br /&gt;レスポンスが受けとったデータを呼び出すので&lt;br /&gt;&lt;/pre&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        public IJsonResult target;&lt;br /&gt;&lt;br /&gt;        string = {レスポンスデータ};&lt;br /&gt;        target.SendJson(data);&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;みたいな実装が必要なのでまずインターフェースを定義してみた。&lt;br /&gt;これは生成時にT型が必要なのですが、呼び出し時にtargetをインスタンス化する為です。&lt;br /&gt;&lt;/pre&gt;&lt;div class="caption"&gt;SendJson()の実装&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;で、SendJson()の実装はジェネリックを利用して&lt;br /&gt;&lt;/pre&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;    public class JsonResult&amp;lt;T&amp;gt; : Ziro.OAuth.IJsonResult where T : JsonData &lt;br /&gt;    {&lt;br /&gt;        private Action&amp;lt;T&amp;gt; action;&lt;br /&gt;        public JsonResult(Action&amp;lt;T&amp;gt; lambda )&lt;br /&gt;        {&lt;br /&gt;            action = lambda;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        public void SendJson(string responseData) {&lt;br /&gt;            //データを解析&lt;br /&gt;            T jsonData = JsonConvert.DeserializeObject&amp;lt;T&amp;gt;(responseData);&lt;br /&gt;            action(jsonData);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;として、文字列をT型でデシリアイズして、それを引数にaction()を呼び出しています。&lt;br /&gt;action()は引数がT型のラムダ式を引数に持つ式をコンストラクタで受け取ってます。&lt;br /&gt;&lt;/pre&gt;&lt;div class="caption"&gt;リクエストの呼び出し&lt;/div&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;        private void GetMe()&lt;br /&gt;        {&lt;br /&gt;            oauth.target = new JsonResult&amp;lt;GooglePlusData.Person&amp;gt;(GetPeople);&lt;br /&gt;            oauth.GetPeople("me");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void GetPeople(GooglePlusData.Person person)&lt;br /&gt;        {&lt;br /&gt;            //元のスレッドでメイン画面に遷移&lt;br /&gt;            this.Dispatcher.BeginInvoke(() =&amp;gt; NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)));&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;って感じでOKです。&lt;br /&gt;GetPeple()はUrlを作成して、GETしています。&lt;br /&gt;&lt;br /&gt;これでJsonResultの生成時に型情報と受け取りの実装を渡します。&lt;br /&gt;&lt;/pre&gt;&lt;div class="caption"&gt;総括&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;一瞬、OAuthを直接行う部分のインスタンス化を行う時にT型を使おうとしたのですが、&lt;br /&gt;アクセストークンをやり取りするのがだるかったのでこうしています。&lt;br /&gt;※おそらく後で分散ストレージを使うので、そうしなくても良かったかな？とも思ってます。&lt;br /&gt;こうしておくことで多分他のOAuthを作りたい感じになった時に楽になるかな。。。と勝手に思ってます。&lt;br /&gt;&lt;br /&gt;ここに行くまでﾌﾞﾋｰって感じでした。&lt;br /&gt;C#の知識が乏しい状況での実装なので、本当にこれでいいのかも不明です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;JavaScript辺りのゆるふわな感じと、Javaの静的な感じが実現できていて素晴らしいなぁ。&lt;br /&gt;結論としては、、、λｶﾜｲｲ。。。&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8018306697011637372?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8018306697011637372/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8018306697011637372' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8018306697011637372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8018306697011637372'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/blog-post.html' title='非同期で結果を受け取る'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1648248027285031925</id><published>2011-10-26T22:33:00.000+09:00</published><updated>2011-10-26T22:34:31.936+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='Google+'/><category scheme='http://www.blogger.com/atom/ns#' term='WindowsPhone'/><title type='text'>WindowsPhoneでGoogle+に対してOAuth認証</title><content type='html'>Google+APIでの認可を書いて、&lt;br /&gt;後日WindowsPhoneへの移植を試みた。。。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;しかしそれと同時に衝撃の事実。&lt;/div&gt;&lt;div&gt;DLLの参照設定ができないのだ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-gcL3jIlVFPA/TqU6kUHbrcI/AAAAAAAAAZg/BFrmntrzQec/s1600/WS000008.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="147" src="http://1.bp.blogspot.com/-gcL3jIlVFPA/TqU6kUHbrcI/AAAAAAAAAZg/BFrmntrzQec/s320/WS000008.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;「WindowsPhoneアセンブリのみと連動・・・」・・・なんとっ！&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ということでOAuthの生コードを書くことにした。&lt;/div&gt;&lt;div&gt;何か調べるとライブラリは存在するのだが、OAuth1.0っぽいもの(Twitter系)が多くて&lt;/div&gt;&lt;div&gt;勝手に使い物にならないと判断した。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;まぁC#触るの自体久しぶりだし、言語になれる意味でやっていきますか。&lt;/div&gt;&lt;div&gt;ってことで結局Google+のOAuthのページを読むことにした。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/intl/ja/apis/accounts/docs/OAuth2.html"&gt;http://code.google.com/intl/ja/apis/accounts/docs/OAuth2.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;画面の作成&lt;/div&gt;&lt;/div&gt;画面を作ります。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-spp7fELoHfQ/TqYeXO1U63I/AAAAAAAAAZs/4oFPGZEdWIE/s1600/WS000009.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-spp7fELoHfQ/TqYeXO1U63I/AAAAAAAAAZs/4oFPGZEdWIE/s320/WS000009.JPG" width="181" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;OAuthにはブラウザアクセスが必要なので、ブラウザを準備して&lt;br /&gt;作成した認証コードが必要になるのでテキストと認証用のボタンを準備しておきます。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="caption"&gt;認証用のURLの発行&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;上記のURLにある通りにアクセスするURLを作成します。&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Helvetica, Arial, sans-serif; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;https://accounts.google.com/o/oauth2/auth?&lt;br /&gt;  client_id=xxxxxxx.apps.googleusercontent.com&amp;amp;&lt;br /&gt;  redirect_uri=urn:ietf:wg:oauth:2.0:oob&amp;amp;&lt;br /&gt;  scope=https://www.googleapis.com/auth/plus.me&amp;amp;&lt;br /&gt;  response_type=code&lt;/pre&gt;&lt;br /&gt;自分のクライアントIDを添えてブラウザでアクセスします。&lt;br /&gt;scopeに関しては上記のOAuthのサイトでは、別のスコープになってますので注意してください。&lt;br /&gt;&lt;br /&gt;これを画面の初期化時にブラウザに設定して呼び出します。&lt;br /&gt;※もちろん本物のアプリは違うタイミングでしょうけど。&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-a1zjfWToSXE/TqYfVr5XA0I/AAAAAAAAAZ0/7TAmw6n2Cdc/s1600/WS000010.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-a1zjfWToSXE/TqYfVr5XA0I/AAAAAAAAAZ0/7TAmw6n2Cdc/s320/WS000010.JPG" width="169" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;こういう風にGoogleの認証ページになります。&lt;br /&gt;認証は前にやった時と同じように行います。で認可が下りると&lt;br /&gt;AuthCodeが発行された画面になります。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;&lt;br /&gt;&lt;div class="caption"&gt;アクセストークンを取得する&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;AuthCodeコードがブラウザ画面に出ますので下にあるテキストボックスに貼付け&lt;br /&gt;「認証」ボタンを押したところで&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Helvetica, Arial, sans-serif; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;https://accounts.google.com/o/oauth2/token&lt;/pre&gt;&lt;br /&gt;のURLに対して&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Helvetica, Arial, sans-serif; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;POST /o/oauth2/token HTTP/1.1&lt;br /&gt;Host: accounts.google.com&lt;br /&gt;Content-Type: application/x-www-form-urlencoded&lt;br /&gt;&lt;br /&gt;client_id=xxxxxxxxx.apps.googleusercontent.com&amp;amp;&lt;br /&gt;client_secret=xxxxxxxxxxx&amp;amp;&lt;br /&gt;code={AuthCode}&amp;amp;&lt;br /&gt;redirect_uri=urn:ietf:wg:oauth:2.0:oob&amp;amp;&lt;br /&gt;grant_type=authorization_code&lt;/pre&gt;&lt;br /&gt;というポストを書いてあげます。&lt;br /&gt;「code」は認証した後に発行された認証コードをテキストボックスに設定した値になります。&lt;br /&gt;&lt;br /&gt;ここでWindowsPhoneは非同期処理しかないので送信には&lt;br /&gt;BeginGetResponse(),BeginGetResponse()などを利用する必要があります。&lt;br /&gt;&lt;br /&gt;これにより&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Helvetica, Arial, sans-serif; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;{&lt;br /&gt;  "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",&lt;br /&gt;  "expires_in":3920,&lt;br /&gt;  "token_type":"Bearer",&lt;br /&gt;  "refresh_token":"1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ"&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;というような文字列が取得できます。&lt;br /&gt;これらの解析にはNewtonsoft.Json.Silverlightを使用しました。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;&lt;br /&gt;&lt;div class="caption"&gt;Google+にアクセスする。&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;さてアクセストークンができたので何はともあれアクセスです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'MS PGothic'; font-size: small; line-height: normal; white-space: normal;"&gt;https://www.googleapis.com/plus/v1/&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'MS PGothic'; font-size: small; line-height: normal; white-space: normal;"&gt;people/me?&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'MS PGothic'; font-size: small; line-height: normal; white-space: normal;"&gt;access_token=xxxxxx&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;とアクセスしてあげたら自分の情報が取れます。&lt;br /&gt;※meは自分の情報ってことなのでAPI的にはuserIdを指定してあげればOKです。&lt;br /&gt;&lt;br /&gt;これでまたJsonが戻ってきますので、解析してあげたらOKなわけです。&lt;br /&gt;OAuth2.0ですので、アクセストークンの時間が切れた場合は&lt;br /&gt;refresh_tokenで再発行を行う必要があります。&lt;br /&gt;&lt;br /&gt;その際はアクセストークン時に使用した引数を&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Helvetica, Arial, sans-serif; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;refresh_token=1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ&amp;amp;&lt;br /&gt;grant_type=refresh_token&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と変えて再発行すれば再認可は必要なくなります。&lt;br /&gt;※refresh_tokenも期限はあるみたいです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;総括&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;基本的にはOAuthの説明です。&lt;br /&gt;やったことある方なら通常のGoogleのドキュメントだけでOKだと思います。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;詳しいAPIの説明は&lt;br /&gt;&lt;a href="https://developers.google.com/+/api/"&gt;https://developers.google.com/+/api/&lt;/a&gt;&lt;br /&gt;にあります。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;注意すべきは&lt;br /&gt;・現状ではGoogleのクライアントAPIでは、WindowsPhoneアプリは無理なこと。&lt;br /&gt;・WindowsPhoneの非同期等のポリシーなどでWebアクセスが通常ではないこと。&lt;br /&gt;・C#が結構ｲｹﾃﾙ事。&lt;br /&gt;・API呼び出しはBearerを利用した方がいいと思います。&lt;br /&gt;・更新系のGoogle+APIがまだ&lt;br /&gt;&lt;br /&gt;WindowsPhoneとC#になれる時間もいるのでゆっくりクライアントを作っていく予定。&lt;br /&gt;&lt;br /&gt;さて、ではWindowsPhoneアプリの開発ですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1648248027285031925?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1648248027285031925/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1648248027285031925' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1648248027285031925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1648248027285031925'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/windowsphonegoogleoauth.html' title='WindowsPhoneでGoogle+に対してOAuth認証'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-gcL3jIlVFPA/TqU6kUHbrcI/AAAAAAAAAZg/BFrmntrzQec/s72-c/WS000008.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-2332061339188681661</id><published>2011-10-23T17:07:00.000+09:00</published><updated>2011-10-23T17:07:34.220+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='Google+'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>.NET(C#) でGoogleOAuthを行なってみる。</title><content type='html'>&lt;br /&gt;IS12Tを手にいれたけど、何かアプリつくろう！って思って考えてたら&lt;br /&gt;Google+のクライアントがないことに気づいたのでそれを作ってみようと思う。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;サンプルを読み込む&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;とにかくOAuthアクセスを実現する必要があるはずなので&lt;br /&gt;まずはサンプルを取得してきます。&lt;br /&gt;&lt;br /&gt;https://developers.google.com/+/downloads&lt;br /&gt;http://code.google.com/p/google-api-dotnet-client/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-kmlXpfiwVFU/TqOt7GpgqsI/AAAAAAAAAZI/pQKFhb_qHTU/s1600/WS000004.JPG" imageanchor="1"&gt;&lt;img border="0" height="54" src="http://2.bp.blogspot.com/-kmlXpfiwVFU/TqOt7GpgqsI/AAAAAAAAAZI/pQKFhb_qHTU/s400/WS000004.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ここにサンプルとあるのでそれを取得。&lt;br /&gt;※各種OAuthとかの文章ありますけど、ソースとかが古かったりですね。&lt;br /&gt;&lt;br /&gt;「Tasks.SimpleOAuth2」というプロジェクトがコンソールでできるやつみたいなので&lt;br /&gt;そちらをスタートプロジェクトにして実行するわけですけど、&lt;br /&gt;「Google.Apis.Samples.TasksOAuth2.ClientCredentials」に&lt;br /&gt;APIキーの設定のがあるの以下のように設定します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public static readonly string ClientID = "xxxxxxxx.apps.googleusercontent.com";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// The OAuth2.0 Client secret of your project.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public static readonly string ClientSecret = "xxxxxxxxxxxxxxxxlOd2y";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// Your Api/Developer key.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public static readonly string ApiKey = "urn:xxxxxxxxxx";&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;OAuth用の準備&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;https://code.google.com/apis/console&lt;br /&gt;&lt;br /&gt;に行ってGoogle+APIをONにしておきます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-2lzMJl9g2B8/TqNyrx-ec0I/AAAAAAAAAYw/xUzY87tDpqg/s1600/WS000000.JPG" imageanchor="1"&gt;&lt;img border="0" height="33" src="http://3.bp.blogspot.com/-2lzMJl9g2B8/TqNyrx-ec0I/AAAAAAAAAYw/xUzY87tDpqg/s400/WS000000.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;今は「Courtesy limit: 1,000 queries/day」なので&lt;br /&gt;１日1000回のアクセスまでのようですね。。。。ん？ユーザじゃなくてAPIキーでかな？&lt;br /&gt;&lt;br /&gt;API AccessのところにOAuth2.0があるのでそこでキーを発行します。&lt;br /&gt;OAuthでお馴染みのClientIDとSecretですね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-ScXAS67auaU/TqNz2nhWPPI/AAAAAAAAAY8/Sz7a_c1ix2I/s1600/WS000001.JPG" imageanchor="1"&gt;&lt;img border="0" height="123" src="http://2.bp.blogspot.com/-ScXAS67auaU/TqNz2nhWPPI/AAAAAAAAAY8/Sz7a_c1ix2I/s400/WS000001.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;Google PlusのAPIを使ってみる&lt;/div&gt;&lt;br /&gt;このサンプルはTasks APIの&lt;br /&gt;PlusのDLLはBinaryサンプルのServiceの中にあります。&lt;br /&gt;これを参照設定して追加してPlusServiceを使えるようにしておきます。&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Display the header and initialize the sample.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CommandLine.EnableExceptionHandling();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CommandLine.DisplayGoogleSampleHeader("Google+ API");&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;コンソールにGoogleのロゴを出す部分ですね。特に大事なコードではないです。&lt;br /&gt;一応TaskになっていたのでGoogle+に変更。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Register the authenticator.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; provider.ClientIdentifier = ClientCredentials.ClientID;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; provider.ClientSecret = ClientCredentials.ClientSecret;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var auth = new OAuth2Authenticator&amp;lt;NativeApplicationClient&amp;gt;(provider, GetAuthorization);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ここでClientIDとSecretを使ってURLを作成している処理です。&lt;br /&gt;GetAuthrorizarionは、サンプルであるProgram.csにあります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Get the auth URL:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IAuthorizationState state = new AuthorizationState(new[] { PlusService.Scopes.PlusMe.GetStringValue() });&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Uri authUri = arg.RequestUserAuthorization(state);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Request authorization from the user (by opening a browser window):&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Process.Start(authUri.ToString());&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.Write(" &amp;nbsp;Authorization Code: ");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; string authCode = Console.ReadLine();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // Retrieve the access token by using the authorization code:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return arg.ProcessUserAuthorization(authCode, state);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NativeApplicationClient&amp;nbsp;を元にOAuthにアクセスするURLを作成していきます。&lt;br /&gt;IAuthorizarionStateでTasksのGetStringValue()を読んでいるのでPlusServiceにしてあげます。&lt;br /&gt;実行するとこんな感じです。&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Vf1d3Utjr0M/TqO0eb8g_UI/AAAAAAAAAZQ/BwAZxKpzZA0/s1600/WS000005.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="190" src="http://3.bp.blogspot.com/-Vf1d3Utjr0M/TqO0eb8g_UI/AAAAAAAAAZQ/BwAZxKpzZA0/s320/WS000005.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;ReadLine()でOAuthの認証コードを待ち受けます。&lt;br /&gt;※実際の実行タイミングはFetch()するまでアクセスはされません。&lt;br /&gt;&lt;br /&gt;Process.Start()で作成したURLにアクセスしますのでこれと同時にブラウザが立ちあがってるはずです。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-cLSGoWWN46g/TqO6u2beGUI/AAAAAAAAAZY/aoHpmMqh25k/s1600/WS000006.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://4.bp.blogspot.com/-cLSGoWWN46g/TqO6u2beGUI/AAAAAAAAAZY/aoHpmMqh25k/s320/WS000006.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;アクセスを許可するとキーが発行されるのでそれをコンソールにコピペして、Enterします。&lt;br /&gt;タスクに対して&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var service = new PlusService(auth);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Person me = service.People.Get("me").Fetch();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CommandLine.WriteLine(" &amp;nbsp; &amp;nbsp; ^2" + me.Name);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ActivitiesResource.Collection collection = new ActivitiesResource.Collection();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ActivityFeed feed = service.Activities.List("me",collection).Fetch();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; foreach (Activity list in feed.Items)&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CommandLine.WriteLine(" &amp;nbsp; &amp;nbsp; ^2" + list.Title);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CommandLine.PressAnyKeyToExit();&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;と行なってみたら、自分の投稿を取得できました。&lt;/div&gt;&lt;div&gt;はじめ自分のIDを指定して検索してたんですが&lt;/div&gt;&lt;div&gt;「うんなもんOAuthじゃねーヽ(`Д´)ﾉﾌﾟﾝﾌﾟﾝ」だったんですけど"me"で取得できました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;一旦これでアクセス自体はできたみたいですね。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;途中、OAuthとGoogle+のAPIと.NETのAPIを読んでいてパニック起こしました。&lt;/div&gt;&lt;div&gt;誰がどれを作っているのかわからなくなったからです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;上位のクラスとか結構しっかり作ってある感じなので&lt;/div&gt;&lt;div&gt;簡単にOAuth(Google+API)にアクセスすることができます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;これをネタにWindowsPhoneクライアントを作るっていう大きな作業が待ってます。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-2332061339188681661?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/2332061339188681661/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=2332061339188681661' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2332061339188681661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2332061339188681661'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/netc-googleoauth.html' title='.NET(C#) でGoogleOAuthを行なってみる。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-kmlXpfiwVFU/TqOt7GpgqsI/AAAAAAAAAZI/pQKFhb_qHTU/s72-c/WS000004.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1836353341233163319</id><published>2011-10-12T07:07:00.018+09:00</published><updated>2011-10-12T13:21:24.602+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ci'/><category scheme='http://www.blogger.com/atom/ns#' term='jenkins'/><category scheme='http://www.blogger.com/atom/ns#' term='jsunit'/><title type='text'>Jenkinsを利用したJSUnitの実行</title><content type='html'>普段、Java周りではJenkinsを利用していますが、&lt;br /&gt;静岡ITPro勉強会インフラ部でBTS周りをやる事になったので、&lt;br /&gt;CIの発表としてJenkinsの利用方法をやる事になりました。&lt;br /&gt;&lt;br /&gt;通常Javaでテスト作ってMavenで構成して、SVNでつなげるというパターンが多いのですが&lt;br /&gt;勉強会で発表する事もあり(Java屋さんがいない)少しいつもと違う環境で動作させる事にしました。&lt;br /&gt;という事でJavaScriptのプロジェクトを準備して、GitHubに連携って方法を行なってみる事にしました。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;継続的インテグレーションの意義&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Jenkinsはソース管理システムからソースコードを引っ張ってきて、テストを実行してレポートをする。&lt;br /&gt;というのが王道の使い方です。&lt;br /&gt;これを常時繰り返す事で、常にソースコードはテストを常に実行され、健全な状態に保って行く事が可能です。&lt;br /&gt;Cronみたいなイメージでも使用できますが、レポート等も取れ、可視化できるので&lt;br /&gt;インフラ周りでも使う事は可能だと思います。&lt;br /&gt;&lt;br /&gt;開発の現場(出先など)で苦労する点としては&lt;br /&gt;・ビルドサーバを準備できない&lt;br /&gt;・そもそもテストが自動化できてない＞＜。&lt;br /&gt;等と苦労する点があります。&lt;br /&gt;&lt;br /&gt;管理者自身を助ける(単体テストの可視化と報告)優秀なやつなのですが&lt;br /&gt;案外管理者等に伝わらない事が問題だと思っています。&lt;br /&gt;※まぁこれは私のちから不足なのですが。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;インストール&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;通常私の開発環境周りではTomcatが多いのですが、&lt;br /&gt;軽いほうがいいかな？っと思い、軽量なコンテナのJettyを採用してみました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://download.eclipse.org/jetty/stable-7/dist/"&gt;ここからダウンロード&lt;/a&gt;してきます。&lt;br /&gt;ポート変更はetc/jetty.xmlでport(デフォは8080)の部分を変更すれば可能です。&lt;br /&gt;&lt;br /&gt;「java -jar start.jar」&lt;br /&gt;※ポートを開ける権限が無ければsudo等で実行してください&lt;br /&gt;&lt;br /&gt;でサーバは起動します。&lt;br /&gt;&lt;a href="http://jenkins-ci.org/"&gt;Jenkinsをダウンロード&lt;/a&gt;してきます。&lt;br /&gt;&lt;br /&gt;war形式で配布されています。※一瞬インストーラーになってたので焦った＞＜。&lt;br /&gt;「jankins.war」をJettyの「webapps」ディレクトリに展開すると&lt;br /&gt;&lt;br /&gt;「http://localhost:8080/jenkins/」で起動画面をみる事ができます。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;ジョブ&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ジョブを作ります。&lt;br /&gt;通常はMavenを使って構成しているのですが、その辺りに詳しくないとわかりづらいと思ったので&lt;br /&gt;やはりここはフリースタイルで行なってみる事にした。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;JSUnitでテストを出きるようにする&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Javaのテストは良く書いていますが、JSUnitでテストをするのは初でした。&lt;br /&gt;なのでまずJSUnitを準備してテストできる状況にします。&lt;br /&gt;&lt;br /&gt;http://sourceforge.net/projects/jsunit/files/jsunit/2.2/&lt;br /&gt;&lt;br /&gt;解凍を行ったら&lt;br /&gt;app,css,images,java,build.xml,testRunner.html&lt;br /&gt;をプロジェクトに置きます。&lt;br /&gt;Javaは通常実行時には要らないのですが、JenkinsでJSUnitプラグインを利用する際に指定するので必要です、&lt;br /&gt;build.xmlはserver.xml等と名前を変えておきます。&lt;br /&gt;※後述するビルドを「build.xml」とする為で、どちらも任意の名前で良い。&lt;br /&gt;配置するディレクトリは「jsunit」とか「test」とかで良いと思います。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&amp;lt;script language="JavaScript" type="text/javascript"&amp;gt;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* テストの一覧&lt;br /&gt;*/&lt;br /&gt;function suite() {&lt;br /&gt; var suite = new top.jsUnitTestSuite();&lt;br /&gt; suite.addTestPage('testDesigner.html');&lt;br /&gt; return suite;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;というSuiteを用意して増えた時でも大丈夫な状態にしておきます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&amp;lt;script language="JavaScript" type="text/javascript"&amp;gt;&lt;br /&gt;// テスト用のコード&lt;br /&gt;function testMethod() {&lt;br /&gt;assertEquals($('.item').length,3);&lt;br /&gt;assertNotNull($('.content-box'));&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;というテストメソッドを作っておきます。他のxUnitと同じ感じですね。&lt;br /&gt;&lt;br /&gt;でファイルシステムでも良いので「testRunner.html」にアクセスします。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-lC1JVqlu6dI/TpTW2KGOgdI/AAAAAAAAAXo/KJTKIdvTMys/s1600/junit.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 133px;" src="http://1.bp.blogspot.com/-lC1JVqlu6dI/TpTW2KGOgdI/AAAAAAAAAXo/KJTKIdvTMys/s400/junit.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5662386857423307218" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;testRunner.htmlからファイルを指定してRunするとこのようにテスト結果が出力されます。&lt;br /&gt;&lt;br /&gt;これでテストする準備は整った。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;プラグインを入れよう！&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;普段使っている時でもJenkinsのプラグインには様々なものがあります。&lt;br /&gt;ソース管理はほとんどサポートしていますし、CheckStyle等のコードチェッカー等も充実しています。&lt;br /&gt;&lt;br /&gt;今回はGitHub（＋Git）とJSUnit（＋xUnit）のプラグインを入れます。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;ソースを取ってこよう！&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ジョブの設定画面で「ソースコード管理システム」で「Git」を選択します。&lt;br /&gt;そこにGitHubにあるリポジトリを指定しておきます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-p4FI8_GXdSw/TpTwTEB8_GI/AAAAAAAAAYY/go_SwGwXvfo/s1600/git.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 78px;" src="http://3.bp.blogspot.com/-p4FI8_GXdSw/TpTwTEB8_GI/AAAAAAAAAYY/go_SwGwXvfo/s400/git.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5662414841801669730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この時点でビルドすると「ワークスペース」にソースを持ってこれるはずなので&lt;br /&gt;それを確認しておくのが良いでしょう。こんな感じです。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-RNg2QTT2c-g/TpTwjkyTB1I/AAAAAAAAAYk/YlojjJq1OuA/s1600/workspace.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 253px; height: 209px;" src="http://4.bp.blogspot.com/-RNg2QTT2c-g/TpTwjkyTB1I/AAAAAAAAAYk/YlojjJq1OuA/s400/workspace.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5662415125472282450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;ビルドを設定してテストしよう！&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;テストを実行する為、ビルドはAntを呼び出します。&lt;br /&gt;Ant呼び出しを設定して、testをターゲットにしておきます。&lt;br /&gt;Antの実行パス等はJenkins自体の設定で指定できます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-vaO8cOEo5jQ/TpTwF9kim1I/AAAAAAAAAYM/vFdO64xmOz8/s1600/build.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 280px; height: 220px;" src="http://4.bp.blogspot.com/-vaO8cOEo5jQ/TpTwF9kim1I/AAAAAAAAAYM/vFdO64xmOz8/s400/build.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5662414616729394002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ビルドファイルなのですがリポジトリ等に置いてあるAntの設定ファイルを叩きます。&lt;br /&gt;「./{projectName}/test/build.xml」&lt;br /&gt;とかになると思います。&lt;br /&gt;&lt;br /&gt;build.xmlは以下※展開してください。&lt;br /&gt;&lt;pre name="code" class="xml:collapse"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;project name="JSUnitForJenkins" default="test" basedir="."&amp;gt;&lt;br /&gt;  &amp;lt;description&amp;gt;&lt;br /&gt;    Jenkins 上で JSUnit によるユニットテストを行う。&lt;br /&gt;  &amp;lt;/description&amp;gt;&lt;br /&gt;  &amp;lt;property environment="jenkins"/&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- プロジェクトのホームディレクトリ --&amp;gt;&lt;br /&gt;  &amp;lt;property name="home"&lt;br /&gt;            location="${jenkins.WORKSPACE}/drag-designer"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- テスト対象のページ --&amp;gt;&lt;br /&gt;  &amp;lt;property name="testPage"&lt;br /&gt;            location="${home}/test/testSuite.html"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- JSUnit の動作するポート番号 --&amp;gt;&lt;br /&gt;  &amp;lt;property name="jsunitPort"&lt;br /&gt;            value="8090"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- Firefox のパス --&amp;gt;&lt;br /&gt;  &amp;lt;property name="firefox"&lt;br /&gt;            location="/Applications/FireFox.app/Contents/MacOS/firefox"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- JSUnit のホームディレクトリ --&amp;gt;&lt;br /&gt;  &amp;lt;property name="jsunitHome"&lt;br /&gt;            location="${home}/test"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- ログを出力するディレクトリ --&amp;gt;&lt;br /&gt;  &amp;lt;property name="logsDirectory"&lt;br /&gt;            location="${home}/test/logs"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- JSUnit 形式のログファイルを JUnit 形式のログファイルに変換する XSLT --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- TestRunner --&amp;gt;&lt;br /&gt;  &amp;lt;property name="testRunner"&lt;br /&gt;            location="${jsunitHome}/testRunner.html"/&amp;gt;&lt;br /&gt;  &amp;lt;!-- JSUnit Server を起動する build.xml --&amp;gt;&lt;br /&gt;  &amp;lt;property name="buildScript"&lt;br /&gt;            location="${jsunitHome}/server.xml"/&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;target name="test"&amp;gt;&lt;br /&gt;    &amp;lt;mkdir dir="${logsDirectory}"/&amp;gt;&lt;br /&gt;    &amp;lt;delete includeemptydirs="true"&amp;gt;&lt;br /&gt;      &amp;lt;fileset dir="${logsDirectory}" includes="**/*"/&amp;gt;&lt;br /&gt;    &amp;lt;/delete&amp;gt;&lt;br /&gt;    &amp;lt;makeurl file="${testRunner}" property="testRunnerURL"/&amp;gt;&lt;br /&gt;    &amp;lt;ant antfile="${buildScript}" dir="${jsunitHome}" target="standalone_test"&amp;gt;&lt;br /&gt;      &amp;lt;property name="browserFileNames" value="${firefox}"/&amp;gt;&lt;br /&gt;      &amp;lt;property name="port" value="${jsunitPort}"/&amp;gt;&lt;br /&gt;      &amp;lt;property name="logsdirectory" location="${logsDirectory}"/&amp;gt;&lt;br /&gt;      &amp;lt;property name="url" value="${testRunnerURL}?testPage=${testPage}"/&amp;gt;&lt;br /&gt;    &amp;lt;/ant&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;プロジェクトのホームを設定して対応のSuiteのページを設定。&lt;br /&gt;ブラウザを指定、ログ出力(テスト結果)の箇所、TestRunnerの指定、&lt;br /&gt;JSUnitをコピーした際に名前を変更しておいてserver.xmlを指定します。&lt;br /&gt;&lt;br /&gt;この設定でJenkinsはワークスペース上に取ってきたソースを元にJSUnitの実行を行います。&lt;br /&gt;途中Firefoxで実行していますが&lt;br /&gt;これらを増やして、クロスブラウジング等のテストを行うのも可能です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;処理結果をリポートする&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Build後の処理として&lt;br /&gt;「Publish testing tools result report」を選択して&lt;br /&gt;JSUnit-2.2を選択して追加します。&lt;br /&gt;&lt;br /&gt;**{projectName}/test/logs/*.xml&lt;br /&gt;&lt;br /&gt;と、ビルドした際のテスト結果を出力した位置を指定します。これでOKです。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-3tgUfIKLAQo/TpTv1ubzhHI/AAAAAAAAAYA/ydMjnEFUVnA/s1600/jsunitresult.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 326px; height: 123px;" src="http://4.bp.blogspot.com/-3tgUfIKLAQo/TpTv1ubzhHI/AAAAAAAAAYA/ydMjnEFUVnA/s400/jsunitresult.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5662414337788314738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;ジョブ実行&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;これで準備完了ですのでジョブを実行します。&lt;br /&gt;実行時にFirefoxが起動してびっくりしますけど＞＜。&lt;br /&gt;&lt;br /&gt;で結果がこれ。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-QZagO_oaz_c/TpTvlQjujZI/AAAAAAAAAX0/OD9qKpyC760/s1600/result.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 134px;" src="http://2.bp.blogspot.com/-QZagO_oaz_c/TpTvlQjujZI/AAAAAAAAAX0/OD9qKpyC760/s400/result.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5662414054890573202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;テスト自体はしょぼいですけど、できましたー&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;問題&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;・クロスブラウジングのテスト何かもできるなぁ〜と思っていたのですが&lt;br /&gt;　通常動作しているJenkinsサーバはXがないけど動作するのかな？&lt;br /&gt;&lt;br /&gt;・今回Firefox使いましたけど、バージョンアップとかの画面出てしまうと&lt;br /&gt;　テスト自体ストップする状況になってしまうような気がする&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;おまけ&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;・本当はMylynとGitHubをつなげたIssue管理をやろうとしたのですが&lt;br /&gt;　それは後日ブログに書きます。&lt;br /&gt;・私個人としてはCIでパトランプを回すのが目標なのですが&lt;br /&gt;　後日の勉強会でやった事ある方にパトランプを回す所を見せてもらいました！&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=85_sLg_xVmo"&gt;パトランプの動画&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;やってみて、興味を示してくれた方が何人かいらっしゃって&lt;br /&gt;既に実行された方もいるみたいなので、やって良かった！と思いました。&lt;br /&gt;※パトランプの成果が一番大きいかも＞＜。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1836353341233163319?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1836353341233163319/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1836353341233163319' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1836353341233163319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1836353341233163319'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/10/jenkinsjsunit.html' title='Jenkinsを利用したJSUnitの実行'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-lC1JVqlu6dI/TpTW2KGOgdI/AAAAAAAAAXo/KJTKIdvTMys/s72-c/junit.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3964149568909944060</id><published>2011-06-20T22:55:00.009+09:00</published><updated>2011-06-25T20:53:45.727+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ブラウザ三国志'/><category scheme='http://www.blogger.com/atom/ns#' term='ChromeExtension'/><category scheme='http://www.blogger.com/atom/ns#' term='localStorage'/><title type='text'>ブラウザ三国志 経路算出：ChromeExtensionを改良</title><content type='html'>さて前回ダイクストラで最短経路を算出してみました。&lt;br /&gt;このままではもちろんダメで何がダメかというと、&lt;br /&gt;マップ見るたびに経路計算をしてしまうというダメダメな仕様。&lt;br /&gt;&lt;br /&gt;このままでは通常時マップを見る時に計算してしまう。&lt;br /&gt;ただ線引くだけのくせに、、、ｼﾞｬﾏ！ｱﾝｲﾝｽﾄｰﾙ。である。&lt;br /&gt;&lt;br /&gt;なのでGUIを作って(無駄に画面だけあったけど＞＜)&lt;br /&gt;そこでON/OFFできるようにする。せっかくなので座標を貯めこむ。&lt;br /&gt;&lt;br /&gt;で座標を指定して経路を算出！みたいな感じである。&lt;br /&gt;&lt;br /&gt;前回利用したcontent_scriptsとページ間のリソースの共有は基本的にできません。&lt;br /&gt;コンテキストスクリプトは拡張機能というよりWebページに埋め込む。という仕組みである為、&lt;br /&gt;拡張機能とは隔離されているもの。という風にできています。&lt;br /&gt;&lt;br /&gt;そこでbackgroundという仕組みを利用します。manifest.jsonに以下を追加します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;  "background_page": "html/background.html",&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/secondarykey/donchangon/blob/master/manifest.json"&gt;全体はココ&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;で、イベントによる受け渡しをやるわけですが、以下が概要です。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-1H1hBnha-kU/TgXCFbL2GUI/AAAAAAAAANg/s1jNIOI7GP4/s1600/%25E6%25A6%2582%25E8%25A6%2581.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 321px;" src="http://3.bp.blogspot.com/-1H1hBnha-kU/TgXCFbL2GUI/AAAAAAAAANg/s1jNIOI7GP4/s400/%25E6%25A6%2582%25E8%25A6%2581.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5622113108294506818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;こういう風にしたいと思います。&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;font-size:32px;"&gt;座標を保存する&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;まず、content_script により、51x51マップの時に、座標を吸い上げて以下を行います。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt; var map = document.getElementById( "map51-content" );&lt;br /&gt; if ( map == null ) {&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; var pointArray = [];&lt;br /&gt; var mapUlList = map.getElementsByTagName("ul");&lt;br /&gt; for ( var ulIdx = 0; ulIdx &amp;lt; mapUlList.length; ++ulIdx ) {&lt;br /&gt;   var mapLiList = mapUlList[ulIdx].getElementsByTagName("li");&lt;br /&gt;   for ( var liIdx = 0; liIdx &amp;lt; mapUlList.length; ++liIdx ) {&lt;br /&gt;     var linkTag = mapLiList[liIdx].getElementsByTagName("a")[0];&lt;br /&gt;     var point = createPoint(linkTag);&lt;br /&gt;     pointArray.push(point);&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //バックグラウンドで保存する&lt;br /&gt; chrome.extension.sendRequest( { &lt;br /&gt;   action : "save" ,&lt;br /&gt;   args : [pointArray]&lt;br /&gt;  } , function( response )  {&lt;br /&gt;   //戻り値処理&lt;br /&gt;   console.log(response);&lt;br /&gt;  }&lt;br /&gt; );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;以前処理した時と同じように座標オブジェクトをcreatePoint()によって作成しています。&lt;br /&gt;ここで重要なのは、chrome.extension.sendRequest()により、イベントを発生しています。&lt;br /&gt;&lt;br /&gt;これはbackgroundで以下のように処理して、イベントを待機しています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;var CMD = {&lt;br /&gt;    isSaveMode    : isSaveMode ,&lt;br /&gt;    save      : save ,&lt;br /&gt;    analysisDijkstra : analysisDijkstra &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;function init() {&lt;br /&gt;    chrome.extension.onRequest.addListener( function ( message , sender , sendResponse) {&lt;br /&gt;        var retVal = CMD[message.action].apply(this,message.args); &lt;br /&gt;        sendResponse( { values : retVal } );&lt;br /&gt;    } ) ;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;backgroundの処理はブラウザが立ち上がった瞬間に始まりますので&lt;br /&gt;そこでinit()を呼び出してあげます。&lt;br /&gt;CMDはmessageによりメソッド名を送ってそれを実行する為の配列ですね。&lt;br /&gt;自分で判定文を作って、関数を作っても良いのですが、こうしておくと、やりとりが増えても大丈夫です。&lt;br /&gt;&lt;br /&gt;listenerですのでsendRequest()を呼んであげたらここが呼び出されるので&lt;br /&gt;「save」というactionを呼び出してる感じ。argsにはオブジェクトのリストを渡してます。&lt;br /&gt;&lt;br /&gt;ここでオブジェクトに変換せずにそのままHTMLのDOMを送りたい所ですが、&lt;br /&gt;この通信手段にはJSONが使われているみたいで、その引数の変換時にデータ内に改行が存在してしまい、変換に失敗するようです。&lt;br /&gt;&lt;br /&gt;で受け取ったbackgroundはリストにより、座標を保存します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;function save( mapArray ){&lt;br /&gt; for ( var idx = 0; idx &amp;lt; mapArray.length; ++idx ) {&lt;br /&gt;  var point = mapArray[idx];&lt;br /&gt;     localStorage[point.x + ":" + point.y] = JSON.stringify(point);&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;こんな感じですね。&lt;br /&gt;&lt;br /&gt;localStorageは「WebStorage」と呼ばれるHTML5的な新しい技術で拡張機能として専用のサンドボックス内にデータを保存するような仕組みです。&lt;br /&gt;配列と同じようにして保存する事が可能です。&lt;br /&gt;"他のブラウザで、、、"って一瞬思いましたが、冷静に考えればChromeExtensionでした＞＜。&lt;br /&gt;&lt;br /&gt;localStorageには文字列が保存できるので JSON.stringify(point);で文字列にして保存しています。&lt;br /&gt;※使っている場所ではJSON.parse()を実行しています。&lt;br /&gt;&lt;br /&gt;これで座標を保存ができるようになったわけです。&lt;br /&gt;実際にはGUIを利用して、「保存モード」かを判定して処理を行っています。&lt;br /&gt;※それも通信とlocalStorageを利用してから実現しています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;font-size:32px;"&gt;経路の計算を行う&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;これで十分座標は保存できたと考えて、&lt;br /&gt;次は画面操作との兼ね合いです。とは言っても簡単なHTMLですので、そんなに難しい事はしていません。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-KOtZYnV-Puc/TgXIS5FeKvI/AAAAAAAAANo/LlxYnmz41sw/s1600/popup.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 187px;" src="http://1.bp.blogspot.com/-KOtZYnV-Puc/TgXIS5FeKvI/AAAAAAAAANo/LlxYnmz41sw/s400/popup.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5622119936728902386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;こういう画面です。&lt;br /&gt;&lt;a href="https://github.com/secondarykey/donchangon/blob/master/html/popup.html"&gt;ソースはココ&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;※経路表示はまだ実装してないです＞＜&lt;br /&gt;&lt;br /&gt;この画面から経路算出の為に座標をbackgroundに渡して&lt;br /&gt;※座標は保存するようにしたので、引数では渡してませんけど＞＜&lt;br /&gt;そこから経路算出を行っています。そこから戻り値で、経路情報を返しています。&lt;br /&gt;&lt;br /&gt;ソース自体は&lt;a href="https://github.com/secondarykey/donchangon"&gt;github&lt;/a&gt;にすべておきました。&lt;br /&gt;ダイクストラの大部分は変更していませんが、&lt;br /&gt;&lt;br /&gt;・51x51の配列を使わないようにした。&lt;br /&gt;・座標データはlocalStorageにある&lt;br /&gt;&lt;br /&gt;って事で、直接座標データを取って処理しています。&lt;br /&gt;※色々改良する余地はあると思います。&lt;br /&gt;&lt;br /&gt;さて、これでWebページの情報を残して処理をするという基本アーキテクトの変更は可能になったわけです。&lt;br /&gt;次回はbackgroundを利用して、経路表示も行いたいと思います。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3964149568909944060?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3964149568909944060/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3964149568909944060' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3964149568909944060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3964149568909944060'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/chromeextension.html' title='ブラウザ三国志 経路算出：ChromeExtensionを改良'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-1H1hBnha-kU/TgXCFbL2GUI/AAAAAAAAANg/s1jNIOI7GP4/s72-c/%25E6%25A6%2582%25E8%25A6%2581.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8567766434658967174</id><published>2011-06-17T11:27:00.018+09:00</published><updated>2011-06-19T23:01:15.302+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ブラウザ三国志'/><category scheme='http://www.blogger.com/atom/ns#' term='Dijkstra'/><category scheme='http://www.blogger.com/atom/ns#' term='ChromeExtention'/><title type='text'>ブラウザ三国志でダイクストラを行ってみる。</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.3gokushi.jp/"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 230px; height: 180px;" src="http://www.3gokushi.jp/resource/images/index/img_suikyo.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;「ブラウザ三国志」というゲームがあります。&lt;br /&gt;そのゲームでは領地の奪い合い、砦攻略を目指して軍を進めていきます。&lt;br /&gt;基本ゲームはしませんが、「ソーシャルゲーム」という分野においての勉強としてずっと続けています。いやバランス良くて本当に面白い。。。ってそんな事やってる場合じゃない＞＜&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ChromeExtentionの仕組みみたいな部分での調査が大きいので「処理速度」や汚さは勘弁してください。あくまでそんな事できるんだ。程度でお読みください。&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;text-size:32px"&gt;思い立ち&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;さてブラウザ三国志で砦攻略で重要になってくるのが、座標計算です。&lt;br /&gt;次の砦に向かうという時に領地レベル☆１をめがけて経路を作ってつなげていきます。&lt;br /&gt;自分１人でやっていくのはいいのですが、「同盟」を組んで同盟員とつなげていくと&lt;br /&gt;&lt;br /&gt;「今度ここー」&lt;br /&gt;「次私ここー」&lt;br /&gt;&lt;br /&gt;みたいな事が起こってきます。&lt;br /&gt;それを掲示板等で共有して進んでいくわけです。ソーシャルですねぇー。&lt;br /&gt;&lt;br /&gt;で「ここ」って決めてく経路があるのです。&lt;br /&gt;で、既にツール等もあるのですが、せっかくだから自分で作ってみよー！って思ったわけです。&lt;br /&gt;ひとまずChromeExtensionで行きます。&lt;br /&gt;&lt;br /&gt;今回は簡単に「51x51マップ」内で指定した座標間を結ぶ。をやってみましょう。&lt;br /&gt;&lt;br /&gt;動きとしては&lt;br /&gt;・51x51マップ時のみに動作する&lt;br /&gt;　・座標を取得してくる&lt;br /&gt;　・ダイクストラで経路を算出する&lt;br /&gt;　・算出した経路をHTML表示する&lt;br /&gt;&lt;br /&gt;って流れですかね。&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;text-size:32px"&gt;Chrome Extentionを作成してみよう！&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;さて、まずはボタンを表示してみましょう。&lt;br /&gt;&lt;a href="http://blog.smartnetwork.co.jp/staff/node/44"&gt;ここ&lt;/a&gt;を元に構成を勉強して、、、とひとまずHTMLを書けました。&lt;br /&gt;&lt;br /&gt;こんな感じ。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-krbppRKnpsY/TfrbLJp1w5I/AAAAAAAAAM0/HSwN86ohuKg/s1600/extention.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 368px; height: 155px;" src="http://2.bp.blogspot.com/-krbppRKnpsY/TfrbLJp1w5I/AAAAAAAAAM0/HSwN86ohuKg/s400/extention.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619044469714568082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-JgmUOcfk5UQ/TfrbTDhYZqI/AAAAAAAAAM8/tgeHuVkxtj0/s1600/icon.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 60px; height: 44px;" src="http://1.bp.blogspot.com/-JgmUOcfk5UQ/TfrbTDhYZqI/AAAAAAAAAM8/tgeHuVkxtj0/s400/icon.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619044605507430050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ブラ三おなじみのアイコンで、&lt;br /&gt;アイコンをクリックするとHTMLを出力してくれるようになりました。&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;text-size:32px"&gt;座標データを収集&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;さて、このツールは何につけても座標データが存在しないといけません。&lt;br /&gt;&lt;br /&gt;って事で&lt;br /&gt;・HTMLのデータを取得&lt;br /&gt;・そこから座標データを抜き出す！&lt;br /&gt;という流れを説明します。&lt;br /&gt;&lt;br /&gt;まず51x51マップか、、、という判定。&lt;br /&gt;既存のページ(対象のHTML)の要素を取得するには先ほどのページで使った&lt;br /&gt;「browser_action」とは別に「content_scripts」という仕組みを使用する方法があります。&lt;br /&gt;&lt;br /&gt;以下をmanifest.jsonに追記します。&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;  "content_scripts": [&lt;br /&gt;    {&lt;br /&gt;      "matches": [&lt;br /&gt;        "http://m21.3gokushi.jp/big_map.php*"&lt;br /&gt;      ],&lt;br /&gt;&lt;br /&gt;      "js" : [&lt;br /&gt;        "script.js"&lt;br /&gt;      ],&lt;br /&gt;&lt;br /&gt;      "run_at": "document_end",&lt;br /&gt;      "all_frames": true&lt;br /&gt;  ]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;※要素のつなぎは「,」を忘れずに。&lt;br /&gt;&lt;br /&gt;という風に記述します。&lt;br /&gt;matchesはそのページに来たら。jsは使用するJavaScript、run_atはどのタイミングで動作するか？です。&lt;br /&gt;all_frameはすべてのフレームに対して処理を行うか？を記述します。&lt;br /&gt;&lt;br /&gt;manifest.jsonは更新したら再読込の必要あります。&lt;br /&gt;これらを思い通りに動かせる(読み込み失敗とかがない)ようになるまでは&lt;br /&gt;Googleのトップページで練習した方が良いかもです。&lt;br /&gt;&lt;br /&gt;ブラウザ三国志(mixi)ですが難しいのはページの構成ですね。&lt;br /&gt;URLはもちろんmixiを指しますが、アプリ自体は&lt;br /&gt;「"http://m21.3gokushi.jp/big_map.php*"」にアクセスしています。&lt;br /&gt;なので、それをマッチに入れて、Frameをtrueにしているわけです。&lt;br /&gt;&lt;br /&gt;ここまでで、ひとまず「全体地図」のクリックで動作するか確認しておくべきでしょう。&lt;br /&gt;&lt;br /&gt;そこまでできたらアプリケーションが使用しているHTMLをハックします。&lt;br /&gt;そうすれば&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-rQs-incOUYE/TfsJ_aFtrlI/AAAAAAAAANI/SMnpCUxajqk/s1600/map51.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 215px; height: 54px;" src="http://4.bp.blogspot.com/-rQs-incOUYE/TfsJ_aFtrlI/AAAAAAAAANI/SMnpCUxajqk/s400/map51.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619095945014521426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;というコードが存在するので、このデータを&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;var map51 = document.getElementById( "map51-wrapper" );&lt;br /&gt;if ( map51 == null ) {&lt;br /&gt;  return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;という感じでデータを取得してきます。&lt;br /&gt;その中に&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;a &lt;br /&gt;href=​"/​land.php?x=-22&amp;y=-52#ptop" &lt;br /&gt;onmouseover=​"return gloss('&lt;br /&gt;&lt;br /&gt;&amp;lt;​dl class="​bigmap"​&amp;gt;&lt;br /&gt;​&amp;lt;​dt class="​bigmap-caption"​&amp;gt;​空き地&amp;lt;​/​dt&amp;gt;&lt;br /&gt;​&amp;lt;​dd class="​bigmap-subcap"​&amp;gt;​&amp;​nbsp;​&amp;lt;​/​dd&amp;gt;&lt;br /&gt;​&amp;lt;​dt&amp;gt;​座標&amp;​nbsp;​/​&amp;​nbsp;​距離&amp;lt;​/​dt&amp;gt;​&lt;br /&gt;&amp;lt;​dd&amp;gt;​(-22,-52)​&amp;​nbsp;​/​&amp;​nbsp;​[35.36]​&amp;lt;​/​dd&amp;gt;​&lt;br /&gt;&amp;lt;​dt&amp;gt;​戦力&amp;lt;​/​dt&amp;gt;&lt;br /&gt;​&amp;lt;​dd&amp;gt;​★&amp;lt;​/​dd&amp;gt;​&lt;br /&gt;&amp;lt;​dt class="​bottom-popup-l"​&amp;gt;​資源&amp;lt;​/​dt&amp;gt;&lt;br /&gt;​&amp;lt;​dd class="​bottom-popup-r"​&amp;gt;​木1&amp;​nbsp;​岩0&amp;​nbsp;​鉄0&amp;​nbsp;​糧0&amp;lt;​/​dd&amp;gt;​&amp;lt;​/​dl&amp;gt;​'&lt;br /&gt;&lt;br /&gt;)​;​" onmouseout=​"nd()​;​"&amp;gt;​&lt;br /&gt;1​&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;というデータがありますので取得します。&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;// ULタグを取得&lt;br /&gt;var mapUlList = map51.getElementsByTagName("ul");&lt;br /&gt;for ( var ulIdx = 0; ulIdx &lt; mapUlList.length; ++ulIdx ) {&lt;br /&gt;  // 内部のLiタグを取得&lt;br /&gt;  var mapLiList = mapUlList[ulIdx].getElementsByTagName("li");&lt;br /&gt;  for ( var liIdx = 0; liIdx &lt; mapUlList.length; ++liIdx ) {&lt;br /&gt;    // Aタグを取得&lt;br /&gt;    var linkTag = mapLiList[liIdx].getElementsByTagName("a")[0];&lt;br /&gt;    dijkstra.pointArray[ulIdx][liIdx] = createPoint(linkTag);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;createPoint(linkTag)で座標データを解析しています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js:collapse"&gt;&lt;br /&gt;var createPoint = function ( linkTag ) {&lt;br /&gt;&lt;br /&gt;  var point = {};&lt;br /&gt;  point.x    = 0;&lt;br /&gt;  point.y    = 0;&lt;br /&gt;  point.team = "";&lt;br /&gt;  point.lv   = 0;&lt;br /&gt;&lt;br /&gt;  var lv  = replaceAll(linkTag.innerHTML,"\n","");&lt;br /&gt;  if ( lv != "1" &amp;&amp; lv != "2" &amp;&amp; lv != "3" &amp;&amp; lv != "4" &amp;&amp; lv != "5" ) {&lt;br /&gt;    return point;&lt;br /&gt;  }&lt;br /&gt;  point.lv = parseFloat(lv);&lt;br /&gt;  if ( point.lv != 1 ) {&lt;br /&gt;   point.lv = parseFloat(lv) *  parseFloat(lv);&lt;br /&gt;  }&lt;br /&gt;  // 文字列に変換&lt;br /&gt;  var text = linkTag.outerHTML;&lt;br /&gt;&lt;br /&gt;  // リンクタグの解析&lt;br /&gt;  var firstIdx = text.indexOf("'");&lt;br /&gt;  var lastIdx  = text.lastIndexOf("'"); &lt;br /&gt;  var data = text.slice(firstIdx+1,lastIdx);&lt;br /&gt;&lt;br /&gt;  data = replaceAll(data,"&amp;lt;","&amp;lt;");&lt;br /&gt;  data = replaceAll(data,"&amp;gt;","&amp;gt;");&lt;br /&gt;  data = replaceAll(data,"&amp;quot;","'");&lt;br /&gt;  data = replaceAll(data,"&amp;amp;","&amp;");&lt;br /&gt;  data = replaceAll(data,"&amp;n"," ");&lt;br /&gt;  data = replaceAll(data," bsp;"," ");&lt;br /&gt;&lt;br /&gt;  var dp = new DOMParser();&lt;br /&gt;  var doc = dp.parseFromString(data, "text/xml");&lt;br /&gt;&lt;br /&gt;  var dtTags = doc.getElementsByTagName("dt");&lt;br /&gt;  var ddTags = doc.getElementsByTagName("dd");&lt;br /&gt;&lt;br /&gt;  // タグ数回繰り返す&lt;br /&gt;  for ( var idx = 0; idx &amp;lt; dtTags.length; ++idx ) {&lt;br /&gt;&lt;br /&gt;    var dtTag = dtTags[idx];&lt;br /&gt;    var tagVal = dtTag.firstChild.data;&lt;br /&gt;&lt;br /&gt;    if ( tagVal == "君主名" ) {&lt;br /&gt;      point.team = ddTags[idx].firstChild.data;&lt;br /&gt;    } else if ( tagVal == "座標 / 距離") {&lt;br /&gt;      var tagData = ddTags[idx].firstChild.data;&lt;br /&gt;      var startP = tagData.indexOf("(");&lt;br /&gt;      var endP   = tagData.lastIndexOf(")"); &lt;br /&gt;      var pointData = tagData.slice(startP+1,endP);&lt;br /&gt;      var pointArray = pointData.split(",");&lt;br /&gt;      point.x = pointArray[0];&lt;br /&gt;      point.y = pointArray[1];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return point;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;相手が存在する場合等もありますから、&lt;br /&gt;x,y,同盟名,lv(領地の強さ)を設定したpointオブジェクトを貯めこんでおきます。&lt;br /&gt;パーサを使用していますが、大きなマップ等になったら変更する予定ではあります。&lt;br /&gt;※51x51ではそんなに重くなかった。&lt;br /&gt;&lt;br /&gt;。。。さぁこれで座標データの抜き出しはOKです。&lt;br /&gt;ダイクストラを行ってみましょう！&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;text-size:32px"&gt;ダイクストラで最短経路を算出&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;さて座標データはすべて取得できたので、そのデータから最短経路を算出してみましょう。&lt;br /&gt;実際のソースを貼っておきます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js:collapse"&gt;&lt;br /&gt;&lt;br /&gt;//Map51x51かを確認&lt;br /&gt;var map51 = document.getElementById( "map51-content" );&lt;br /&gt;if ( map51 == null ) {&lt;br /&gt;  return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var MAX_X = 51;&lt;br /&gt;var MAX_Y = 51;&lt;br /&gt;&lt;br /&gt;// ダイクストラのロジック&lt;br /&gt;var dijkstra = {};&lt;br /&gt;&lt;br /&gt;// 座標データ&lt;br /&gt;dijkstra.pointArray = new Array(MAX_X);&lt;br /&gt;for ( var idx = 0; idx &amp;lt; dijkstra.pointArray.length; ++idx ) {&lt;br /&gt;  dijkstra.pointArray[idx] = new Array(MAX_Y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// 経路算出&lt;br /&gt;dijkstra.getRoute = function(startX,startY,endX,endY){&lt;br /&gt;&lt;br /&gt;  // その座標まで行くルート&lt;br /&gt;  var workRouteArray = new Array(MAX_X);&lt;br /&gt;  // 決定している距離&lt;br /&gt;  var pointArray = new Array(MAX_X);&lt;br /&gt;  // すべての配列を初期化&lt;br /&gt;  for ( var xidx = 0; xidx &amp;lt; workRouteArray.length; ++xidx ) {&lt;br /&gt;    workRouteArray[xidx] = new Array(MAX_Y);&lt;br /&gt;    pointArray[xidx] = new Array(MAX_Y);&lt;br /&gt;    for ( var yidx = 0; yidx &amp;lt; pointArray[xidx].length; ++yidx ) {&lt;br /&gt;      workRouteArray[xidx][yidx] = null;&lt;br /&gt;      pointArray[xidx][yidx] = Number.POSITIVE_INFINITY;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // 作業する座標&lt;br /&gt;  var workPointArray = new Array();&lt;br /&gt;&lt;br /&gt;  // 始点オブジェクト&lt;br /&gt;  var nowPoint = dijkstra.pointArray[startX][startY];&lt;br /&gt;  var nowX = startX;&lt;br /&gt;  var nowY = startY;&lt;br /&gt;  var nowLen = 0;&lt;br /&gt;&lt;br /&gt;  // 作業用のリストを取得する&lt;br /&gt;  workRouteArray[nowX][nowY] = new Array();&lt;br /&gt;  var nowRoute;&lt;br /&gt;&lt;br /&gt;  while ( true ) {&lt;br /&gt;&lt;br /&gt; pointArray[nowX][nowY] = nowLen;&lt;br /&gt; nowRoute = workRouteArray[nowX][nowY];&lt;br /&gt;&lt;br /&gt;    // 近隣の座標を算出&lt;br /&gt;    for ( var addX = -1; addX &amp;lt;= 1; ++addX ) {&lt;br /&gt;&lt;br /&gt;      var wkX = nowX + addX;&lt;br /&gt;      if ( wkX &amp;lt; 0 ) continue;&lt;br /&gt;      if ( wkX &amp;gt;= MAX_X ) continue;&lt;br /&gt;     &lt;br /&gt;      // 周りを見渡す&lt;br /&gt;      for ( var addY = -1; addY &amp;lt;= 1; ++addY ) {&lt;br /&gt;       &lt;br /&gt;        var wkY = nowY + addY;&lt;br /&gt;        if ( wkY &amp;lt; 0 ) continue;&lt;br /&gt;        if ( wkY &amp;gt;= MAX_Y ) continue;&lt;br /&gt;&lt;br /&gt;        // 既に決定済の場合&lt;br /&gt;        if ( pointArray[wkX][wkY] != Number.POSITIVE_INFINITY ) {&lt;br /&gt;          continue;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // その座標のルートを取得&lt;br /&gt;        var workRoute = workRouteArray[wkX][wkY];&lt;br /&gt;        // そこに行っていいのか？&lt;br /&gt;        if ( workRoute === undefined ) {&lt;br /&gt;          continue;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // 作業中の場所を取得&lt;br /&gt;        var point = dijkstra.pointArray[wkX][wkY];&lt;br /&gt;&lt;br /&gt;        //既に存在した場合&lt;br /&gt;        if ( workRoute != null ) {&lt;br /&gt;         var workLen = workRoute.length;&lt;br /&gt;         var nowRouteLen  = nowRoute.length;&lt;br /&gt;         //作業用のリストが短い場合&lt;br /&gt;         if ( (workLen - 1) &amp;lt;= nowRouteLen ) {&lt;br /&gt;          continue;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         var workLv = 0;&lt;br /&gt;         //TODO レベル加算を見る必要あり&lt;br /&gt;         for ( var idx = 0; idx &amp;lt; workLen; ++idx ) {&lt;br /&gt;          var point = workRoute[idx];&lt;br /&gt;          var lv = parseFloat(point.lv);&lt;br /&gt;          workLv = workLv + lv;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         if ( (nowLen + parseFloat(point.lv)) &amp;gt; workLv  ) {&lt;br /&gt;          continue;&lt;br /&gt;         }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // 行けない場所だった場合&lt;br /&gt;        if ( point.lv == "0" ) {&lt;br /&gt;          // 行っちゃダメにする&lt;br /&gt;          workRouteArray[wkX][wkY] = undefined;&lt;br /&gt;          continue;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var newRoute = new Array();&lt;br /&gt;        for (var i=0, l= nowRoute.length; i&amp;lt;l; i++) {&lt;br /&gt;            newRoute[i] = nowRoute[i];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //その地点を設定&lt;br /&gt;        newRoute.push(point);&lt;br /&gt;        // 作業用のルートを作成&lt;br /&gt;        workRouteArray[wkX][wkY] = newRoute;&lt;br /&gt;&lt;br /&gt;        // 作業の配列に座標を指定&lt;br /&gt;        var workPoint = {};&lt;br /&gt;        workPoint.x = wkX;&lt;br /&gt;        workPoint.y = wkY;&lt;br /&gt;&lt;br /&gt;        workPointArray.push(workPoint);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //console.log(workPointArray.length);&lt;br /&gt;    //for ( var cnt = 0; cnt &amp;lt; workPointArray.length; ++cnt ) {&lt;br /&gt;     //console.log("作業リスト" + workPointArray[cnt].x + ":" + workPointArray[cnt].y);&lt;br /&gt;    //}&lt;br /&gt;&lt;br /&gt;    var minLen = Number.POSITIVE_INFINITY;&lt;br /&gt;    var deleteIdx = 0;&lt;br /&gt;&lt;br /&gt;    // 作業リスト数回繰り返す&lt;br /&gt;    for ( var cnt = 0; cnt &amp;lt; workPointArray.length; ++cnt ) {&lt;br /&gt;     &lt;br /&gt;     var workPoint = workPointArray[cnt];&lt;br /&gt;        var wkX = workPoint.x;&lt;br /&gt;        var wkY = workPoint.y;&lt;br /&gt;  &lt;br /&gt;     var workRoute = workRouteArray[wkX][wkY];&lt;br /&gt;     var wkLen = 0;&lt;br /&gt;&lt;br /&gt;     for ( var idx = 0; idx &amp;lt; workRoute.length; ++idx ) {&lt;br /&gt;      var point = workRoute[idx];&lt;br /&gt;      var lv = parseFloat(point.lv);&lt;br /&gt;      wkLen = wkLen + lv;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     // 設定できた場合&lt;br /&gt;     if ( minLen == Number.POSITIVE_INFINITY || wkLen &amp;lt; minLen ) {&lt;br /&gt;      minLen = wkLen;&lt;br /&gt;&lt;br /&gt;      nowX = wkX;&lt;br /&gt;      nowY = wkY;&lt;br /&gt;      nowLen = wkLen;&lt;br /&gt;      deleteIdx = cnt;&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    // 行く所がない場合&lt;br /&gt;    if ( minLen == Number.POSITIVE_INFINITY ) {&lt;br /&gt;      break;&lt;br /&gt;    }&lt;br /&gt;    workPointArray.splice(deleteIdx, 1);&lt;br /&gt;    &lt;br /&gt;    // 現在の点を編集&lt;br /&gt;    nowPoint = this.pointArray[nowX][nowY];&lt;br /&gt; //console.log("[" + nowPoint.x + "," + nowPoint.y + "]" + nowPoint.lv );&lt;br /&gt;    // 終点と同一点だった場合&lt;br /&gt;    if ( nowX == endX &amp;&amp; nowY == endY ) {&lt;br /&gt;      // 作業ルートから取得&lt;br /&gt;      return workRouteArray[endX][endY];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // 決まらなかった場合&lt;br /&gt;  return null;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var nbsp = String.fromCharCode( 160 );&lt;br /&gt;// 全ての文字列 s1 を s2 に置き換える&lt;br /&gt;function replaceAll(expression, org, dest){  &lt;br /&gt;    return expression.split(org).join(dest);  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;var createPoint = function ( linkTag ) {&lt;br /&gt;&lt;br /&gt;  var point = {};&lt;br /&gt;  point.x    = 0;&lt;br /&gt;  point.y    = 0;&lt;br /&gt;  point.team = "";&lt;br /&gt;  point.lv   = 0;&lt;br /&gt;&lt;br /&gt;  var lv  = replaceAll(linkTag.innerHTML,"\n","");&lt;br /&gt;  if ( lv != "1" &amp;&amp; lv != "2" &amp;&amp; lv != "3" &amp;&amp; lv != "4" &amp;&amp; lv != "5" ) {&lt;br /&gt;    return point;&lt;br /&gt;  }&lt;br /&gt;  point.lv = parseFloat(lv);&lt;br /&gt;  if ( point.lv != 1 ) {&lt;br /&gt;   point.lv = parseFloat(lv) *  parseFloat(lv);&lt;br /&gt;  }&lt;br /&gt;  // 文字列に変換&lt;br /&gt;  var text = linkTag.outerHTML;&lt;br /&gt;&lt;br /&gt;  // リンクタグの解析&lt;br /&gt;  var firstIdx = text.indexOf("'");&lt;br /&gt;  var lastIdx  = text.lastIndexOf("'"); &lt;br /&gt;  var data = text.slice(firstIdx+1,lastIdx);&lt;br /&gt;&lt;br /&gt;  data = replaceAll(data,"&amp;lt;","&amp;lt;");&lt;br /&gt;  data = replaceAll(data,"&amp;gt;","&amp;gt;");&lt;br /&gt;  data = replaceAll(data,"&amp;quot;","'");&lt;br /&gt;  data = replaceAll(data,"&amp;amp;","&amp;");&lt;br /&gt;  data = replaceAll(data,"&amp;n"," ");&lt;br /&gt;  data = replaceAll(data," bsp;"," ");&lt;br /&gt;&lt;br /&gt;  var dp = new DOMParser();&lt;br /&gt;  var doc = dp.parseFromString(data, "text/xml");&lt;br /&gt;&lt;br /&gt;  var dtTags = doc.getElementsByTagName("dt");&lt;br /&gt;  var ddTags = doc.getElementsByTagName("dd");&lt;br /&gt;&lt;br /&gt;  // タグ数回繰り返す&lt;br /&gt;  for ( var idx = 0; idx &amp;lt; dtTags.length; ++idx ) {&lt;br /&gt;&lt;br /&gt;    var dtTag = dtTags[idx];&lt;br /&gt;    var tagVal = dtTag.firstChild.data;&lt;br /&gt;&lt;br /&gt;    if ( tagVal == "君主名" ) {&lt;br /&gt;      point.team = ddTags[idx].firstChild.data;&lt;br /&gt;    } else if ( tagVal == "座標 / 距離") {&lt;br /&gt;      var tagData = ddTags[idx].firstChild.data;&lt;br /&gt;      var startP = tagData.indexOf("(");&lt;br /&gt;      var endP   = tagData.lastIndexOf(")"); &lt;br /&gt;      var pointData = tagData.slice(startP+1,endP);&lt;br /&gt;      var pointArray = pointData.split(",");&lt;br /&gt;      point.x = pointArray[0];&lt;br /&gt;      point.y = pointArray[1];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return point;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;console.log("start");&lt;br /&gt;// ULタグを取得&lt;br /&gt;var mapUlList = map51.getElementsByTagName("ul");&lt;br /&gt;for ( var ulIdx = 0; ulIdx &amp;lt; mapUlList.length; ++ulIdx ) {&lt;br /&gt;  // 内部のLiタグを取得&lt;br /&gt;  var mapLiList = mapUlList[ulIdx].getElementsByTagName("li");&lt;br /&gt;  for ( var liIdx = 0; liIdx &amp;lt; mapUlList.length; ++liIdx ) {&lt;br /&gt;    // Aタグを取得&lt;br /&gt;    var linkTag = mapLiList[liIdx].getElementsByTagName("a")[0];&lt;br /&gt;    dijkstra.pointArray[ulIdx][liIdx] = createPoint(linkTag);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;console.log("getRoute()");&lt;br /&gt;var route;&lt;br /&gt;route = dijkstra.getRoute(0,0,50,50);&lt;br /&gt;if ( route != null ) {&lt;br /&gt; console.log("route log:" + route.length);&lt;br /&gt; for ( var idx = 0; idx &amp;lt; route.length; ++idx ) {&lt;br /&gt;  var point = route[idx];&lt;br /&gt;  console.log("[" + point.x + "," + point.y + "]" + point.lv );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;console.log("end");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;このコードでは0,0 - 51,51を算出するわけですが、あくまで動作確認ように行なっているだけです。&lt;br /&gt;実際には、始点座標から終点座標を入力するのが良いですね。&lt;br /&gt;&lt;br /&gt;実際のコードのcreatePoint()はLvに対してべき乗の重みを付けています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="text-decoration: underline;text-size:32px"&gt;画面に表示してみよう&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;さて、座標は判定できたのでそのままHTMLに表示していきます。&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;route = dijkstra.getRoute(0,0,50,50);&lt;br /&gt;var pointArray = new Array();&lt;br /&gt;&lt;br /&gt;//経路のリストを連想配列に入れる&lt;br /&gt;for ( var idx = 0; idx &amp;lt; route.length; ++idx ) {&lt;br /&gt; var point = route[idx];&lt;br /&gt; pointArray[point.arrayX + "," + point.arrayY] = point;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;for ( var ulIdx = 0; ulIdx &amp;lt; mapUlList.length; ++ulIdx ) {&lt;br /&gt;  // 内部のLiタグを取得&lt;br /&gt;  var mapLiList = mapUlList[ulIdx].getElementsByTagName("li");&lt;br /&gt;  for ( var liIdx = 0; liIdx &amp;lt; mapUlList.length; ++liIdx ) {&lt;br /&gt;  &lt;br /&gt;   var idx = pointArray[ulIdx + "," + liIdx];&lt;br /&gt;   if ( idx === undefined ) {&lt;br /&gt;    continue;&lt;br /&gt;   }&lt;br /&gt;   // Aタグを取得&lt;br /&gt;   var liTag = mapLiList[liIdx];&lt;br /&gt;   liTag.style.backgroundColor = "#555555";&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;配列のポイントがあった方が処理しやすかったので&lt;br /&gt;routeのオブジェクトにarrayX,arrayYを設定しています。&lt;br /&gt;&lt;br /&gt;あとはULとLI回回して背景を変更するって感じです。&lt;br /&gt;で出来上がったマップが以下の通り。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-3X0AYcGuV1k/Tf2xRW9FY4I/AAAAAAAAANQ/WLajiOLXS8U/s1600/map.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 400px;" src="http://2.bp.blogspot.com/-3X0AYcGuV1k/Tf2xRW9FY4I/AAAAAAAAANQ/WLajiOLXS8U/s400/map.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619842821805925250" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;コードにより☆５までしか判定してないので最終地点に拠点等が存在すると&lt;br /&gt;経路算出でエラーになります。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.smartnetwork.co.jp/staff/node/44"&gt;ここ&lt;/a&gt;に載っているように世界にすぐ配信できます。&lt;br /&gt;権利関係微妙ですが他のツール等に比べるとおとなしいので&lt;a href="https://chrome.google.com/webstore/detail/opeonlaalionidmmdkjlmchiiiopeadf"&gt;公開しておきました&lt;/a&gt;&lt;br /&gt;誰かアイコン作って！（128x128pngしか受け付けない＞＜）&lt;br /&gt;&lt;br /&gt;仕事中に呆けて遊んでいたのでやっとアウトプットできた感じ＞＜&lt;br /&gt;&lt;br /&gt;今回のマップのダイクストラでの醍醐味は&lt;br /&gt;重さが領地のレベルである事。☆２を進んだ時に遠征だときついだとか&lt;br /&gt;その辺を考慮して重さを設定するところですね。&lt;br /&gt;&lt;br /&gt;このソースを利用してマップをDBに貯めこんで計算してとかやれば大規模な遠征の道順等も教えてくれるはずです。&lt;br /&gt;これをつくりはじめた時に、AppEngineを利用して&lt;br /&gt;座標を全ユーザから送信してもらって、それで地図を更新して行くという仕様を考えましたけど&lt;br /&gt;本気で行くと有料レベルになると思って止めました。&lt;br /&gt;※お金発生してもOKですけど、お金取る(CM)とか入れると厄介かなぁと。。。&lt;br /&gt;&lt;br /&gt;今回はゲーム周りでしたが、Tweetボタンやいいねボタンがないようなページを&lt;br /&gt;簡単に共有したり、その他他人のWebページに１つエッセンスを加えて処理をやりやすくしたり、&lt;br /&gt;Webのマクロみたいなイメージで処理する事が可能になります。&lt;br /&gt;&lt;br /&gt;ChromeExtentionはChromeOSの登場によって&lt;br /&gt;ChromeOS上で動作するアプリケーションを作れる事になります。&lt;br /&gt;ChromeOSがどの程度市場を席巻するかは不明ですが、１つのアプリの公開形態としては&lt;br /&gt;注視しておいても良いでしょう。&lt;br /&gt;&lt;br /&gt;さぁ同盟員に書簡して使ってもらおう！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8567766434658967174?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8567766434658967174/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8567766434658967174' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8567766434658967174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8567766434658967174'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/blog-post.html' title='ブラウザ三国志でダイクストラを行ってみる。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-krbppRKnpsY/TfrbLJp1w5I/AAAAAAAAAM0/HSwN86ohuKg/s72-c/extention.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4579188641783870630</id><published>2011-06-13T20:06:00.005+09:00</published><updated>2011-06-15T00:19:53.110+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>Canvasで絵を書いてみる</title><content type='html'>さて、メモを操作するようなアプリを考えていて&lt;br /&gt;初めはHTMLでゴリゴリと思っていたんですけど、&lt;br /&gt;四角を書いてそれを線で結びたかったのでCanvasを使って絵を書こうと思いました。&lt;br /&gt;JavaScript部分にはjQueryを使います。&lt;br /&gt;&lt;br /&gt;まずはHTML上にCanvasを宣言します。&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;  &amp;lt;body id="body"&amp;gt;&lt;br /&gt;    &amp;lt;canvas id="canvas"&amp;gt;&amp;lt;/canvas&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Canvasを一杯使いたいのでCanvasの要素を取得してきて&lt;br /&gt;それをbodyタグと同じ大きさにします。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;  var $cvm = $('#canvas');&lt;br /&gt;  var width = $(document.body).width();&lt;br /&gt;  var height = $(document.body).height();&lt;br /&gt;  $cvm.attr("width", width);&lt;br /&gt;  $cvm.attr("height", height);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ウィンドウのサイズ変更されたら、、、って考えなきゃだめですね。&lt;br /&gt;TODOにしとこう！&lt;br /&gt;&lt;br /&gt;でキャンバスの基本設定&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;  var ctx = $cvm[0].getContext('2d');&lt;br /&gt;  ctx.lineWidth = 1;&lt;br /&gt;  ctx.globalAlpha = 0.7;&lt;br /&gt;  ctx.globalCompositeOperation = "source-over";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;getElementById() から取得してgetContext("2d")でもできるのですが&lt;br /&gt;せっかくjQueryを使用しているのでjQueryのオブジェクトから取得。&lt;br /&gt;&lt;br /&gt;lineWidthは線の太さ、globalAlhaは透明度ですね。&lt;br /&gt;globalAlhaを設定した場合、globalCompositeOperationを設定します。&lt;br /&gt;&lt;br /&gt;このglobalCompositeOperationってのは&lt;br /&gt;&lt;a href="http://www.html5.jp/canvas/ref/property/globalCompositeOperation.html"&gt;ココ&lt;/a&gt;が分かりやすいです。&lt;br /&gt;文章よりサンプルがわかりやすいかも。&lt;br /&gt;&lt;br /&gt;さて四角を書くのですが、それに対してテキストを入れてみます。&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;ctx.font =textHeight + 'px "ヒラギノ角ゴ　Ｐｒｏ"';&lt;br /&gt;// 表示するテキストの幅を取得する&lt;br /&gt;var textWidth = ctx.measureText(item.text).width;&lt;br /&gt;//Itemの幅を設定する&lt;br /&gt;item.width = textWidth;&lt;br /&gt;// テキストの背景を描画&lt;br /&gt;ctx.fillStyle = "white";&lt;br /&gt;ctx.fillRect(item.x, item.y, item.width,textHeight);&lt;br /&gt;&lt;br /&gt;//テキストを描画&lt;br /&gt;ctx.textBaseline = "bottom";&lt;br /&gt;ctx.fillStyle = "black";&lt;br /&gt;ctx.fillText(item.text, item.x, item.y + textHeight);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まずContextのfontに対して文字列の大きさ(高さの数値で変数化してます)を設定しています。&lt;br /&gt;その後、テキストの横幅を測っています。ContextのmeasureTextで測ってます。&lt;br /&gt;item.widthというものに残していますがitemはテキストのオブジェクト(描画位置とか持ってる)を&lt;br /&gt;再描画用に持っているので、それに残してるってだけです。(矩形描画時に使ってます)&lt;br /&gt;色をfillStyleで設定してfillRect()で矩形を描画します。&lt;br /&gt;&lt;br /&gt;その後、textBaselineでテキストの位置を設定してfillStyleで文字の色を設定して&lt;br /&gt;fillText()で描画を行います。これで矩形内に文字列を埋め込みます。&lt;br /&gt;&lt;br /&gt;で要素間を結合したいので、その座標に関して線を引きます。&lt;br /&gt;今回は「ベジエ曲線」という線を使って要素を結合したいと思います。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt; ctx.beginPath();&lt;br /&gt; var point = new bezierPoint(preItem,item);&lt;br /&gt; ctx.moveTo(point.x1,point.y1);&lt;br /&gt; ctx.bezierCurveTo(point.x2,point.y1,point.x1,point.y2,point.x2,point.y2);&lt;br /&gt; ctx.strokeStyle="#440000";&lt;br /&gt; ctx.stroke();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まずbeginPath()を呼びます。&lt;br /&gt;これは線を描画する際に「さぁ始めるぞ！」っていう事を意味します。&lt;br /&gt;その後、bezirePoint()を呼んでいますが、これは独自処理で線を引くための座標を算出しています。&lt;br /&gt;それで取得してきたpoint(独自のオブジェクト)を元にmoveTo()によって開始点を設定します。&lt;br /&gt;そこからbezierCurveTo()を利用して、終点を設定します。&lt;br /&gt;６個引数がありますが、４つ目までは曲線の付加情報ですね。(もうちょっと凝る予定ですけど)&lt;br /&gt;で５，６の引数が曲線の終点になります。&lt;br /&gt;でstorokeStyleで色を決定し、stroke()で線を描画します。&lt;br /&gt;&lt;br /&gt;これをやると&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-i2kkeeAEgRI/TfYXg24N-iI/AAAAAAAAAMs/7b5YEKYgNjM/s1600/canvas.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 118px;" src="http://1.bp.blogspot.com/-i2kkeeAEgRI/TfYXg24N-iI/AAAAAAAAAMs/7b5YEKYgNjM/s400/canvas.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5617703438445836834" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;こんな感じになります。&lt;br /&gt;&lt;br /&gt;ひとまず少し前に記述していたEvernoteの要素をそのまま出してみました！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4579188641783870630?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4579188641783870630/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4579188641783870630' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4579188641783870630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4579188641783870630'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/canvas.html' title='Canvasで絵を書いてみる'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-i2kkeeAEgRI/TfYXg24N-iI/AAAAAAAAAMs/7b5YEKYgNjM/s72-c/canvas.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8280891814614578823</id><published>2011-06-07T19:20:00.002+09:00</published><updated>2011-06-07T21:13:45.913+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='UserStore'/><title type='text'>Evernoteにアクセスする　その７　ユーザ情報編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;さてNotebookの内容に入って行こうと思ってたんですけど、&lt;br /&gt;冷静に考えるとユーザ名がない事に気づいた。&lt;br /&gt;ログアウトとかに表示したいですよね。&lt;br /&gt;&lt;br /&gt;なのでユーザの情報を取得しようと思います。&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;       THttpClient userStoreTrans;&lt;br /&gt;  try {&lt;br /&gt;   userStoreTrans = new THttpClient(USER_URL);&lt;br /&gt;  } catch (TTransportException e) {&lt;br /&gt;   throw new RuntimeException("クライアントアクセス時の例外",e);&lt;br /&gt;  } catch (NullPointerException e) {&lt;br /&gt;   throw new RuntimeException("クライアントアクセス時の例外",e);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;       TBinaryProtocol userStoreProt = new TBinaryProtocol(userStoreTrans);&lt;br /&gt;       UserStore.Client userStore = new UserStore.Client(userStoreProt, userStoreProt);&lt;br /&gt;&lt;br /&gt;     User user = userStore.getUser(getAccessToken());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;こんな感じです。&lt;a href="https://www.evernote.com/about/developer/api/ref/UserStore.html#Svc_UserStore"&gt;UserStore&lt;/a&gt;を取得するための&lt;br /&gt;USER_URLには「https://sandbox.evernote.com/edam/user」ですね。&lt;br /&gt;ノートの場合とアクセスするUrlが違います。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.evernote.com/about/developer/api/ref/UserStore.html#Fn_UserStore_getUser"&gt;getUser()&lt;/a&gt;に対してアクセストークンを渡してあげます。&lt;br /&gt;これで返って来る&lt;a href="https://www.evernote.com/about/developer/api/ref/Types.html#Struct_User"&gt;User&lt;/a&gt;に情報が入っています。&lt;br /&gt;&lt;br /&gt;getEmail()とかあるので「やべー」と思いましたがどうやら値は入ってないようですね。&lt;br /&gt;Userを見る限り、UploadのLimit等も入っているのでその辺りを考慮してアップロード等を&lt;br /&gt;行う必要があるようですが、一応アップ系の処理は行わないので使わないかな？&lt;br /&gt;&lt;br /&gt;さてまた寄り道になりましたがひとまずそれを利用してログアウトのリンクを作成。&lt;br /&gt;ノートブックの一覧等を利用して、ひとまずノートを選択するような仕組みにしてみました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://note.ziro.co.jp"&gt;ここ&lt;/a&gt;からアクセスできますけど、&lt;br /&gt;sandboxのユーザがないと無理ですので、持っている方しかアクセスできません。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8280891814614578823?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8280891814614578823/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8280891814614578823' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8280891814614578823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8280891814614578823'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote_07.html' title='Evernoteにアクセスする　その７　ユーザ情報編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7876461046740321430</id><published>2011-06-06T08:26:00.003+09:00</published><updated>2011-06-07T19:20:50.391+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><title type='text'>Evernoteにアクセスする　その６ ノート一覧取得編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;さて認証部分も終わったので、そろそろAPIでアクセスしないと&lt;br /&gt;何やってるかわかんなくなってくるのでひとまずアクセスしてみよう！&lt;br /&gt;&lt;br /&gt;実際にそこまでEvernote使いこなしているのか？という事も疑問でしたが&lt;br /&gt;「メモ(ノート)を取る」という意味ではすごく良いアプリなんだな。。。と感じてました。&lt;br /&gt;&lt;br /&gt;で、メモを活用するというアプリを考えた時に&lt;br /&gt;「んじゃEvernote使えば？」というのが、このAPIにアクセスするきっかけになったわけです。&lt;br /&gt;&lt;br /&gt;で、、、当初メモを取るアプリを考えていたんですけど、逆に考える事にしました。&lt;br /&gt;メモはいくらでも、どんな媒体でも取るんだから、メモに情報を付加したり、&lt;br /&gt;メモを取った後に色々眺める機能を作ってみようって。&lt;br /&gt;まぁAPIアクセスを考えれるように、少しは追加とかもやるかもですけど。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;で、evernoteにAPIでアクセスするまで、「ノートブック」と「ノート」の概念をあまり考えていませんでした。&lt;br /&gt;なのでまずは一覧化して表示してみましょう。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;       NoteStore.Client noteStore = getClient();&lt;br /&gt;       List&lt;Notebook&gt; notebooks = noteStore.listNotebooks(getAccessToken());&lt;br /&gt;&lt;br /&gt;       for (Notebook notebook : notebooks) {&lt;br /&gt;        String guid = notebook.getGuid();&lt;br /&gt;        logger.info(notebook.getName() + ":" + guid);&lt;br /&gt;        NoteFilter filter = new NoteFilter();&lt;br /&gt;        filter.setNotebookGuid(guid);&lt;br /&gt;        NoteList noteList = noteStore.findNotes(getAccessToken(),filter, 0, 100);&lt;br /&gt;        for ( Note note: noteList.getNotes() ) {&lt;br /&gt;         logger.info(note.getTitle());&lt;br /&gt;        }&lt;br /&gt;       }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;getClient()は前述の通り、SharedIdを元に取得してきます。&lt;br /&gt;それとgetAccessToken()も認証の情報を元に取得してきます。&lt;br /&gt;&lt;br /&gt;まず&lt;a href="https://www.evernote.com/about/developer/api/ref/NoteStore.html#Fn_NoteStore_listNotebooks"&gt;listNotebooks()&lt;/a&gt;によりノートブックの一覧が取得できます。&lt;br /&gt;Notebookには「guid」が存在し、それが一意の識別子になります。&lt;br /&gt;&lt;br /&gt;それを元に&lt;a href="https://www.evernote.com/about/developer/api/ref/NoteStore.html#Struct_NoteFilter"&gt;NoteFilter&lt;/a&gt;を準備して、そこにGuidを設定して&lt;a href="https://www.evernote.com/about/developer/api/ref/NoteStore.html#Fn_NoteStore_findNotes"&gt;findNotes()&lt;/a&gt;を行います。&lt;br /&gt;第３、４引数は、オフセットとMaxの件数です。Maxの件数は、、、すべてってのは出来なさそう、、、&lt;br /&gt;&lt;br /&gt;ひとまずこんなところですかね。&lt;br /&gt;一応アプリではNotebookの一覧を表示して、クリックしたら、Noteの一覧が出るようなものを考えています。&lt;br /&gt;&lt;br /&gt;次はNotebookについて記述していきましょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7876461046740321430?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7876461046740321430/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7876461046740321430' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7876461046740321430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7876461046740321430'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote_06.html' title='Evernoteにアクセスする　その６ ノート一覧取得編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6392173379435397913</id><published>2011-06-04T17:45:00.004+09:00</published><updated>2011-06-05T17:03:15.633+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><title type='text'>Evernoteにアクセスする　その５ OAuth理解編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;OAuthサンプルによって解説しようと思っていましたが、&lt;br /&gt;結局暗号化を行って、テスト書いて、色々分かりやすくコードをいじってってこの状態になりました。&lt;br /&gt;以下のコードでアクセスできます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;package jp.co.ziro.evernote.controller;&lt;br /&gt;&lt;br /&gt;import java.io.BufferedReader;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.io.UnsupportedEncodingException;&lt;br /&gt;import java.net.HttpURLConnection;&lt;br /&gt;import java.net.MalformedURLException;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.net.URLDecoder;&lt;br /&gt;import java.net.URLEncoder;&lt;br /&gt;import java.security.InvalidKeyException;&lt;br /&gt;import java.security.NoSuchAlgorithmException;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.Random;&lt;br /&gt;import java.util.TreeMap;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import javax.crypto.Mac;&lt;br /&gt;import javax.crypto.spec.SecretKeySpec;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.codec.binary.Base64;&lt;br /&gt;import org.slim3.util.ApplicationMessage;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * &lt;pre&gt;&lt;br /&gt; * EvernoteへのOAuthアクセスクラス&lt;br /&gt; *  - 認証URL作成 setCallbackUrl()&lt;br /&gt; *  - アクセストークン取得時はsendRequest(tokenSecret)&lt;br /&gt; *  で処理を行います。&lt;br /&gt; * &lt;br /&gt; * 認証Urlの作成&lt;br /&gt; * 1.コンストラクタにより、固定値を設定する&lt;br /&gt; * 2.使用側は setCallbackUrl() にコールバックするUrlを設定する&lt;br /&gt; * 3.createAuthorization() の戻り値が認証Urlを取得&lt;br /&gt; * 4.getTokenSecret(),secretを取得(保存)&lt;br /&gt; * &lt;br /&gt; * 認証Urlにアクセスする&lt;br /&gt; * 認可画面が表示され、そこでの結果がコールバックに渡される&lt;br /&gt; *&lt;br /&gt; * コールバックUrlで行う事&lt;br /&gt; * 1.コンストラクタにより固定値を設定する&lt;br /&gt; * 2.oauth_verifier,oauth_tokenがコールバックに呼ばれるのでそれを&lt;br /&gt; *   setToken() setVerifier() で設定&lt;br /&gt; *   verifierがnullだったら、認証が行われていない。&lt;br /&gt; * 3.sendRequest()を行う。引数は認証Url時に作成したsecret&lt;br /&gt; * 4.oauth_token にリクエストトークン、edam_shard にAPIアクセス用のIdが渡されます。&lt;br /&gt; * &lt;br /&gt; * これらでthriftのAPIを利用して、Evernoteにアクセスできます。&lt;br /&gt; *  &lt;br /&gt; * &lt;/pre&gt;&lt;br /&gt; * @author secondarykey&lt;br /&gt; */&lt;br /&gt;public class EvernoteRequest {&lt;br /&gt;&lt;br /&gt;    @SuppressWarnings("unused")&lt;br /&gt;    private static Logger logger = Logger.getLogger(EvernoteRequest.class.getName());&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * EverNoteのAPI ConsumerKey&lt;br /&gt;     */&lt;br /&gt; private static final String CONSUMERKEY = ApplicationMessage&lt;br /&gt;   .get("evernote.api.key");&lt;br /&gt; /**&lt;br /&gt;  * EvernoteのAPI ConsumerSecret&lt;br /&gt;  */&lt;br /&gt; private static final String CONSUMERSECRET = ApplicationMessage&lt;br /&gt;   .get("evernote.api.secret");&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * アクセスするUrl&lt;br /&gt;  */&lt;br /&gt; private static final String BASEURL = ApplicationMessage&lt;br /&gt;   .get("evernote.api.baseUrl");&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * リクエストToken取得用のUrl&lt;br /&gt;  */&lt;br /&gt; private static final String requestUrl = BASEURL&lt;br /&gt;   + ApplicationMessage.get("evernote.api.requestTokenUrl");&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  *　認証のUrl&lt;br /&gt;  */&lt;br /&gt;    private static final String authorizationUrlBase = BASEURL + ApplicationMessage.get("evernote.api.oauthUrl");&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * 文字コード&lt;br /&gt;  */&lt;br /&gt; private static final String CHARSET = "UTF-8";&lt;br /&gt; /**&lt;br /&gt;  * キー作成用のGETメソッド名&lt;br /&gt;  */&lt;br /&gt; private static final String REQUEST_METHOD = "GET";&lt;br /&gt; /**&lt;br /&gt;  * OAuth nonces用のランダム値生成&lt;br /&gt;  */&lt;br /&gt; private static final Random random = new Random();&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * ベースのURL&lt;br /&gt;  * @return リクエストするBaseUrl&lt;br /&gt;  */&lt;br /&gt; public static String getBaseUrl() {&lt;br /&gt;  return BASEURL;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * リクエストするパラメーター&lt;br /&gt;  */&lt;br /&gt; private Map&lt;String, String&gt; parameters = new TreeMap&lt;String, String&gt;();&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * TokenSecret&lt;br /&gt;  * getTokenSecret()時に空の場合、Exceptionを発生&lt;br /&gt;  */&lt;br /&gt; private String tokenSecret = null;&lt;br /&gt; /**&lt;br /&gt;  * &lt;pre&gt;&lt;br /&gt;  * コンストラクタ&lt;br /&gt;  * パラメータ固定値を設定する&lt;br /&gt;  * &lt;/pre&gt;&lt;br /&gt;  */&lt;br /&gt; public EvernoteRequest() {&lt;br /&gt;  setParameter("oauth_consumer_key", CONSUMERKEY);&lt;br /&gt;  setParameter("oauth_timestamp", getTimestamp());&lt;br /&gt;  setParameter("oauth_nonce", Long.toHexString(random.nextLong()));&lt;br /&gt;  setParameter("oauth_version", "1.0");&lt;br /&gt;  //暗号化を行う&lt;br /&gt;  setParameter("oauth_signature_method", "HMAC-SHA1");&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * タイムスタンプを作成&lt;br /&gt;  * @return 現在時刻の秒をString化した値&lt;br /&gt;  */&lt;br /&gt; private String getTimestamp() {&lt;br /&gt;  return Long.toString(System.currentTimeMillis() / 1000);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * コールバックURLを設定する&lt;br /&gt;  * @param callbackUrl コールバックUrl&lt;br /&gt;  */&lt;br /&gt; public void setCallbackUrl(String callbackUrl) {&lt;br /&gt;        setParameter("oauth_callback", callbackUrl);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * リクエストトークンを設定&lt;br /&gt;  * @param requestToken コールバックされたリクエストトークン&lt;br /&gt;  */&lt;br /&gt; public void setToken(String requestToken) {&lt;br /&gt;        //それぞれをリクエスターに設定&lt;br /&gt;        setParameter( "oauth_token", requestToken);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Verifierの設定&lt;br /&gt;  * @param verifier コールバックされたverifier値&lt;br /&gt;  */&lt;br /&gt; public void setVerifier(String verifier) {&lt;br /&gt;        setParameter( "oauth_verifier", verifier);&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * リクエスト時の引数設定&lt;br /&gt;  * @param name パラメータ名称&lt;br /&gt;  * @param value パラメータの値&lt;br /&gt;  */&lt;br /&gt; private void setParameter(String name, String value) {&lt;br /&gt;  parameters.put(name, value);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Encodes this request as a single URL that can be opened.&lt;br /&gt;  */&lt;br /&gt; private String getUrl() {&lt;br /&gt;  return requestUrl + "?" + join();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * HTTP引数の連結&lt;br /&gt;  * @return Url引数にして返す&lt;br /&gt;  */&lt;br /&gt; private String join() {&lt;br /&gt;  StringBuilder sb = new StringBuilder();&lt;br /&gt;  //開始フラグ&lt;br /&gt;  boolean firstParam = true;&lt;br /&gt;  &lt;br /&gt;  //引数数繰り返す&lt;br /&gt;  for (Map.Entry&lt;String, String&gt; parameter : parameters.entrySet()) {&lt;br /&gt;   //最初の処理&lt;br /&gt;   if (firstParam) {&lt;br /&gt;    firstParam = false;&lt;br /&gt;   } else {&lt;br /&gt;    sb.append('&amp;');&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //キー値を取得&lt;br /&gt;   sb.append(parameter.getKey());&lt;br /&gt;   //連結子を設定&lt;br /&gt;   sb.append('=');&lt;br /&gt;   try {&lt;br /&gt;    //値をエンコードして設定&lt;br /&gt;    sb.append(URLEncoder.encode(parameter.getValue(), CHARSET));&lt;br /&gt;   } catch (UnsupportedEncodingException e) {&lt;br /&gt;    throw new RuntimeException("エンコード時の例外", e);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return sb.toString();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * リクエストを行う&lt;br /&gt;  * @param&lt;br /&gt;  * &lt;br /&gt;  * @throws IOException&lt;br /&gt;  *             if a problem occurs making the request or getting the reply.&lt;br /&gt;  */&lt;br /&gt; public Map&lt;String, String&gt; sendRequest(String tokenSecret) {&lt;br /&gt;        //Signatureを設定&lt;br /&gt;  setParameter("oauth_signature", createSignature(tokenSecret));&lt;br /&gt;  //アクセスする&lt;br /&gt;  HttpURLConnection connection;&lt;br /&gt;  try {&lt;br /&gt;   connection = (HttpURLConnection) (new URL(getUrl())).openConnection();&lt;br /&gt;  } catch (MalformedURLException e) {&lt;br /&gt;   throw new RuntimeException("アクセスに対する例外",e);&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new RuntimeException("アクセスに対する例外",e);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  int responseCode;&lt;br /&gt;  String responseMessage;&lt;br /&gt;  try {&lt;br /&gt;   responseCode = connection.getResponseCode();&lt;br /&gt;   responseMessage = connection.getResponseMessage();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new RuntimeException("結果取得を行う",e);&lt;br /&gt;  }&lt;br /&gt;  // リクエストが正常じゃない場合&lt;br /&gt;  if (responseCode != HttpURLConnection.HTTP_OK) {&lt;br /&gt;   throw new RuntimeException("Server returned error code: " + responseCode + " " + responseMessage);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return createResponseMap(connection);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * &lt;pre&gt;&lt;br /&gt;  * 暗号化を行う&lt;br /&gt;  * 1. メソッド名&amp;アクセスUrl&amp;HTTPの引数の文字列を作成&lt;br /&gt;  * 2. secretをTokenと連結してsecretをバイト化&lt;br /&gt;  * 3. Secret値を元にSignatureStringを暗号化を行う&lt;br /&gt;  * 4. その値をBase64で16進数かする&lt;br /&gt;  * &lt;/pre&gt;&lt;br /&gt;  * @param tokenSecret リクエストToken取得時に発行されたSecret&lt;br /&gt;  * @return 暗号化したSecret値&lt;br /&gt;  */&lt;br /&gt; private String createSignature(String tokenSecret) {&lt;br /&gt;&lt;br /&gt;  String encodeUrl  = encode(requestUrl);&lt;br /&gt;  String encodeJoin = encode(join());&lt;br /&gt;  String signatureBaseString = REQUEST_METHOD + "&amp;" + encodeUrl + "&amp;" + encodeJoin;&lt;br /&gt;&lt;br /&gt;  // 署名対象のテキストを作成&lt;br /&gt;  String secret = CONSUMERSECRET + "&amp;";&lt;br /&gt;  //TokenSecretが存在する場合&lt;br /&gt;  if (tokenSecret != null) {&lt;br /&gt;   secret += tokenSecret;&lt;br /&gt;  }&lt;br /&gt;        byte[] secretyKeyBytes;&lt;br /&gt;  try {&lt;br /&gt;   secretyKeyBytes = secret.getBytes(CHARSET);&lt;br /&gt;  } catch (UnsupportedEncodingException e2) {&lt;br /&gt;   throw new RuntimeException("エンコード時の失敗",e2);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  String hmac = "HmacSHA1";&lt;br /&gt;     SecretKeySpec secretKeySpec =  new SecretKeySpec(secretyKeyBytes,hmac);&lt;br /&gt;     Mac mac;&lt;br /&gt;  try {&lt;br /&gt;   mac = Mac.getInstance(hmac);&lt;br /&gt;   mac.init(secretKeySpec);&lt;br /&gt;  } catch (NoSuchAlgorithmException e1) {&lt;br /&gt;   throw new RuntimeException("暗号化インスタンス取得失敗",e1);&lt;br /&gt;  } catch (InvalidKeyException e1) {&lt;br /&gt;   throw new RuntimeException("暗号化インスタンス取得失敗",e1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;        byte[] data;&lt;br /&gt;        try {&lt;br /&gt;            data = signatureBaseString.getBytes(CHARSET);&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException(CHARSET + " is unsupported!", e);&lt;br /&gt;        }&lt;br /&gt;        byte[] rawHmac = mac.doFinal(data);&lt;br /&gt;        Base64 encoder = new Base64();&lt;br /&gt; &lt;br /&gt;        return new String(encoder.encode(rawHmac));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * 値のUrlエンコード&lt;br /&gt;  * @param value エンコードする値&lt;br /&gt;  * @return エンコードした値&lt;br /&gt;  */&lt;br /&gt; private String encode(String value) {&lt;br /&gt;  String rtnData;&lt;br /&gt;  try {&lt;br /&gt;   rtnData = URLEncoder.encode(value,CHARSET);&lt;br /&gt;  } catch (UnsupportedEncodingException e) {&lt;br /&gt;   throw new RuntimeException("エンコード時の例外",e);&lt;br /&gt;  }&lt;br /&gt;  return rtnData;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * レスポンスの値を取得&lt;br /&gt;  * &lt;br /&gt;  * @param connection&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; private Map&lt;String, String&gt; createResponseMap(HttpURLConnection connection) {&lt;br /&gt;&lt;br /&gt;  BufferedReader bufferedReader;&lt;br /&gt;  String result;&lt;br /&gt;  try {&lt;br /&gt;   bufferedReader = new BufferedReader(new InputStreamReader(&lt;br /&gt;     connection.getInputStream()));&lt;br /&gt;   result = bufferedReader.readLine();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new RuntimeException("読み込み時の例外", e);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Map&lt;String, String&gt; responseParameters = new HashMap&lt;String, String&gt;();&lt;br /&gt;  for (String param : result.split("&amp;")) {&lt;br /&gt;   int equalsAt = param.indexOf('=');&lt;br /&gt;   if (equalsAt &gt; 0) {&lt;br /&gt;    String name = param.substring(0, equalsAt);&lt;br /&gt;    String value;&lt;br /&gt;    try {&lt;br /&gt;     value = URLDecoder.decode(param.substring(equalsAt + 1),&lt;br /&gt;       CHARSET);&lt;br /&gt;    } catch (UnsupportedEncodingException e) {&lt;br /&gt;     throw new RuntimeException("エンコード時の例外", e);&lt;br /&gt;    }&lt;br /&gt;    responseParameters.put(name, value);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return responseParameters;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * 認証Urlの作成&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public String createAuthorizarionUrl() {&lt;br /&gt;        //リクエスト&lt;br /&gt;        Map&lt;String, String&gt; reply = sendRequest(null);&lt;br /&gt;        String requestToken     = reply.get("oauth_token");&lt;br /&gt;        //認証Urlの作成&lt;br /&gt;        String authorizationUrl = authorizationUrlBase + "?oauth_token=" + requestToken;&lt;br /&gt;        //TokenSecretを設定する&lt;br /&gt;        tokenSecret = reply.get("oauth_token_secret");&lt;br /&gt;  return authorizationUrl;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * TokenSecretの取得&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public String getTokenSecret() {&lt;br /&gt;  if ( tokenSecret == null ) {&lt;br /&gt;   throw new NullPointerException("TokenSecretが設定されていない");&lt;br /&gt;  }&lt;br /&gt;  return tokenSecret;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;まずコンストラクタで各種固定値の設定を行います。&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;oauth_consumer_key:&lt;i&gt;KEY値&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;oauth_signature_method:&lt;i&gt;「PLANTEXT」「HMAC-SHA1」のどちらか&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;oauth_timestamp:&lt;i&gt;現在の秒&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;oauth_nonce:&lt;i&gt;ランダムの値(リクエスト毎に一意)&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;oauth_version:&lt;i&gt;「1.0」固定&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Evernoteのサンプルではoauth_signatureにSECRET値を指定していますが、&lt;br /&gt;HMAC-SHA1の際は暗号化を行うので、まだ指定していません。&lt;br /&gt;oauth_signature_methodはPLANTEXT、HMAC-SHA1が存在し、サンプルはPLANTEXTが指定されています。&lt;br /&gt;PLANTEXTを推奨(つうか使って)しているのも珍しい気もします。&lt;br /&gt;&lt;br /&gt;HTTPにアクセスする時に利用するMapをTreeMapを利用していますが&lt;br /&gt;暗号化時に引数をソートする必要があるのでTreeMapでKey値のソートを行っているわけです。&lt;br /&gt;&lt;br /&gt;コンストラクタで設定した後はコールバックUrl(oauth_callback)を指定します。&lt;br /&gt;Evernoteの認可画面により処理が行われるとそのUrlに戻ってきます。&lt;br /&gt;&lt;br /&gt;認可画面に行くためにリクエストトークンを取得しに行きます。&lt;br /&gt;createAuthorizarionUrl()ですね。&lt;br /&gt;&lt;br /&gt;ここでsendRequest()でEvernoteにアクセスしています。&lt;br /&gt;oauth_signatureをcreateSignatuer()を行ってHMAC-SHA1の暗号化を行って指定しています。&lt;br /&gt;&lt;br /&gt;返ってきたResponseから値を取得します。&lt;br /&gt;レスポンスにリクエストトークン（oauth_token）とSecret(oauth_token_secret)が指定されています。&lt;br /&gt;リクエストトークンはhttps://sandbox.evernote.com/?oauth_token=xxxxとして利用すると認可画面にアクセスする事ができます。&lt;br /&gt;Secret値は、アクセストークン時にシグネチャ値のキー値とする時にConsumerSecretと合わせて使用します。&lt;br /&gt;&lt;br /&gt;ここまでが認可画面のリンクを作成する流れです。&lt;br /&gt;&lt;br /&gt;コールバックURLを指定していますが、認可画面にアクセスし、操作を行うとこのUrlに戻ってきます。&lt;br /&gt;そちらの処理が以下になります。&lt;br /&gt;&lt;br /&gt;認証に成功するとコールバックURLにoauth_token、oauth_verifierが付与されて来ます。&lt;br /&gt;oauth_verifierが存在しない場合は認証で拒否された等ですので、エラー画面等を出力しましょう。&lt;br /&gt;&lt;br /&gt;設定されていたら、アクセストークンを取得する為、&lt;br /&gt;このクラスをnewしてインスタンス化します。※設定する値は一緒。&lt;br /&gt;&lt;br /&gt;oauth_tokenをsetToken() ,oauth_verifierをsetVerifier()を利用して、設定します。&lt;br /&gt;設定したらsendRequest()によりアクセストークンを取得するのですが、&lt;br /&gt;この時に最初のアクセスで取得したtokenSecretを渡します。&lt;br /&gt;&lt;br /&gt;取得に成功するとoauth_tokenにアクセストークン、edam_shardにEvernoteにアクセスする時に必要な値が入ってきます。&lt;br /&gt;このアクセストークンさえあれば何でもできるわけです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;その値を利用してAPIのアクセスです。&lt;br /&gt;thriftのライブラリを使っています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        String noteStoreUrl = noteStoreUrlBase + shardId;&lt;br /&gt;       THttpClient noteStoreTrans    = new THttpClient(noteStoreUrl);&lt;br /&gt;       TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);&lt;br /&gt;&lt;br /&gt;       NoteStore.Client noteStore =&lt;br /&gt;         new NoteStore.Client(noteStoreProt, noteStoreProt);&lt;br /&gt;       List&lt;Notebook&gt; notebooks = noteStore.listNotebooks(accessToken);&lt;br /&gt;       for (Notebook notebook : notebooks) {&lt;br /&gt;         logger.info("Notebook: " + notebook.getName());&lt;br /&gt;       }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;サンドボックス＋"/edam/note/"＋edam_shardの値を作成して&lt;br /&gt;それでTHttpClientを生成、それを利用してTBinaryProtocolを生成しています。&lt;br /&gt;&lt;br /&gt;それを利用して生成しているNoteStore.ClientはEvernoteのライブラリですね。&lt;br /&gt;生成したオブジェクトでAPI呼び出しを行っています。&lt;br /&gt;ここではlistNotebooks()です。そこにアクセストークンを渡してアクセスしています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・さて、再度理解を深める為にOAuthをしっかり説明してみました。&lt;br /&gt;説明がヘタすぎますけど、ご了承ください。&lt;br /&gt;&lt;br /&gt;まぁとにかく次回はAPIで色々やってみます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6392173379435397913?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6392173379435397913/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6392173379435397913' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6392173379435397913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6392173379435397913'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote-oauth_04.html' title='Evernoteにアクセスする　その５ OAuth理解編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4167055166719568741</id><published>2011-06-03T16:26:00.010+09:00</published><updated>2011-06-04T17:55:42.656+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='HMAC-SHA1'/><title type='text'>Evernoteにアクセスする　その４ HMAC-SHA1編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;ここまでサンプルを元にEvernoteにアクセスしてきましたが、&lt;br /&gt;SimpleOAuthRequestの中身を見てOAuthアクセスへの理解を&lt;br /&gt;深めておきましょう。。。。って思ったんですけど、PLANTEXTでアクセスしているので&lt;br /&gt;HMAC-SHA1でアクセスしてみましょう。&lt;br /&gt;&lt;br /&gt;以下が元ソースです。&lt;br /&gt;見られる場合は展開してください。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;/**&lt;br /&gt; * Copyright 2008 by EverNote Corporation.  All rights reserved.&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package com.evernote.oauth.consumer;&lt;br /&gt;&lt;br /&gt;import java.io.BufferedReader;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.net.HttpURLConnection;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.net.URLDecoder;&lt;br /&gt;import java.net.URLEncoder;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.Random;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * This is a very simple implementation of an OAuth consumer request which can&lt;br /&gt; * be used to ask an OAuth service provider for either a Request Token or&lt;br /&gt; * an Access Token.  It only handles PLAINTEXT authentication, and it only goes&lt;br /&gt; * over a GET transport.  As a result, it should only be used over SSL.&lt;br /&gt; * &lt;br /&gt; * @author Dave Engberg&lt;br /&gt; */&lt;br /&gt;public class SimpleOAuthRequest {&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Random number generator for creating OAuth nonces&lt;br /&gt;   */&lt;br /&gt;  private static final Random random = new Random();&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * The URL of the OAuth service Provider that we should hit to request a&lt;br /&gt;   * token.&lt;br /&gt;   */&lt;br /&gt;  private String providerUrl;&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * A mapping containing all of the OAuth parameters that will be passed in&lt;br /&gt;   * the reply.&lt;br /&gt;   */&lt;br /&gt;  private Map&lt;String, String&gt; parameters = new HashMap&lt;String, String&gt;();&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Constructs a request object that can be used to make token requests from&lt;br /&gt;   * an OAuth provider.&lt;br /&gt;   * &lt;br /&gt;   * @param providerUrl  the base URL to request a Request or Access token&lt;br /&gt;   * @param consumerKey  the OAuth consumer key, given by the Service Provider&lt;br /&gt;   * @param consumerSecret  the OAuth consumer secret, given by the Provider&lt;br /&gt;   * @param tokenSecret  if non-null, this is the previous oauth_token_secret&lt;br /&gt;   *   that should be used in signing this request.  If null, this will assume&lt;br /&gt;   *   that this message does not include a token secret in its signature&lt;br /&gt;   */&lt;br /&gt;  public SimpleOAuthRequest(String providerUrl, String consumerKey,&lt;br /&gt;      String consumerSecret, String tokenSecret) {&lt;br /&gt;    this.providerUrl = providerUrl;&lt;br /&gt;    setParameter("oauth_consumer_key", consumerKey);&lt;br /&gt;    String signature = consumerSecret + "&amp;";&lt;br /&gt;    if (tokenSecret != null) {&lt;br /&gt;      signature += tokenSecret;&lt;br /&gt;    }&lt;br /&gt;    setParameter("oauth_signature", signature);&lt;br /&gt;    setParameter("oauth_signature_method", "PLAINTEXT");&lt;br /&gt;    setParameter("oauth_timestamp",&lt;br /&gt;        Long.toString(System.currentTimeMillis() / 1000));&lt;br /&gt;    setParameter("oauth_nonce",&lt;br /&gt;        Long.toHexString(random.nextLong()));&lt;br /&gt;    setParameter("oauth_version", "1.0");&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Sets one of the query string parameters for the request that will be&lt;br /&gt;   * made to the OAuth provider.  The value will be URL encoded before adding&lt;br /&gt;   * to the URL.&lt;br /&gt;   * &lt;br /&gt;   * @param name  the name of the parameter to be set&lt;br /&gt;   * @param value  the string value, unencoded&lt;br /&gt;   */&lt;br /&gt;  public void setParameter(String name, String value) {&lt;br /&gt;    parameters.put(name, value);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Encodes this request as a single URL that can be opened.&lt;br /&gt;   */&lt;br /&gt;  public String encode() throws IOException {&lt;br /&gt;    StringBuilder sb = new StringBuilder();&lt;br /&gt;    sb.append(providerUrl);&lt;br /&gt;    boolean firstParam = providerUrl.indexOf('?') &lt; 0;&lt;br /&gt;    for (Map.Entry&lt;String, String&gt; parameter : parameters.entrySet()) {&lt;br /&gt;      if (firstParam) {&lt;br /&gt;        sb.append('?');&lt;br /&gt;        firstParam = false;&lt;br /&gt;      } else {&lt;br /&gt;        sb.append('&amp;');&lt;br /&gt;      }&lt;br /&gt;      sb.append(parameter.getKey());&lt;br /&gt;      sb.append('=');&lt;br /&gt;      sb.append(URLEncoder.encode(parameter.getValue(), "UTF-8"));&lt;br /&gt;    }&lt;br /&gt;    return sb.toString();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Sends the request to the OAuth Provider, and returns the set of reply&lt;br /&gt;   * parameters, mapped from name to decoded value.&lt;br /&gt;   *&lt;br /&gt;   * @throws IOException  if a problem occurs making the request or getting the&lt;br /&gt;   *   reply.&lt;br /&gt;   */&lt;br /&gt;  public Map&lt;String,String&gt; sendRequest() throws IOException {&lt;br /&gt;&lt;br /&gt;    HttpURLConnection connection =&lt;br /&gt;      (HttpURLConnection)(new URL(encode())).openConnection();&lt;br /&gt;    int responseCode = connection.getResponseCode();&lt;br /&gt;    if (responseCode != HttpURLConnection.HTTP_OK) {&lt;br /&gt;      throw new IOException("Server returned error code: " + responseCode +&lt;br /&gt;          " " + connection.getResponseMessage());&lt;br /&gt;    }&lt;br /&gt;    BufferedReader bufferedReader = new BufferedReader(&lt;br /&gt;        new InputStreamReader(connection.getInputStream()));&lt;br /&gt;    String result = bufferedReader.readLine();&lt;br /&gt;    Map&lt;String,String&gt; responseParameters = new HashMap&lt;String,String&gt;();&lt;br /&gt;    for (String param : result.split("&amp;")) {&lt;br /&gt;      int equalsAt = param.indexOf('=');&lt;br /&gt;      if (equalsAt &gt; 0) {&lt;br /&gt;        String name = param.substring(0, equalsAt);&lt;br /&gt;        String value =&lt;br /&gt;          URLDecoder.decode(param.substring(equalsAt + 1), "UTF-8");&lt;br /&gt;        responseParameters.put(name, value);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return responseParameters;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;これをHMAC-SHA1で処理を行う場合は、oauth_signatureの指定に&lt;br /&gt;・HTTPメソッド&lt;br /&gt;・リクエストURL&lt;br /&gt;・リクエストパタメータ&lt;br /&gt;これらをURLエンコードして、＆で結合してHMAC-SHA1で16進のダイジェスト値を作って&lt;br /&gt;Base64エンコード後、URLエンコードした値をoauth_signatureに指定します。&lt;br /&gt;&lt;br /&gt;オリジナルでEvernoteRequestクラスを作成してアクセスしてみましょう。&lt;br /&gt;※動作確認用なので汚いのは許して＞＜&lt;br /&gt;&lt;br /&gt;以下がHMAC-SHA1でアクセスしたソース&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;/**&lt;br /&gt; * Copyright 2008 by EverNote Corporation.  All rights reserved.&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package jp.co.ziro.evernote.controller;&lt;br /&gt;&lt;br /&gt;import java.io.BufferedReader;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.io.UnsupportedEncodingException;&lt;br /&gt;import java.net.HttpURLConnection;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.net.URLDecoder;&lt;br /&gt;import java.net.URLEncoder;&lt;br /&gt;import java.security.InvalidKeyException;&lt;br /&gt;import java.security.NoSuchAlgorithmException;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.Random;&lt;br /&gt;import java.util.TreeMap;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import javax.crypto.Mac;&lt;br /&gt;import javax.crypto.spec.SecretKeySpec;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.codec.binary.Base64;&lt;br /&gt;import org.slim3.util.ApplicationMessage;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * This is a very simple implementation of an OAuth consumer request which can&lt;br /&gt; * be used to ask an OAuth service provider for either a Request Token or an&lt;br /&gt; * Access Token. It only handles PLAINTEXT authentication, and it only goes over&lt;br /&gt; * a GET transport. As a result, it should only be used over SSL.&lt;br /&gt; * &lt;br /&gt; * @author Dave Engberg&lt;br /&gt; */&lt;br /&gt;public class EvernoteRequest {&lt;br /&gt;&lt;br /&gt;    @SuppressWarnings("unused")&lt;br /&gt;    private static Logger logger = Logger.getLogger(EvernoteRequest.class.getName());&lt;br /&gt; private static final String consumerKey = ApplicationMessage&lt;br /&gt;   .get("evernote.api.key");&lt;br /&gt; private static final String consumerSecret = ApplicationMessage&lt;br /&gt;   .get("evernote.api.secret");&lt;br /&gt; private static final String urlBase = ApplicationMessage&lt;br /&gt;   .get("evernote.api.baseUrl");&lt;br /&gt; private static final String requestUrl = urlBase&lt;br /&gt;   + ApplicationMessage.get("evernote.api.requestTokenUrl");&lt;br /&gt; /**&lt;br /&gt;  * ベースのURL&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public static String getBaseUrl() {&lt;br /&gt;  return urlBase;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Random number generator for creating OAuth nonces&lt;br /&gt;  */&lt;br /&gt; private static final Random random = new Random();&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * A mapping containing all of the OAuth parameters that will be passed in&lt;br /&gt;  * the reply.&lt;br /&gt;  */&lt;br /&gt; private Map&lt;String, String&gt; parameters = new TreeMap&lt;String, String&gt;();&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Constructs a request object that can be used to make token requests from&lt;br /&gt;  * an OAuth provider.&lt;br /&gt;  */&lt;br /&gt; public EvernoteRequest() {&lt;br /&gt;  setParameter("oauth_consumer_key", consumerKey);&lt;br /&gt;  //暗号化を行う&lt;br /&gt;  setParameter("oauth_signature_method", "HMAC-SHA1");&lt;br /&gt;  setParameter("oauth_timestamp", getTimestamp());&lt;br /&gt;  setParameter("oauth_nonce", Long.toHexString(random.nextLong()));&lt;br /&gt;  setParameter("oauth_version", "1.0");&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * タイムスタンプを作成&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; private String getTimestamp() {&lt;br /&gt;  return Long.toString(System.currentTimeMillis() / 1000);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Sets one of the query string parameters for the request that will be made&lt;br /&gt;  * to the OAuth provider. The value will be URL encoded before adding to the&lt;br /&gt;  * URL.&lt;br /&gt;  * &lt;br /&gt;  * @param name&lt;br /&gt;  *            the name of the parameter to be set&lt;br /&gt;  * @param value&lt;br /&gt;  *            the string value, unencoded&lt;br /&gt;  */&lt;br /&gt; public void setParameter(String name, String value) {&lt;br /&gt;  parameters.put(name, value);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Encodes this request as a single URL that can be opened.&lt;br /&gt;  */&lt;br /&gt; private String encode() {&lt;br /&gt;  return requestUrl + "?" + join();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * HTTP引数の連結&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; private String join() {&lt;br /&gt;  StringBuilder sb = new StringBuilder();&lt;br /&gt;  boolean firstParam = true;&lt;br /&gt;  for (Map.Entry&lt;String, String&gt; parameter : parameters.entrySet()) {&lt;br /&gt;   if (firstParam) {&lt;br /&gt;    firstParam = false;&lt;br /&gt;   } else {&lt;br /&gt;    sb.append('&amp;');&lt;br /&gt;   }&lt;br /&gt;   sb.append(parameter.getKey());&lt;br /&gt;   sb.append('=');&lt;br /&gt;   try {&lt;br /&gt;    sb.append(URLEncoder.encode(parameter.getValue(), CHARSET));&lt;br /&gt;   } catch (UnsupportedEncodingException e) {&lt;br /&gt;    throw new RuntimeException("エンコード時の例外", e);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return sb.toString();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * 文字コード&lt;br /&gt;  */&lt;br /&gt; private static final String CHARSET = "UTF-8";&lt;br /&gt; /**&lt;br /&gt;  * キー作成用のGETメソッド名&lt;br /&gt;  */&lt;br /&gt; private static final String REQUEST_METHOD = "GET";&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Sends the request to the OAuth Provider, and returns the set of reply&lt;br /&gt;  * parameters, mapped from name to decoded value.&lt;br /&gt;  * &lt;br /&gt;  * @throws IOException&lt;br /&gt;  *             if a problem occurs making the request or getting the reply.&lt;br /&gt;  */&lt;br /&gt; public Map&lt;String, String&gt; sendRequest(String tokenSecret) throws IOException {&lt;br /&gt;  // 署名対象のテキストを作成&lt;br /&gt;  String secret = consumerSecret + "&amp;";&lt;br /&gt;  if (tokenSecret != null) {&lt;br /&gt;   secret += tokenSecret;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  String hmac = "HmacSHA1";&lt;br /&gt;  &lt;br /&gt;  String encodeUrl  = URLEncoder.encode(requestUrl,CHARSET);&lt;br /&gt;  String encodeJoin = URLEncoder.encode(join(),CHARSET);&lt;br /&gt;&lt;br /&gt;  String signatureBaseString = REQUEST_METHOD + "&amp;" + encodeUrl + "&amp;" + encodeJoin;&lt;br /&gt;  logger.info(signatureBaseString);&lt;br /&gt;&lt;br /&gt;        byte[] secretyKeyBytes = secret.getBytes(CHARSET);&lt;br /&gt;     SecretKeySpec secretKeySpec =  new SecretKeySpec(secretyKeyBytes,hmac);&lt;br /&gt;     Mac mac;&lt;br /&gt;  try {&lt;br /&gt;   mac = Mac.getInstance(hmac);&lt;br /&gt;   mac.init(secretKeySpec);&lt;br /&gt;  } catch (NoSuchAlgorithmException e1) {&lt;br /&gt;   throw new RuntimeException("暗号化インスタンス取得失敗",e1);&lt;br /&gt;  } catch (InvalidKeyException e1) {&lt;br /&gt;   throw new RuntimeException("暗号化インスタンス取得失敗",e1);&lt;br /&gt;  }&lt;br /&gt;     &lt;br /&gt;        String signature = null;&lt;br /&gt;        byte[] data;&lt;br /&gt;        byte[] rawHmac;&lt;br /&gt;        try {&lt;br /&gt;            data = signatureBaseString.getBytes(CHARSET);&lt;br /&gt;            rawHmac = mac.doFinal(data);&lt;br /&gt;            Base64 encoder = new Base64();&lt;br /&gt;            signature = new String(encoder.encode(rawHmac));&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException(CHARSET + " is unsupported!", e);&lt;br /&gt;        }&lt;br /&gt;  setParameter("oauth_signature", signature);&lt;br /&gt;&lt;br /&gt;  HttpURLConnection connection = (HttpURLConnection) (new URL(encode())).openConnection();&lt;br /&gt;  int responseCode = connection.getResponseCode();&lt;br /&gt;  // リクエストが正常じゃない場合&lt;br /&gt;  if (responseCode != HttpURLConnection.HTTP_OK) {&lt;br /&gt;   throw new IOException("Server returned error code: " + responseCode&lt;br /&gt;     + " " + connection.getResponseMessage());&lt;br /&gt;  }&lt;br /&gt;  return createResponseMap(connection);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * レスポンスの値を取得&lt;br /&gt;  * &lt;br /&gt;  * @param connection&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; private Map&lt;String, String&gt; createResponseMap(HttpURLConnection connection) {&lt;br /&gt;&lt;br /&gt;  BufferedReader bufferedReader;&lt;br /&gt;  String result;&lt;br /&gt;  try {&lt;br /&gt;   bufferedReader = new BufferedReader(new InputStreamReader(&lt;br /&gt;     connection.getInputStream()));&lt;br /&gt;   result = bufferedReader.readLine();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new RuntimeException("読み込み時の例外", e);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Map&lt;String, String&gt; responseParameters = new HashMap&lt;String, String&gt;();&lt;br /&gt;  for (String param : result.split("&amp;")) {&lt;br /&gt;   int equalsAt = param.indexOf('=');&lt;br /&gt;   if (equalsAt &gt; 0) {&lt;br /&gt;    String name = param.substring(0, equalsAt);&lt;br /&gt;    String value;&lt;br /&gt;    try {&lt;br /&gt;     value = URLDecoder.decode(param.substring(equalsAt + 1),&lt;br /&gt;       CHARSET);&lt;br /&gt;    } catch (UnsupportedEncodingException e) {&lt;br /&gt;     throw new RuntimeException("エンコード時の例外", e);&lt;br /&gt;    }&lt;br /&gt;    responseParameters.put(name, value);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return responseParameters;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;・・・本当に汚い、、、&lt;br /&gt;で、これを利用してindex時に&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        EvernoteRequest oauthRequestor = new EvernoteRequest();&lt;br /&gt;        String thisUrl = request.getRequestURL().toString();&lt;br /&gt;        String cbUrl = thisUrl.substring(0, thisUrl.lastIndexOf('/') + 1);&lt;br /&gt;        cbUrl = cbUrl + "callback";&lt;br /&gt;&lt;br /&gt;        oauthRequestor.setParameter("oauth_callback", cbUrl);&lt;br /&gt;        Map&lt;String, String&gt; reply = oauthRequestor.sendRequest(null);&lt;br /&gt;        &lt;br /&gt;        String requestToken = reply.get("oauth_token");&lt;br /&gt;        String tokenSecret = reply.get("oauth_token_secret");&lt;br /&gt;        String authorizationUrl = authorizationUrlBase + "?oauth_token=" + requestToken;&lt;br /&gt;&lt;br /&gt;        sessionScope("tokenSecret",tokenSecret);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;という風にします。&lt;br /&gt;すべての引数を指定した後にoauth_signatureを生成するので&lt;br /&gt;sendRequest()にtokenSecretを持ってきています。(コールバック時に利用)&lt;br /&gt;&lt;br /&gt;リクエストトークンとともにtokenSecretは取得できます。&lt;br /&gt;アクセストークンを取得する際に使用するtokenSecretをセッションに残しています。&lt;br /&gt;で以下がコールバックの処理。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        EvernoteRequest oauthRequestor = new EvernoteRequest();&lt;br /&gt;&lt;br /&gt;        String requestToken = requestScope("oauth_token");&lt;br /&gt;        String verifier     = requestScope("oauth_verifier");&lt;br /&gt;        String tokenSecret  = sessionScope("tokenSecret");&lt;br /&gt;&lt;br /&gt;        oauthRequestor.setParameter( "oauth_token", requestToken);&lt;br /&gt;        oauthRequestor.setParameter( "oauth_verifier", verifier);&lt;br /&gt;&lt;br /&gt;        //取得する&lt;br /&gt;        Map&lt;String, String&gt; reply = oauthRequestor.sendRequest(tokenSecret);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;こちらはセッションからtokenSecretを取得して指定しているだけですね。&lt;br /&gt;&lt;br /&gt;んーAuthrorization Headerでアクセスしたいですよねー。&lt;br /&gt;アクセスもPOSTでもないですし。。。本物はそうしてみようっ。と。&lt;br /&gt;&lt;br /&gt;次回、OAuthを読んでいくか、APIアクセスをもう少し行ってみるか悩んでます。&lt;br /&gt;それを記述するのはOAuthの仕様なだけなのでそっち読めば良いかなぁ、、、と。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4167055166719568741?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4167055166719568741/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4167055166719568741' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4167055166719568741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4167055166719568741'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote-hmac-sha1.html' title='Evernoteにアクセスする　その４ HMAC-SHA1編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1672047621748669376</id><published>2011-06-03T09:33:00.005+09:00</published><updated>2011-06-03T10:15:04.746+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Evernoteにアクセスする　その３ サンプルをシンプル編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;サンプルはJSPでOAuthを分かりやすく記述していますが&lt;br /&gt;手数が多く記述してあるので、実装としてはわかりずらいので&lt;br /&gt;一旦整理してみましょう。&lt;br /&gt;&lt;br /&gt;Google for Eclipse Plugin[更新サイト：http://dl.google.com/eclipse/plugin/3.6] と&lt;br /&gt;Slim3 Plugin[更新サイト：http://slim3.googlecode.com/svn/updates/]をインストールします。&lt;br /&gt;&lt;br /&gt;Slim3はGoogleAppEngineに最適化されたMVCフレームワークです。&lt;br /&gt;非常に簡単なので説明は省きます。&lt;br /&gt;&lt;br /&gt;indexを作成して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        SimpleOAuthRequest oauthRequestor =&lt;br /&gt;            new SimpleOAuthRequest(requestTokenUrl,consumerKey,consumerSecret,null);&lt;br /&gt;&lt;br /&gt;        //現在のURLからコールバックURLを作成&lt;br /&gt;        String thisUrl = request.getRequestURL().toString();&lt;br /&gt;        String cbUrl = thisUrl.substring(0, thisUrl.lastIndexOf('/') + 1);&lt;br /&gt;        cbUrl = cbUrl + "callback";&lt;br /&gt;&lt;br /&gt;        oauthRequestor.setParameter("oauth_callback", cbUrl);&lt;br /&gt;        Map&lt;String, String&gt; reply = oauthRequestor.sendRequest();&lt;br /&gt;&lt;br /&gt;        String requestToken = reply.get("oauth_token");&lt;br /&gt;        String authorizationUrl = authorizationUrlBase + "?oauth_token=" + requestToken;&lt;br /&gt;&lt;br /&gt;        //認証にリダイレクトを行う&lt;br /&gt;        return redirect(authorizationUrl);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;設定値などはコールバックURL以外はそのままです。&lt;br /&gt;SimpleOAuthRequestを利用して認証用のURLを作成してそのままリダイレクトをかけてます。&lt;br /&gt;※もちろんログインボタンとか作りたいなら別ですけど。&lt;br /&gt;&lt;br /&gt;これにより/indexにアクセスするとEvernoteの認可画面が表示されるはずです。&lt;br /&gt;それではコールバックURLを指定してみましょう。&lt;br /&gt;callbackを作成して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;        SimpleOAuthRequest oauthRequestor = new SimpleOAuthRequest( requestTokenUrl, consumerKey, consumerSecret, null);&lt;br /&gt;&lt;br /&gt;        String requestToken = requestScope("oauth_token");&lt;br /&gt;        String verifier     = requestScope("oauth_verifier");&lt;br /&gt;        oauthRequestor.setParameter( "oauth_token", requestToken);&lt;br /&gt;        oauthRequestor.setParameter( "oauth_verifier", verifier);&lt;br /&gt;&lt;br /&gt;        Map&lt;String, String&gt; reply = oauthRequestor.sendRequest();&lt;br /&gt;&lt;br /&gt;        String accessToken = reply.get("oauth_token"); &lt;br /&gt;        String shardId     = reply.get("edam_shard");&lt;br /&gt;        String noteStoreUrl = noteStoreUrlBase + shardId;&lt;br /&gt;&lt;br /&gt;       THttpClient noteStoreTrans    = new THttpClient(noteStoreUrl);&lt;br /&gt;       TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);&lt;br /&gt;       NoteStore.Client noteStore =&lt;br /&gt;         new NoteStore.Client(noteStoreProt, noteStoreProt);&lt;br /&gt;&lt;br /&gt;       List&lt;Notebook&gt; notebooks = noteStore.listNotebooks(accessToken);&lt;br /&gt;       for (Notebook notebook : notebooks) {&lt;br /&gt;         logger.info("Notebook: " + notebook.getName());&lt;br /&gt;       }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これもサンプルと同じ実装ですね。&lt;br /&gt;もちろん認証してなかったら～とかの処理は必要ですが、&lt;br /&gt;何やっているかを分かりやすくするため、２つのURLだけで実装してみました。&lt;br /&gt;&lt;br /&gt;ListのところはNotebookを返してたので？じゃなくしました。&lt;br /&gt;THttpClient はライブラリに存在するthriftのAPIですね。&lt;br /&gt;それらを利用してEvernoteのAPIを利用するイメージです。&lt;br /&gt;&lt;br /&gt;SimpleOAuthRequestの実装を説明しないと何やってるかわかりずらいですね。&lt;br /&gt;次回はSimpleOAuthRequestについて記述してみましょう。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1672047621748669376?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1672047621748669376/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1672047621748669376' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1672047621748669376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1672047621748669376'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote_03.html' title='Evernoteにアクセスする　その３ サンプルをシンプル編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3303493424172725595</id><published>2011-06-02T20:22:00.007+09:00</published><updated>2011-06-02T22:48:01.454+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><title type='text'>Evernoteにアクセスする　その２ OAuthアクセス編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;前回サンプルを動作させてみました。&lt;br /&gt;サンプルはOAuthの動作を見せる感じに作ってあります。&lt;br /&gt;JSPに書かれていて処理がわかりずらいのでコードを解析しながら読みやすくしていきましょう。&lt;br /&gt;&lt;br /&gt;最初の方は定数等を定義していますね。&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   private enum supportedRedirSchemas {FULL, EMBED};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;は、iframeを利用する場合の処理の分岐ですね。&lt;br /&gt;少し分かりづらいですが、基本的にindex.jspに対して、&lt;br /&gt;「action」という引数を渡して処理を行ってます。&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;getRequestTokenの処理&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Evernoteにアクセス(引数なし)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;認証後getAccessTokenの処理&lt;/li&gt;&lt;br /&gt;&lt;li&gt;AccessTokenによりlistNotebooks&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;という順序で処理を行っています。&lt;br /&gt;これはRequestTokenを準備してEvernoteにアクセスして&lt;br /&gt;認証結果をAccessTokenで取得。&lt;br /&gt;最後にAPIにアクセスしている感じです。&lt;br /&gt;&lt;br /&gt;まぁご存知「OAuth1.0」アクセスです。&lt;br /&gt;まずはgetRequestTokenによるrequestTokenの取得です。&lt;br /&gt;&lt;br /&gt;サンプルのはじめのリンクをクリックした時の処理&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;          SimpleOAuthRequest oauthRequestor =&lt;br /&gt;            new SimpleOAuthRequest(requestTokenUrl, consumerKey, consumerSecret, null);&lt;br /&gt;&lt;br /&gt;          // Set the callback URL&lt;br /&gt;          String thisUrl = request.getRequestURL().toString();&lt;br /&gt; 　String cbUrl = thisUrl.substring(0, thisUrl.lastIndexOf('/') + 1);&lt;br /&gt; 　if (redirSchema != null &amp;&amp; redirSchema.equals(supportedRedirSchemas.EMBED.toString())) {&lt;br /&gt; 　　cbUrl = cbUrl + callbackEmbedUrl;&lt;br /&gt; 　} else {&lt;br /&gt; 　　cbUrl = cbUrl + callbackUrl;&lt;br /&gt; 　}&lt;br /&gt; 　oauthRequestor.setParameter("oauth_callback", cbUrl);&lt;br /&gt;     &lt;br /&gt;          out.println("Request: " + oauthRequestor.encode());&lt;br /&gt;          Map&lt;String,String&gt; reply = oauthRequestor.sendRequest();&lt;br /&gt;          out.println("Reply: " + reply);&lt;br /&gt;          requestToken = reply.get("oauth_token");&lt;br /&gt;          session.setAttribute("requestToken", requestToken);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ここで大事なのは&lt;br /&gt;　com.evernote.oauth.consumer.SimpleOAuthRequest&lt;br /&gt;クラスです。&lt;br /&gt;&lt;br /&gt;コンストラクタではリクエストする為の引数を作っています。&lt;br /&gt;その後、iframe埋め込みかを判定して、戻ってくるURLを変更しています。&lt;br /&gt;サンプルを動作させるとわかりますがEMBEDを選んだ場合はiframeが出現して、&lt;br /&gt;callback.jspが表示され、そのiframe上で認証をかけます。&lt;br /&gt;なのでまぁその辺はあまり関係ないです。(OAuth後に呼び出すURLを変更するだけ)&lt;br /&gt;&lt;br /&gt;sendRequest()によりrequestTokenUrlにリクエストして、RequestTokenを取得しにいっています。&lt;br /&gt;戻り値のマップはResponseの値です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;その下で取得したRequestTokenでURLを作成しています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  String authorizationUrl = authorizationUrlBase + "?oauth_token=" + requestToken;&lt;br /&gt;  if (redirSchema != null &amp;&amp; redirSchema.equals(supportedRedirSchemas.EMBED.toString())) {&lt;br /&gt;   authorizationUrl = authorizationUrl + "&amp;format=microclip";&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;埋め込みの場合は少しいじってますね。&lt;br /&gt;このURL(Evernote)にアクセスする事で認可できるわけです。&lt;br /&gt;このURLが２番目のURL。&lt;br /&gt;&lt;br /&gt;JSPでまどろっこしいのですが、&lt;br /&gt;基本的にはURL生成からリダイレクトすればいきなり認証も可能ですね。&lt;br /&gt;&lt;br /&gt;そのURLにアクセスすれば&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-HS2yMgRCIA4/TeeBDGWkQUI/AAAAAAAAAL4/7itAFPxfjRw/s1600/WS000000.JPG"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 184px;" src="http://2.bp.blogspot.com/-HS2yMgRCIA4/TeeBDGWkQUI/AAAAAAAAAL4/7itAFPxfjRw/s200/WS000000.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613597350785466690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;という風にEvernoteへの認可画面(認証済なのでこういう画面ですが認証してないとログイン画面)が出ます。&lt;br /&gt;&lt;br /&gt;これに認可されると指定してあるCallbackUrlに処理がきます。&lt;br /&gt;&lt;br /&gt;コールバックで戻ってくる最初の処理がこちら。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;          requestToken = request.getParameter("oauth_token");&lt;br /&gt;          verifier = request.getParameter("oauth_verifier");&lt;br /&gt;          session.setAttribute("verifier", verifier);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ちなみに「oauth_verifier」がnullの時は認可がされなかった時になります。&lt;br /&gt;とにかくセッションに貯めてますね。。。このサンプル。&lt;br /&gt;実際使う場合はコールバックURLでRequestTokenもverifierも取得して判定すれば良いでしょう。&lt;br /&gt;&lt;br /&gt;で３番目のリンクをクリックすると&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;          // Send an OAuth message to the Provider asking to exchange the&lt;br /&gt;          // existing Request Token for an Access Token&lt;br /&gt;          SimpleOAuthRequest oauthRequestor =&lt;br /&gt;            new SimpleOAuthRequest(requestTokenUrl, consumerKey, consumerSecret, null);&lt;br /&gt;          oauthRequestor.setParameter("oauth_token",&lt;br /&gt;              (String)session.getAttribute("requestToken"));&lt;br /&gt;          oauthRequestor.setParameter("oauth_verifier", &lt;br /&gt;              (String)session.getAttribute("verifier"));&lt;br /&gt;          out.println("Request: " + oauthRequestor.encode());&lt;br /&gt;          Map&lt;String,String&gt; reply = oauthRequestor.sendRequest();&lt;br /&gt;          out.println("Reply: " + reply);&lt;br /&gt;          accessToken = reply.get("oauth_token");&lt;br /&gt;          String shardId = reply.get("edam_shard");&lt;br /&gt;          session.setAttribute("accessToken", accessToken);&lt;br /&gt;          session.setAttribute("shardId", shardId);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;この処理を行っています。&lt;br /&gt;再度SimpleOAuthRequestを利用してアクセストークンを取得しています。&lt;br /&gt;・・・まぁセッションにまた貯めてますねぇ。。。&lt;br /&gt;&lt;br /&gt;で最後にAPIにアクセスしています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;          String noteStoreUrl = noteStoreUrlBase +&lt;br /&gt;            session.getAttribute("shardId");&lt;br /&gt;&lt;br /&gt;          out.println("Listing notebooks from: " + noteStoreUrl);&lt;br /&gt;          THttpClient noteStoreTrans = new THttpClient(noteStoreUrl);&lt;br /&gt;          TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);&lt;br /&gt;          NoteStore.Client noteStore =&lt;br /&gt;            new NoteStore.Client(noteStoreProt, noteStoreProt);&lt;br /&gt;          List&lt;?&gt; notebooks = noteStore.listNotebooks(accessToken);&lt;br /&gt;&lt;br /&gt;          for (Object notebook : notebooks) {&lt;br /&gt;            out.println("Notebook: " + ((Notebook)notebook).getName());&lt;br /&gt;          }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これによりノートブック一覧が取得できます。&lt;br /&gt;ひとまずOAuthアクセスはこんな感じでできます。&lt;br /&gt;&lt;br /&gt;SimpleOAuthRequestを読んでもらえればわかりますが、&lt;br /&gt;パラメータを設定してアクセスしてあげてくれるだけです。&lt;br /&gt;&lt;br /&gt;なのでOAuthの仕組みさえわかっていれば簡単です。&lt;br /&gt;※サンプルは流れさえ押さえれば、わかるのですが&lt;br /&gt;　JSPだけでアクセスしてるのでかなり複雑な書き方になっています。&lt;br /&gt;&lt;br /&gt;OAuth1.0の解説で一番わかりやすいのはゆろよろ氏が記述している&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/yuroyoro/20100506/1273137673"&gt;OAuthプロトコルの中身をざっくり解説してみるよ&lt;/a&gt;だと思います。&lt;br /&gt;ご覧になってください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さて今回はサンプルを元にやりましたので&lt;br /&gt;次回Slim3を使ってアクセスしてみましょう！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3303493424172725595?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3303493424172725595/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3303493424172725595' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3303493424172725595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3303493424172725595'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote-oauth.html' title='Evernoteにアクセスする　その２ OAuthアクセス編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-34132097055755243</id><published>2011-06-01T21:05:00.010+09:00</published><updated>2011-06-02T20:22:29.195+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='evernote'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><title type='text'>Evernoteにアクセスする　その１ サンプル動作編</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s1600/enlogo.png"&gt;&lt;img style="float:left;cursor:pointer; cursor:hand;width: 60px; height: 60px;" src="http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s200/enlogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5613258502386671170" /&gt;&lt;/a&gt;&lt;br /&gt;少し前にメモアプリを考えていて、&lt;br /&gt;appengineに保存しようと思っていたんですけど、&lt;br /&gt;なんとなくevernoteに残そうと思い立ったのでアクセスしてみた。&lt;br /&gt;&lt;br /&gt;まず「&lt;a href="http://www.evernote.com/"&gt;http://www.evernote.com/&lt;/a&gt;」にアクセスすると&lt;br /&gt;サイト下部に「開発者の方へ」とあるのでそこをクリック。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-9k-aTL2ymn4/TeYsbw2updI/AAAAAAAAALI/3WwU6dHj4XE/s1600/WS000001.JPG"&gt;&lt;img style="margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 173px;" src="http://2.bp.blogspot.com/-9k-aTL2ymn4/TeYsbw2updI/AAAAAAAAALI/3WwU6dHj4XE/s400/WS000001.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613222841046443474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;「WebサービスAPI」の説明があるのでそこを読んでクリック&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-BeO5wOrt6bs/TeYtD0dz2bI/AAAAAAAAALQ/n0Hdpp_LV44/s1600/WS000002.JPG"&gt;&lt;img style="margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 54px;" src="http://3.bp.blogspot.com/-BeO5wOrt6bs/TeYtD0dz2bI/AAAAAAAAALQ/n0Hdpp_LV44/s200/WS000002.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613223529210436018" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;そこで入力フォームがあるので、各種入力してSUBMITを行います。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-XSW7p2Wd9rc/TeYtRKSpEFI/AAAAAAAAALY/MGnpD6MV88k/s1600/WS000003.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 200px; height: 122px;" src="http://2.bp.blogspot.com/-XSW7p2Wd9rc/TeYtRKSpEFI/AAAAAAAAALY/MGnpD6MV88k/s200/WS000003.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613223758407471186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;そこから３日程待ちます。。。(´・ω・`)&lt;br /&gt;※サンプル動かしてみてわかったのですが、&lt;br /&gt;Webとして申込むとクライアントアプリのアクセスはできません。&lt;br /&gt;おそらくクライアントアプリでWebのAPIアクセスは無理です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;すると英文でKeyとSecretが送られてきます。&lt;br /&gt;一応これはsandboxなので終わったらできあがったよーってメール送ると&lt;br /&gt;本番環境でも使えるようになるみたいです。(それは後日書くかな。。。)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さて開発に入ります。&lt;br /&gt;・・・その前にユーザを&lt;a href="https://sandbox.evernote.com/Registration.action"&gt;sandnox側で登録&lt;/a&gt;しておく必要があります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;まずは&lt;br /&gt;&lt;a href="http://www.evernote.com/about/developer/api/"&gt;http://www.evernote.com/about/developer/api/&lt;/a&gt;&lt;br /&gt;からサンプル等の入ったZIPをダウンロードしてきます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-g0IFLhsZSIE/TeZG5Y9lhPI/AAAAAAAAALg/h5HrBW1G7XA/s1600/WS000000.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 200px; height: 106px;" src="http://3.bp.blogspot.com/-g0IFLhsZSIE/TeZG5Y9lhPI/AAAAAAAAALg/h5HrBW1G7XA/s200/WS000000.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613251937331152114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;まずダウンロードしたファイルを解凍します。&lt;br /&gt;\evernote-api-1.19\sample\java\oauth\src&lt;br /&gt;がソースになります。(warもあるのでそれでもOK)&lt;br /&gt;&lt;br /&gt;java側にはOAuth用(com.evernote.oauth.consumer.SimpleOAuthRequest)のソースが存在します。&lt;br /&gt;webappにはWebアプリ用のソースが存在します。&lt;br /&gt;&lt;br /&gt;ライブラリには&lt;br /&gt;&lt;br /&gt;log4j-1.2.14.jar&lt;br /&gt;libthrift.jar&lt;br /&gt;evernote-api-1.19.jar&lt;br /&gt;&lt;br /&gt;を使ってますね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;展開したinde.jspの20行目位に&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  static final String consumerKey = "xxxxxxx";&lt;br /&gt;  static final String consumerSecret = "xxxxxxxx";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;というコードがあるのでそこをメールできたKEYとSECRETに変更する。&lt;br /&gt;これでAPIにアクセス可能になります。&lt;br /&gt;&lt;br /&gt;これで動作できるようになります。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-e_2fnvX8iuo/TeZNvzH3C4I/AAAAAAAAALw/OEENfAyRgt8/s1600/WS000000.JPG"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 188px;" src="http://3.bp.blogspot.com/-e_2fnvX8iuo/TeZNvzH3C4I/AAAAAAAAALw/OEENfAyRgt8/s200/WS000000.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5613259469136268162" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;。。。サンプルが汚かったのでちょっとまだ読んでないで動作確認のみです。&lt;br /&gt;ソース読みながらOAuthのアクセス(他と一緒の感じですけど)と&lt;br /&gt;API等を見ながらアクセスしてみようと思います。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-34132097055755243?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/34132097055755243/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=34132097055755243' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/34132097055755243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/34132097055755243'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2011/06/evernote.html' title='Evernoteにアクセスする　その１ サンプル動作編'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-uzZ3F7YpD_4/TeZM3hsy3kI/AAAAAAAAALo/XQdhjLUMtTw/s72-c/enlogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3303693835931980379</id><published>2010-11-03T14:01:00.003+09:00</published><updated>2011-06-02T20:22:10.272+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><title type='text'>GoogleAppEngineのヘッダサイズ</title><content type='html'>appengineでmixiのsimplepostのリダイレクトを作成しようとすると、&lt;br /&gt;&lt;br /&gt;「java.lang.ArrayIndexOutOfBoundsException: 4096」&lt;br /&gt;&lt;br /&gt;が発生してしまいました。&lt;br /&gt;リダイレクト時のヘッダーが長すぎるようです。&lt;br /&gt;&lt;br /&gt;mixiのsimplepostの日記は本文が全角１万文字まで&lt;br /&gt;リダイレクトが可能なのですが、&lt;br /&gt;どうもjettyの制限（現在は設定可能）やバグの部分が関係しているようです。&lt;br /&gt;&lt;br /&gt;http://jira.codehaus.org/browse/JETTY-1093&lt;br /&gt;http://jira.codehaus.org/browse/JETTY-1112&lt;br /&gt;&lt;br /&gt;http://groups.google.co.jp/group/google-appengine-java/browse_thread/thread/488d57c223b8173c?pli=1&lt;br /&gt;&lt;br /&gt;http://code.google.com/p/googleappengine/issues/detail?id=2413&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;設定を追加する可能性は低いとみて、&lt;br /&gt;直接リダイレクトせずにクライアントからJavaScriptでリダイレクトをかけようと思います。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3303693835931980379?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3303693835931980379/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3303693835931980379' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3303693835931980379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3303693835931980379'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/11/googleappengine.html' title='GoogleAppEngineのヘッダサイズ'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5777486532591389722</id><published>2010-10-03T16:01:00.005+09:00</published><updated>2010-10-03T17:56:50.234+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mixi'/><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><title type='text'>mixi Graph APIの認証</title><content type='html'>http://developer.mixi.co.jp/connect/mixi_graph_api/api_auth&lt;br /&gt;&lt;br /&gt;にある認可方法のJava実装の説明です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;まず、使用するには開発者登録を行い&lt;br /&gt;https://sap.mixi.jp/&lt;br /&gt;で新規サービス追加を行っておく必要があります。&lt;br /&gt;&lt;br /&gt;まずURLを作って以下にリダイレクトします。&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        String endPoint = "https://mixi.jp/connect_authorize.pl";&lt;br /&gt;     &lt;br /&gt;        String url = endPoint + "?response_type=code";&lt;br /&gt;        &lt;br /&gt;        String key = "キー";&lt;br /&gt;        String scope = "r_profile";&lt;br /&gt;        String display = "pc";&lt;br /&gt;&lt;br /&gt;        url += "&amp;client_id=" + key;&lt;br /&gt;        url += "&amp;scope=" + scope;&lt;br /&gt;        url += "&amp;display=" + display;&lt;br /&gt; &lt;br /&gt;        return redirect(url);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;※redirect関数はslim3の関数です。&lt;br /&gt;　このURLにリダイレクトすればOKです。&lt;br /&gt;&lt;br /&gt;するとmixiの認証画面に飛びます。&lt;br /&gt;許可がおりるとサービスを作成した際のURLに遷移します。&lt;br /&gt;キーにはサービス作成後に生成される「Consumer Key」を指定しておきます。&lt;br /&gt;r_profileの指定は使用するサービスによって変更します。&lt;br /&gt;&lt;br /&gt;認可手順のところに記述してありますね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;        //コードを取得&lt;br /&gt;        String token = requestScope("code");&lt;br /&gt;        String endPoint = "https://secure.mixi-platform.com/2/token";&lt;br /&gt;        String args = "";&lt;br /&gt;        &lt;br /&gt;        String key = "サービスのKEYを指定";&lt;br /&gt;        String scret = "サービスのSECRETを指定";&lt;br /&gt;        String uri = "http://mixi.latest.secondarykey.appspot.com/callback";&lt;br /&gt;&lt;br /&gt;        args += "grant_type=authorization_code";&lt;br /&gt;        args += "&amp;client_id=" + key;&lt;br /&gt;        args += "&amp;client_secret=" + scret;&lt;br /&gt;        args += "&amp;code=" + token;&lt;br /&gt;        args += "&amp;redirect_uri=" + uri;&lt;br /&gt;&lt;br /&gt;        String json = post(endPoint,args);&lt;br /&gt;        Map&lt;String,String&gt; jsonMap = createJsonMap(json);&lt;br /&gt;&lt;br /&gt;        String email = "メールアドレス";&lt;br /&gt;        String url = "http://api.mixi-platform.com/2/search/people?q=" + email;&lt;br /&gt;        //String url = "http://api.mixi-platform.com/2/people/@me/@self";&lt;br /&gt; &lt;br /&gt;        get(url,jsonMap.get("access_token"));&lt;br /&gt;  &lt;br /&gt;        return forward("oauth.jsp");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;飛んできたURLの引数で「code」がきますので&lt;br /&gt;それを元にURLを作成します。&lt;br /&gt;「redirect_uri」は、、、、何設定するのかな？多分合ってない気がする。。。&lt;br /&gt;それをPOSTで投げます。&lt;br /&gt;post()はオリジナルでHttpURLConnectionを利用して投げています。&lt;br /&gt;&lt;br /&gt;その戻り値はjsonで戻ってきます。&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;{"refresh_token":"a4a634845360522a85cc030e043cb869d2536aa",&lt;br /&gt;"expires_in":900,&lt;br /&gt;"access_token":"8b17d199e43c879c1a015019cf55d9ecd0e2503",&lt;br /&gt;"scope":"r_profile"}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;こういう感じのjsonです。&lt;br /&gt;&lt;br /&gt;この「access_token」を利用して、利用したいサービスにサクセスします。&lt;br /&gt;ここではPeople lookup APIにアクセスして、&lt;br /&gt;マイミクの情報を取得しています。&lt;br /&gt;&lt;br /&gt;get()ではHttpURLConnectionに対して&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;connection.setRequestProperty("Authorization", "OAuth " + oauth);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と認証情報にアクセストークンを指定する必要があります。&lt;br /&gt;&lt;br /&gt;このブログを記述している時点では&lt;br /&gt;メールアドレスによる検索は認可されたユーザの&lt;br /&gt;マイミクでないと検索できないようで、404を返してきていました。&lt;br /&gt;テスト時に自分のメールアドレスを検索してて&lt;br /&gt;「なんで４０４なんじゃー！」って思っていましたが、仕様のようです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5777486532591389722?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5777486532591389722/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5777486532591389722' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5777486532591389722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5777486532591389722'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/10/mixi-graph-api.html' title='mixi Graph APIの認証'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4861158454343652082</id><published>2010-04-24T16:51:00.005+09:00</published><updated>2010-04-25T13:58:39.749+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='帳票'/><category scheme='http://www.blogger.com/atom/ns#' term='don-gabacho'/><title type='text'>ExCellaで帳票</title><content type='html'>最近ExCellaを触ってます。&lt;br /&gt;&lt;br /&gt;実際はGoogleAppEngineでサービスを目標にしていて、&lt;br /&gt;一部ExCella自体をいじりながらの開発です。&lt;br /&gt;一応Excelが出力できたのでブログを起こしておきましょう。&lt;br /&gt;&lt;br /&gt;やっぱりGAEでネックになるのは&lt;br /&gt;ファイルシステムとの問題です。&lt;br /&gt;&lt;br /&gt;まず、core側にあるExporterのTextExporterとWorkbookExporterを&lt;br /&gt;削除しました。&lt;br /&gt;単純にいうとまずはスモールスタートの為に&lt;br /&gt;ExcelOutputStreamExporterのみをサポートする事にしました。&lt;br /&gt;&lt;br /&gt;本来はXLS周りを使用してみたかったのですが&lt;br /&gt;POI自体(ExCella内部で使っている)が、テンプレートの読み込み途中で&lt;br /&gt;xmlファイルを保存している感じがあって、落ちてしまいます。&lt;br /&gt;&lt;br /&gt;なので一旦はExcelに集中。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ExCella自体がファイルへの出力重視的な実装になっていて&lt;br /&gt;親クラスで「出力ファイル名」等を持つことが多いみたいなので&lt;br /&gt;ひとまずそのあたりを削除。&lt;br /&gt;エラーになるところを潰していくような作業になりました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・実際は根本の部分でOutputStreamの設定する仕組みに変えるべきだと&lt;br /&gt;。。。ブログ書いてる途中に思いまして、ちょっと実装しなおそうかな？&lt;br /&gt;って思っています。&lt;br /&gt;&lt;br /&gt;現状だと&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        ByteArrayInputStream inStream = new ByteArrayInputStream(template.getBytes());&lt;br /&gt;        &lt;br /&gt;        ReportBook outputBook = new ReportBook(inStream,ExcelOutputStreamExporter.FORMAT_TYPE);&lt;br /&gt;        &lt;br /&gt;        ReportSheet outputSheet = new ReportSheet("テンプレート","請求書");&lt;br /&gt;&lt;br /&gt;        outputBook.addReportSheet(outputSheet);&lt;br /&gt;&lt;br /&gt;        ByteArrayOutputStream stream = new ByteArrayOutputStream();&lt;br /&gt;        ReportProcessor reportProcessor = new ReportProcessor();&lt;br /&gt;        stream = reportProcessor.process(outputBook);&lt;br /&gt;&lt;br /&gt;        response.setHeader("Content-Disposition","attachment; filename=excel.xls");&lt;br /&gt;        response.setContentType("application/msexcel");&lt;br /&gt;        response.setContentLength(stream.toByteArray().length);&lt;br /&gt; &lt;br /&gt;        OutputStream out = new BufferedOutputStream(response.getOutputStream());&lt;br /&gt;        out.write(stream.toByteArray());&lt;br /&gt;        out.close();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;こんな感じで動作します。&lt;br /&gt;&lt;br /&gt;GAEでの動作なのでinputStreamは&lt;br /&gt;テンプレート用のファイルをDataStore上に溜め込んでいます。&lt;br /&gt;&lt;br /&gt;コードネームはdon-gabachoです。&lt;br /&gt;あー。。。もういっかい書き直して&lt;br /&gt;全部書き留めないとなぁ。。。&lt;br /&gt;&lt;br /&gt;※2010/4/25 でリファクタリング完成&lt;br /&gt;http://code.google.com/p/don-gabacho/wiki/ExCella?ts=1272171109&amp;updated=ExCella&lt;br /&gt;streamをBookから引き渡すように変更しています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4861158454343652082?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4861158454343652082/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4861158454343652082' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4861158454343652082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4861158454343652082'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/04/excella.html' title='ExCellaで帳票'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6194842272128801811</id><published>2010-03-26T00:09:00.000+09:00</published><updated>2010-03-26T00:13:39.153+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Assets.swf'/><category scheme='http://www.blogger.com/atom/ns#' term='Cursor'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>カーソルの変更</title><content type='html'>[Embed(source=&amp;quot;Assets.swf&amp;quot;,&amp;nbsp;symbol=&amp;quot;mx.skins.cursor.hogehoge&amp;quot;)]&lt;br /&gt;&lt;br /&gt;private&amp;nbsp;var&amp;nbsp;_hogehogeClass:Class;&lt;br /&gt;&lt;br /&gt;こういう感じみたいですけど、&lt;br /&gt;Assets.swfにあるイメージの一覧が欲しい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6194842272128801811?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6194842272128801811/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6194842272128801811' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6194842272128801811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6194842272128801811'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/03/blog-post.html' title='カーソルの変更'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-2901466994815664394</id><published>2010-03-14T19:14:00.005+09:00</published><updated>2010-03-24T08:13:42.629+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='FlashLite'/><category scheme='http://www.blogger.com/atom/ns#' term='引数埋込'/><title type='text'>FlashLiteで引数を埋め込む(Java)</title><content type='html'>&lt;div&gt;先日友人がFlashLiteでの引数埋込に苦戦してた。&lt;/div&gt;&lt;div&gt;携帯で個体識別番号などの引数を元にFlashを書き換えたいらしい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://nakagami.blog.so-net.ne.jp/2010-02-02"&gt;ここ&lt;/a&gt;に方式はあるんだけど、、、って事でJava化してみた。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt; public static String inCode  = "utf-8"; &lt;br /&gt;    public static String outCode = "shift-jis"; &lt;br /&gt;    /**&lt;br /&gt;     * FlashLite への引数の埋込&lt;br /&gt;     * @param oldFile&lt;br /&gt;     * @param argMap&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public static byte[] createArgEmbedSwf(byte[] oldFile, Map&amp;lt;String, String&amp;gt; argMap) {&lt;br /&gt;        &lt;br /&gt;        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();&lt;br /&gt;        //rectbitの３ビット右シフト&lt;br /&gt;        byte rectbit = (byte)((int)oldFile[8] / 8);&lt;br /&gt;&lt;br /&gt;        //$headlen = ceil(((( 8 - (($rb*4+5)&amp;7) )&amp;7)+ $rb*4 + 5 )/8) + 12 + 5;&lt;br /&gt;        double dblHead = ((( 8 - ((rectbit*4+5)&amp;7) )&amp;7)+ rectbit*4 + 5 ) / 8;&lt;br /&gt;        //ヘッダ長を取得&lt;br /&gt;        int headLen = (int)Math.ceil(dblHead) + 12 + 5;&lt;br /&gt;&lt;br /&gt;        //引数部分の作成&lt;br /&gt;        byte[] doActionTag = createArg(argMap);&lt;br /&gt;&lt;br /&gt;        //$newsize = $oldsize+strlen($doactiontag);&lt;br /&gt;        int oldSize = oldFile.length;&lt;br /&gt;        //新しいサイズを取得&lt;br /&gt;        int newSize = oldSize + doActionTag.length;&lt;br /&gt;&lt;br /&gt;        //新しいヘッダを作成&lt;br /&gt;        byte[] newHeader = createHeader(oldFile,headLen,newSize);&lt;br /&gt;        //ヘッダ後のデータを取得&lt;br /&gt;        byte[] tail = createTail(oldFile,headLen);  &lt;br /&gt;        try {&lt;br /&gt;            //タグ部分の書き込み&lt;br /&gt;            byteStream.write(newHeader);&lt;br /&gt;            byteStream.write(doActionTag);&lt;br /&gt;            byteStream.write(tail);&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;        return byteStream.toByteArray();&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * 新しいヘッダーの作成&lt;br /&gt;     * @param buf&lt;br /&gt;     * @param headLen&lt;br /&gt;     * @param newSize&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static byte[] createHeader(byte[] buf, int headLen, int newSize) {&lt;br /&gt;        &lt;br /&gt;        //ヘッダの位置を取得&lt;br /&gt;        //$head = $headtmp.fread($fr,$headlen-9);&lt;br /&gt;        //$newhead = substr($head,0,4).h32($newsize).substr($head,8);&lt;br /&gt;&lt;br /&gt;        byte[] newHeader   = new byte[headLen];&lt;br /&gt;        //４バイトでint値をバイトに変換&lt;br /&gt;        byte[] newHeadSize = changeBytes(newSize,4);&lt;br /&gt;        //長さを変更&lt;br /&gt;        for ( int cnt = 0; cnt &amp;lt; headLen; ++cnt ) {&lt;br /&gt;            if ( cnt &amp;gt;= 4 &amp;&amp; cnt &amp;lt; 8 ) {&lt;br /&gt;                newHeader[cnt] = newHeadSize[cnt-4];&lt;br /&gt;            } else {&lt;br /&gt;                newHeader[cnt] = buf[cnt];&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return newHeader;&lt;br /&gt;    }&lt;br /&gt;    //3f 03 18 00 00 00 96 08&lt;br /&gt;    //00 00 6d 79 6e 61 6d 65&lt;br /&gt;    //00 96 08 00 00 74 61 77&lt;br /&gt;    //74 61 77 00 1d 00&lt;br /&gt;    &lt;br /&gt;    //3f 03 -- タグはじまり, Type=12(DoActionタグ)&lt;br /&gt;    //18 00 00 00 -- タグ長さ 0x18 = 24 byte(ここからタグ終わりまでの長さ)&lt;br /&gt;&lt;br /&gt;    //96 -- ActionPush&lt;br /&gt;    //08 00 -- Pushするものの長さ, 8 byte&lt;br /&gt;    //00 -- Pushするものは文字列&lt;br /&gt;    //6d 79 6e 61 6d 65 00 -- "myname" (ord("m")=109=0x6d など。00は文字列終端を意味)&lt;br /&gt;&lt;br /&gt;    //96 -- ActionPush&lt;br /&gt;    //08 00 -- Pushするものの長さ&lt;br /&gt;    //00　 -- Pushするものは文字列&lt;br /&gt;    //74 61 77 74 61 77 00 -- "tawtaw"&lt;br /&gt;&lt;br /&gt;    //1d -- ActionSetVariable&lt;br /&gt;    //00 -- タグ終わり&lt;br /&gt;    /**&lt;br /&gt;     * タグ用のバイトを作成&lt;br /&gt;     * @param argMap&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static byte[] createArg(Map&amp;lt;String, String&amp;gt; argMap) {&lt;br /&gt;&lt;br /&gt;        List&amp;lt;Byte&amp;gt; byteList = new ArrayList&amp;lt;Byte&amp;gt;();&lt;br /&gt;&lt;br /&gt;        //タグの始まりを設定&lt;br /&gt;        //$tag = "\x3f\x03";&lt;br /&gt;        byteList.add((byte)0x3f);&lt;br /&gt;        byteList.add((byte)0x03);&lt;br /&gt;&lt;br /&gt;        //タグの長さを取得&lt;br /&gt;        //$taglen = calctaglen($dataarray);&lt;br /&gt;        int tagLen = calcArgLen(argMap);&lt;br /&gt;&lt;br /&gt;        //$tag .= h32($taglen);&lt;br /&gt;        add(changeBytes(tagLen,4),byteList);&lt;br /&gt;&lt;br /&gt;        //foreach($dataarray as $key =&amp;gt; $value)&lt;br /&gt;        Iterator&amp;lt;Entry&amp;lt;String,String&amp;gt;&amp;gt; itr = argMap.entrySet().iterator();&lt;br /&gt;        //キー数回繰り返す&lt;br /&gt;        while ( itr.hasNext() ) {&lt;br /&gt;            Entry&amp;lt;String,String&amp;gt; entry = itr.next();&lt;br /&gt;&lt;br /&gt;            //$tag .= "\x96".h16(strlen($key)+2)."\x00".$key."\x00";&lt;br /&gt;            addString(entry.getKey(),byteList);&lt;br /&gt;            //$tag .= "\x96".h16(strlen($value)+2)."\x00".$value."\x00";&lt;br /&gt;            addString(entry.getValue(),byteList);&lt;br /&gt;&lt;br /&gt;            //$tag .= "\x1d";&lt;br /&gt;            byteList.add((byte)0x1d);&lt;br /&gt;        }&lt;br /&gt;        //終端のバイトを設定&lt;br /&gt;        //$tag .= "\x00";&lt;br /&gt;        byteList.add((byte)0x00);&lt;br /&gt;        return change(byteList);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * 引数の長さを取得&lt;br /&gt;     * @param argMap 引数用のマップ&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static int calcArgLen(Map&amp;lt;String, String&amp;gt; argMap) {&lt;br /&gt;        int rtn = 0;&lt;br /&gt;        Iterator&amp;lt;Entry&amp;lt;String,String&amp;gt;&amp;gt; itr = argMap.entrySet().iterator();&lt;br /&gt;        //キー数回繰り返す&lt;br /&gt;        while ( itr.hasNext() ) {&lt;br /&gt;            Entry&amp;lt;String,String&amp;gt; entry = itr.next();&lt;br /&gt;            String key;&lt;br /&gt;            String value;&lt;br /&gt;            try {&lt;br /&gt;                key = new String(entry.getKey().getBytes(inCode),outCode);&lt;br /&gt;                value = new String(entry.getValue().getBytes(inCode),outCode);&lt;br /&gt;            } catch (UnsupportedEncodingException e) {&lt;br /&gt;                throw new RuntimeException("文字列コード変換失敗",e);&lt;br /&gt;            }&lt;br /&gt;            //それぞれのバイト数とタグ用の11バイトを追加&lt;br /&gt;            try {&lt;br /&gt;                rtn += (key.getBytes(outCode).length + value.getBytes(outCode).length + 11);&lt;br /&gt;            } catch (UnsupportedEncodingException e) {&lt;br /&gt;                throw new RuntimeException("文字列コード変換失敗",e);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        //終端分を追加&lt;br /&gt;        return rtn + 1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * ヘッダの後ろを取得&lt;br /&gt;     * @param buf&lt;br /&gt;     * @param oldSize&lt;br /&gt;     * @param headLen&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static byte[] createTail(byte[] buf,int headLen) {&lt;br /&gt;&lt;br /&gt;        int oldSize = buf.length - headLen;&lt;br /&gt;        byte[] tail = new byte[oldSize];&lt;br /&gt;        int idx = 0;&lt;br /&gt;        //$tail = fread($fr, $oldsize-$headlen);&lt;br /&gt;        for ( int cnt = headLen; cnt &amp;lt; buf.length; ++cnt ) {&lt;br /&gt;            tail[idx] = buf[cnt];&lt;br /&gt;            ++idx;&lt;br /&gt;        }&lt;br /&gt;        return tail;&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * リストから配列に変更&lt;br /&gt;     * @param byteList&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static byte[] change(List&amp;lt;Byte&amp;gt; byteList) {&lt;br /&gt;        byte[] rtnByte = new byte[byteList.size()];&lt;br /&gt;        int idx = 0;&lt;br /&gt;        for ( Byte b : byteList ) {&lt;br /&gt;            rtnByte[idx] = b;&lt;br /&gt;            ++idx;&lt;br /&gt;        }&lt;br /&gt;        return rtnByte;&lt;br /&gt;    } &lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * バイト配列への変更&lt;br /&gt;     * @param i&lt;br /&gt;     * @param leng&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    private static byte[] changeBytes( int i ,int leng){&lt;br /&gt;        byte[] b = new byte[leng] ;&lt;br /&gt;        if ( leng &amp;gt; 4) {&lt;br /&gt;            b[3] = (byte)((i &amp;gt;&amp;gt;&amp;gt; 24 ) &amp; 0xFF);&lt;br /&gt;        }&lt;br /&gt;        if ( leng &amp;gt; 3) {&lt;br /&gt;            b[2] = (byte)((i &amp;gt;&amp;gt;&amp;gt; 16 ) &amp; 0xFF);&lt;br /&gt;        }&lt;br /&gt;        if ( leng &amp;gt; 2) {&lt;br /&gt;            b[1] = (byte)((i &amp;gt;&amp;gt;&amp;gt;  8 ) &amp; 0xFF);&lt;br /&gt;        }&lt;br /&gt;        if ( leng &amp;gt; 1) {&lt;br /&gt;            b[0] = (byte)((i &amp;gt;&amp;gt;&amp;gt;  0 ) &amp; 0xFF);&lt;br /&gt;        }&lt;br /&gt;        return b;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * リストへの追加&lt;br /&gt;     */&lt;br /&gt;    private static void add(byte[] byteArray,List&amp;lt;Byte&amp;gt; byteList) {&lt;br /&gt;        for ( byte b : byteArray ) {&lt;br /&gt;            byteList.add(b);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * 文字列の追加&lt;br /&gt;     * @param key&lt;br /&gt;     * @param byteList&lt;br /&gt;     */&lt;br /&gt;    private static void addString(String key, List&amp;lt;Byte&amp;gt; byteList) {&lt;br /&gt;        &lt;br /&gt;        String tmp = null;&lt;br /&gt;        try {&lt;br /&gt;            tmp = new String(key.getBytes(inCode),outCode);&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException("文字列変換失敗",e);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //$tag .= "\x96".h16(strlen($key)+2)."\x00".$key."\x00";&lt;br /&gt;        byteList.add((byte)0x96);&lt;br /&gt;        //文字列数を設定&lt;br /&gt;        byte[] lengByte;&lt;br /&gt;        try {&lt;br /&gt;            lengByte = changeBytes(tmp.getBytes(outCode).length + 2,2);&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException("文字列変換失敗",e);&lt;br /&gt;        }&lt;br /&gt;        add(lengByte,byteList);&lt;br /&gt;&lt;br /&gt;        byteList.add((byte)0x00);&lt;br /&gt;        //文字列を設定&lt;br /&gt;        try {&lt;br /&gt;            add(tmp.getBytes(outCode),byteList);&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException("文字列変換失敗",e);&lt;br /&gt;        }&lt;br /&gt;        byteList.add((byte)0x00);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;byteのつなげ方とかが独自で、少ない時間での実装なので何か良い方法があるかも。&lt;/div&gt;&lt;div&gt;byte[]での変換に終わってるのは、GAE上での動作確認をしたかったからです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;blob型で保存して動的に変更させる事に成功しました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;        byte[] newFile = FlashUtil.createArgEmbedSwf(targetFile.getBytes() , argMap);&lt;br /&gt;        &lt;br /&gt;        try {&lt;br /&gt;            response.setContentType("application/x-shockwave-flash");&lt;br /&gt;            OutputStream out =&lt;br /&gt;                new BufferedOutputStream(response.getOutputStream());&lt;br /&gt;            try {&lt;br /&gt;                out.write(newFile);&lt;br /&gt;            } finally {&lt;br /&gt;                out.flush();&lt;br /&gt;                out.close();&lt;br /&gt;            }&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            ThrowableUtil.wrapAndThrow(e);&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;こんな感じかな？&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;日本語文字化けしちゃうけど、、、、まぁ方式がわかれば解決するでしょう。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-2901466994815664394?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/2901466994815664394/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=2901466994815664394' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2901466994815664394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2901466994815664394'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/03/flashlitejava.html' title='FlashLiteで引数を埋め込む(Java)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7010940269855811044</id><published>2010-03-02T22:49:00.013+09:00</published><updated>2010-12-11T12:22:19.029+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Slim3でクラウド開発を始める。その４</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3.html"&gt;第一弾&lt;/a&gt;、&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3_22.html"&gt;第二弾&lt;/a&gt;、&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3_27.html"&gt;第三弾&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;第二弾をやってから第一弾をやらないと、&lt;/div&gt;&lt;div&gt;アノテーションのところがプロジェクト名に依存しているので&lt;/div&gt;&lt;div&gt;大変な事になりそう(&gt;_&lt;)すみません。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;今回はGoogleAppEngineへのデプロイです。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;GooglePluginを入れると左上に以下のアイコンが出ます。&lt;/div&gt;&lt;div&gt;それをポチッとな。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/S40YJzT6XcI/AAAAAAAAAI8/EXAD1awRjno/s1600-h/WS000000.JPG"&gt;&lt;img src="http://1.bp.blogspot.com/_wlXf9TOPv20/S40YJzT6XcI/AAAAAAAAAI8/EXAD1awRjno/s400/WS000000.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5444034081232412098" style="cursor: pointer; width: 105px; height: 73px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;するとデプロイの画面がでますので、&lt;/div&gt;&lt;div&gt;プロジェクトを選択して、管理者のメールアドレスとパスワードを入力します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wlXf9TOPv20/S40YMoQoASI/AAAAAAAAAJE/nQOWivU5NnQ/s1600-h/WS000002.JPG"&gt;&lt;img src="http://2.bp.blogspot.com/_wlXf9TOPv20/S40YMoQoASI/AAAAAAAAAJE/nQOWivU5NnQ/s400/WS000002.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5444034129805443362" style="cursor: pointer; width: 400px; height: 112px; " /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;画像では切れていますが、SDKの設定があるのでそこをクリック！&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/S40YQGWz5lI/AAAAAAAAAJM/lVAJzvj_kDA/s1600-h/WS000003.JPG"&gt;&lt;img src="http://3.bp.blogspot.com/_wlXf9TOPv20/S40YQGWz5lI/AAAAAAAAAJM/lVAJzvj_kDA/s400/WS000003.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5444034189424059986" style="cursor: pointer; width: 281px; height: 93px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;出てきた画面にGoogleAppEngineにアプリケーションを登録した際の&lt;/div&gt;&lt;div&gt;IDを入力します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;これで設定は完了です。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;デプロイしたらURLにアクセスしてください。&lt;/div&gt;&lt;div&gt;おそらくアプリケーションが表示されている。。。。はずです。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7010940269855811044?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7010940269855811044/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7010940269855811044' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7010940269855811044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7010940269855811044'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/03/slim3.html' title='Slim3でクラウド開発を始める。その４'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wlXf9TOPv20/S40YJzT6XcI/AAAAAAAAAI8/EXAD1awRjno/s72-c/WS000000.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3898010925149349445</id><published>2010-02-27T10:31:00.013+09:00</published><updated>2010-12-11T12:22:52.796+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Slim3でクラウド開発を始める。その３</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3.html"&gt;第一弾&lt;/a&gt;、&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3_22.html"&gt;第二弾&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;そういえば少し前にGAEがDataNucleusを使ってるので&lt;/div&gt;&lt;div&gt;それを使って、HSQLDBにつなげた事もありました(&gt;_&lt;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;で本題です。&lt;/div&gt;&lt;div&gt;Slim3は同時にテストも出力してくれます。&lt;/div&gt;&lt;div&gt;なのでその設定をします。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;まずプロジェクトを選択して、設定を行います。&lt;/div&gt;&lt;div&gt;その後、Javaのコードスタイル、インポートの編成を選択して&lt;/div&gt;&lt;div&gt;プロジェクト特有の設定を行います。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/S4h6X6exi4I/AAAAAAAAAHc/HOUZNfQd9xc/s1600-h/WS000003.JPG"&gt;&lt;img src="http://3.bp.blogspot.com/_wlXf9TOPv20/S4h6X6exi4I/AAAAAAAAAHc/HOUZNfQd9xc/s400/WS000003.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442734700931156866" style="cursor: pointer; width: 371px; height: 140px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(java.lang.Math.*)に必要なインポート数を「１」に設定します。&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/S4h6VfGjdxI/AAAAAAAAAHU/7b6eiI9lq0o/s1600-h/WS000002.JPG"&gt;&lt;img src="http://3.bp.blogspot.com/_wlXf9TOPv20/S4h6VfGjdxI/AAAAAAAAAHU/7b6eiI9lq0o/s400/WS000002.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442734659222075154" style="cursor: pointer; width: 400px; height: 55px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;終わったら画面を閉じて「ウィンドウ」から「設定」を選択します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6eEaxutI/AAAAAAAAAHk/g-XiIGq0HAw/s1600-h/WS000004.JPG"&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6eEaxutI/AAAAAAAAAHk/g-XiIGq0HAw/s400/WS000004.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442734806677961426" style="cursor: pointer; width: 296px; height: 250px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Javaのエディタにコンテンツ・アシストがあります。&lt;/div&gt;&lt;div&gt;そこにお気に入りがあるので選択して&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/S4h6l0S332I/AAAAAAAAAHs/fVMWUkbSPRw/s1600-h/WS000005.JPG"&gt;&lt;img src="http://1.bp.blogspot.com/_wlXf9TOPv20/S4h6l0S332I/AAAAAAAAAHs/fVMWUkbSPRw/s400/WS000005.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442734939788795746" style="cursor: pointer; width: 200px; height: 177px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;以下を追加します。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;org.hamcrest.CoreMatchers&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;org.junit.Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;org.junit.matchers.JUnitMatchers&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6rU9Qn_I/AAAAAAAAAH0/Z5SmF5PqBj4/s1600-h/WS000006.JPG"&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6rU9Qn_I/AAAAAAAAAH0/Z5SmF5PqBj4/s400/WS000006.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442735034455859186" style="cursor: pointer; width: 382px; height: 100px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;で「一般」を選択すると「ワークスペース」があります。&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/S4h6wFqGfmI/AAAAAAAAAH8/z4LBFj3fCvw/s1600-h/WS000007.JPG"&gt;&lt;img src="http://1.bp.blogspot.com/_wlXf9TOPv20/S4h6wFqGfmI/AAAAAAAAAH8/z4LBFj3fCvw/s400/WS000007.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442735116248317538" style="cursor: pointer; width: 152px; height: 244px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;そこに「自動的にリフレッシュ」がありますんで&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6yj2L-dI/AAAAAAAAAIE/9mtJODsDbKQ/s1600-h/WS000008.JPG"&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4h6yj2L-dI/AAAAAAAAAIE/9mtJODsDbKQ/s400/WS000008.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442735158711810514" style="cursor: pointer; width: 212px; height: 47px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;選択してください。&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3898010925149349445?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3898010925149349445/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3898010925149349445' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3898010925149349445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3898010925149349445'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/slim3_27.html' title='Slim3でクラウド開発を始める。その３'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wlXf9TOPv20/S4h6X6exi4I/AAAAAAAAAHc/HOUZNfQd9xc/s72-c/WS000003.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4079177256861483793</id><published>2010-02-22T07:45:00.008+09:00</published><updated>2010-12-11T12:23:10.899+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Slim3でクラウド開発を始める。その２</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4aVeNm33pI/AAAAAAAAAGo/WG9OoQhwsLM/s1600-h/WS000001.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://secondarykey.blogspot.com/2010/02/slim3.html"&gt;第一弾&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;さぁ第二弾です。&lt;br /&gt;いよいよSlim3 RC1が近づいて参りました。&lt;br /&gt;今回はsllim3-blankの名称を変更したい時の話をします。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://2.bp.blogspot.com/_wlXf9TOPv20/S4aT0qin0fI/AAAAAAAAAGg/F-mvZNq0euw/s320/WS000000.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442199732705808882" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 84px; " /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;/span&gt;まずプロジェクトで右クリックします。&lt;/div&gt;&lt;div&gt;その後リファクタを選んで、名前変更を選択します。&lt;/div&gt;&lt;div&gt;もしくはプロジェクトを選択して、F2でもOK。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;出てきたボックスに対して、&lt;/div&gt;&lt;div&gt;自分の好きな名前（任意）を書きます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;するとプロジェクト名が変わります。&lt;/div&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4aVeNm33pI/AAAAAAAAAGo/WG9OoQhwsLM/s320/WS000001.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5442201546005143186" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 85px; " /&gt;&lt;div&gt;その後、build.xmlを選択して、&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wlXf9TOPv20/S4aT0qin0fI/AAAAAAAAAGg/F-mvZNq0euw/s1600-h/WS000000.JPG"&gt;&lt;/a&gt;nameを変更します。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;こんな感じですかね？&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;第三弾に続く。&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4079177256861483793?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4079177256861483793/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4079177256861483793' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4079177256861483793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4079177256861483793'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/slim3_22.html' title='Slim3でクラウド開発を始める。その２'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wlXf9TOPv20/S4aT0qin0fI/AAAAAAAAAGg/F-mvZNq0euw/s72-c/WS000000.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-176059165473066699</id><published>2010-02-22T07:25:00.008+09:00</published><updated>2010-02-22T07:40:37.058+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GoogleAnalytics'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>FlexでGoogleAnalytics</title><content type='html'>&lt;div&gt;Flexでサービスを作成していましたが、&lt;/div&gt;&lt;div&gt;HTMLの呼び出ししかアクセス解析ができてなくて&lt;/div&gt;&lt;div&gt;ViewStack化しているような位置のアクセス解析ができてなかったので&lt;/div&gt;&lt;div&gt;アクセスログを取りたいなぁ。。。って思ってたら&lt;/div&gt;&lt;div&gt;「gaforflash」たるものを見つけました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(85, 26, 139); -webkit-text-decorations-in-effect: underline; "&gt;&lt;a href="http://code.google.com/p/gaforflash/downloads/list"&gt;http://code.google.com/p/gaforflash/downloads/list&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ダウンロードしたファイルのなかに[lib/analytics.swc]がありますので&lt;/div&gt;&lt;div&gt;ライブラリに追加してあげます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Flashで使う場合はもう一個の「lib/analytics_flash.swc」を&lt;/div&gt;&lt;div&gt;使うみたいですね。&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;  private static var tracker:AnalyticsTracker = null;&lt;br /&gt;  public static function initTracker(object:DisplayObject):void {&lt;br /&gt;   if (tracker == null) {&lt;br /&gt;   tracker = new GATracker(object, "UA-?????-??", "AS3");&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  public static function viewPage(pageUrl:String):void {&lt;br /&gt;   if ( tracker == null ) return;&lt;br /&gt;    tracker.trackPageview(pageUrl);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;巷に落ちてるサンプルだと、常にnewしているようでしたが、&lt;/div&gt;&lt;div&gt;なんか勿体なかったので、Singletonパターンで作成しておいて&lt;/div&gt;&lt;div&gt;viewPage()でURLを設定する形を行いました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;コンストラクタの第四引数に「true」を設定してあげたら&lt;/div&gt;&lt;div&gt;デバッグモードで動作して、アクセスを確認できるみたいです。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-176059165473066699?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/176059165473066699/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=176059165473066699' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/176059165473066699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/176059165473066699'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/flexgoogleanalytics.html' title='FlexでGoogleAnalytics'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6387768862442697309</id><published>2010-02-21T12:25:00.013+09:00</published><updated>2010-12-11T12:24:46.145+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Slim3でクラウド開発を始める</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/S4CvoeI1thI/AAAAAAAAAGY/m-j4sC4xeeM/s1600-h/WS000005.JPG"&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;Slim3に飛びついたのは、GoogleAppEngineで&lt;br /&gt;ファイルのアップロードができるし、Strutsだったから&lt;br /&gt;飛びついたのを覚えています。&lt;br /&gt;現在はStrutsには対応していませんが&lt;/span&gt;&lt;div&gt;MVCが整った軽量なフレームワークです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;使用するにはeclipseとGoogle Plugin for eclipseが必要です。&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CpaEZ91sI/AAAAAAAAAFw/p3C7ZSfnNic/s1600-h/WS000000.JPG"&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CpaEZ91sI/AAAAAAAAAFw/p3C7ZSfnNic/s320/WS000000.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440534615187904194" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 237px; height: 117px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CpaEZ91sI/AAAAAAAAAFw/p3C7ZSfnNic/s1600-h/WS000000.JPG"&gt;&lt;/a&gt;&lt;/span&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;「http://slim3.googlecode.com/svn」&lt;br /&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CpaEZ91sI/AAAAAAAAAFw/p3C7ZSfnNic/s1600-h/WS000000.JPG"&gt;&lt;/a&gt;[slim3-blank]をチェックアウトします。&lt;br /&gt;※Downloadからblankをダウンロードしてインポートしても&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;　　開発は開始できます。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;現在SDKは1.3.1のようですね。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;作成されたプロジェクトで右クリックを押して、&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CrxPcBiPI/AAAAAAAAAF4/CJaBi_rXYoE/s320/WS000001.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440537212309571826" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 46px; " /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;コンパイラのアノテーションのファクトリーパスを選択します。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;右の画像の画面を出してjarを選択します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/S4CsoSzrKGI/AAAAAAAAAGA/Skda7XTeg6s/s1600-h/WS000002.JPG"&gt;&lt;img src="http://3.bp.blogspot.com/_wlXf9TOPv20/S4CsoSzrKGI/AAAAAAAAAGA/Skda7XTeg6s/s320/WS000002.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440538158106880098" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 55px; " /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;まだアーリーアクセス(EA)なんですね(&gt;_&lt;)&lt;/div&gt;&lt;div&gt;完成度結構高いんですけどね。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://2.bp.blogspot.com/_wlXf9TOPv20/S4CtbUzqjsI/AAAAAAAAAGI/EA1xPN2I_Jg/s320/WS000003.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440539034817040066" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 65px; " /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;んでプロジェクトで「war/WEB-INF/web.xml」を&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;開きます。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;右の部分が自分の名前空間になりますから&lt;/div&gt;&lt;div&gt;何か適当な名前をつけましょう！&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://4.bp.blogspot.com/_wlXf9TOPv20/S4CvPA_JkdI/AAAAAAAAAGQ/RF47qHe7TXM/s320/WS000004.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440541022361326034" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 114px; " /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;その後はプロジェクト直下にある&lt;/div&gt;&lt;div&gt;build.xmlを選択して右クリックで&lt;/div&gt;&lt;div&gt;実行を押して、下のantを選択します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;すると右の画面が出ます。&lt;/div&gt;&lt;img src="http://1.bp.blogspot.com/_wlXf9TOPv20/S4CvoeI1thI/AAAAAAAAAGY/m-j4sC4xeeM/s320/WS000005.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5440541459683325458" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 320px; height: 90px; " /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;gen-controllerはコントロールを自動作成&lt;/div&gt;&lt;div&gt;gen-modelはモデルを自動作成してくれます。&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;gen-controllerで出てくるボックスに&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;URLを指定してあげるとその指定したURLを&lt;/span&gt;&lt;/div&gt;&lt;div&gt;操作するControllerとJSP、プラステストコードを出力してくれます。&lt;/div&gt;&lt;div&gt;modelはそのモデルクラスとテストコードを出力してくれます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6387768862442697309?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6387768862442697309/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6387768862442697309' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6387768862442697309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6387768862442697309'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/slim3.html' title='Slim3でクラウド開発を始める'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wlXf9TOPv20/S4CpaEZ91sI/AAAAAAAAAFw/p3C7ZSfnNic/s72-c/WS000000.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-2458260281725619440</id><published>2010-02-13T17:15:00.003+09:00</published><updated>2010-02-13T18:24:22.758+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mixi'/><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTful'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>mixiにOAuthなRESTfulアクセス(Java)</title><content type='html'>最近サービスづいてきています。OAuthばっかりです。&lt;br /&gt;今度はJavaでmixiにアクセスです！&lt;br /&gt;&lt;br /&gt;まず、、、RESTful APIでアクセスするには&lt;br /&gt;まずmixiアプリの登録が必要です。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.mixi.co.jp/appli/pc/pc_prepare/add_app_flow"&gt;http://developer.mixi.co.jp/appli/pc/pc_prepare/add_app_flow&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;アプリケーションを登録できたら、&lt;br /&gt;アプリケーションに対してConsumer KeyとConsumer Secretが発行されます。&lt;br /&gt;&lt;br /&gt;これを元にOAuthアクセスを行います。&lt;br /&gt;&lt;br /&gt;まずHMAC-SHA1と呼ばれる暗号化を行う為のインスタンスを生成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;            byte[] secretyKeyBytes = secret.getBytes("UTF-8");&lt;br /&gt;            secretKeySpec = new SecretKeySpec(secretyKeyBytes,hmac);&lt;br /&gt;            mac = Mac.getInstance(hmac);&lt;br /&gt;            mac.init(secretKeySpec);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ここでのsecretはConsumer Secretに「&amp;」を付与したものになります。&lt;br /&gt;secretKeySpecはjavax.crypto.spec.SecretKeySpecになります。&lt;br /&gt;macはjavax.crypto.Macですね。&lt;br /&gt;&lt;br /&gt;URLに設定する引数を作成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        params.put("oauth_consumer_key", KEY);&lt;br /&gt;        params.put("oauth_signature_method", "HMAC-SHA1");&lt;br /&gt;        params.put("oauth_timestamp", String.valueOf(cal.getTimeInMillis()).substring(0,10));&lt;br /&gt;        params.put("oauth_version", "1.0");&lt;br /&gt;        params.put("oauth_nonce", nonce);&lt;br /&gt;        params.put("xoauth_requestor_id", viewerId);&lt;br /&gt;        params.put("format", "atom");&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;このparamsはURLを作成する為のオリジナルクラスのマップです。&lt;br /&gt;&lt;br /&gt;oauth_consumer_keyに設定しているKEYはConsumer Keyですね。&lt;br /&gt;oauth_signature_methodは暗号化を示す"HMAC-SHA1"を固定で指定します。&lt;br /&gt;oauth_timestampは時刻を設定します。&lt;br /&gt;oauth_versionはmixiに指定された文字列&lt;br /&gt;oauth_nonceはリクエスト毎に違うランダムな文字列です。UUID.randomUUID().toString()などで生成します。&lt;br /&gt;xoauth_requestor_idは対象のユーザIDです。&lt;br /&gt;formatはatomを設定していますが、最終的に取得するデータの形式でjsonでも取得できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;次にシグネチャを取得する為の文字列を取得します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        String method = "GET";&lt;br /&gt;        String http   ="http://" + endpoint + requestURI ;&lt;br /&gt;        String args   = canonicalQS;&lt;br /&gt;        String toSign;&lt;br /&gt;        try {&lt;br /&gt;            toSign = URLEncoder.encode(method,"UTF-8")+"&amp;"+&lt;br /&gt;                            URLEncoder.encode(http,"UTF-8")+"&amp;"+&lt;br /&gt;                            URLEncoder.encode(args,"UTF-8");&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;endpointはmixiのエンドポイント、、、って公開して良いのかな？&lt;br /&gt;requestURIは/people/{id}/@allです。{id}は取得したい人のIDを設定します。&lt;br /&gt;canonicalQSは前に設定したマップから取得したURLの引数です。&lt;br /&gt;&lt;br /&gt;これらの文字列をそれぞれURLエンコードして”&amp;”で連結します。&lt;br /&gt;&lt;br /&gt;その文字列を最初に作ったmacを元にしてシグネチャを作成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;        String signature = null;&lt;br /&gt;        byte[] data;&lt;br /&gt;        byte[] rawHmac;&lt;br /&gt;        try {&lt;br /&gt;            data = stringToSign.getBytes(CHARSET);&lt;br /&gt;            rawHmac = mac.doFinal(data);&lt;br /&gt;            Base64 encoder = new Base64();&lt;br /&gt;            signature = new String(encoder.encode(rawHmac));&lt;br /&gt;         signature = signature.substring(0, hmac.length()-2);&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException(CHARSET + " is unsupported!", e);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            signature = URLEncoder.encode(signature, CHARSET).replace("+", "%20")&lt;br /&gt;                    .replace("*", "%2A").replace("%7E", "~");&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;この文字列には改行が入ってますので２文字削除しています。&lt;br /&gt;そのあと、文字列の変換をかけてます。&lt;br /&gt;&lt;br /&gt;で、、、作成されたシグネチャを元に、アクセスするURLを作成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;String url = "http://" + endpoint + requestURI + "?" + canonicalQS + "&amp;oauth_signature=" + sig;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;でここにアクセスするとそのユーザの情報がXML化されて取得できるってわけです。&lt;br /&gt;但し、ここで問題が発生します。&lt;br /&gt;アクセスすると４０１エラーが返ってきます。&lt;br /&gt;&lt;br /&gt;だので、、、mixiアプリの事を調べていくと。。。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;対象ユーザが対象のmixiアプリを起動していない、もしくは起動から一定時間が経過した後にRESTful APIにアクセスを行った際には、&lt;br /&gt;HTTPレスポンスコードとして「401 Unauthorized」が返却されます。&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ををを、、、そういう事なのね。&lt;br /&gt;ようはしばらくmixiアプリを起動した人の情報を&lt;br /&gt;xoauth_requestor_idに設定してあげないと&lt;br /&gt;アクセスできないってわけです。&lt;br /&gt;&lt;br /&gt;APIを使うにはいろいろ画面遷移を考えないときついっぽいですね。&lt;br /&gt;しかしこれでアクセスできました。&lt;br /&gt;さぁ問題は何を作るかですね。。。。。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OAuthの仕様は&lt;br /&gt;&lt;a href="http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html"&gt;http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html&lt;/a&gt;&lt;br /&gt;にあります。&lt;br /&gt;&lt;br /&gt;シグネチャがうまく取れるまで結構かかりました。&lt;br /&gt;なのでここにある仕様(文字列)を元にテストを書きました。&lt;br /&gt;&lt;br /&gt;実際のコードはその他サービスなどにアクセスしている為&lt;br /&gt;複雑なクラスになっているのを平たく記述しているので&lt;br /&gt;ペローンって感じのコードになっていますが、テストは通ります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;package jp.co.ziro.surpre.helper;&lt;br /&gt;&lt;br /&gt;import static org.junit.Assert.*;&lt;br /&gt;&lt;br /&gt;import java.io.UnsupportedEncodingException;&lt;br /&gt;import java.net.URLEncoder;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.TreeMap;&lt;br /&gt;&lt;br /&gt;import javax.crypto.Mac;&lt;br /&gt;import javax.crypto.spec.SecretKeySpec;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.codec.binary.Base64;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class OAuthServiceHelperTest {&lt;br /&gt;&lt;br /&gt;    private static final String KEY = "dpf43f3p2l4k3l03";&lt;br /&gt;    private static final String SECRET = "kd94hf93k423kf44";&lt;br /&gt;    private static final String endpoint = "provider.example.net"; &lt;br /&gt;    private static final String HMAC = "HmacSHA1";&lt;br /&gt;    private static final String REQUEST_URI = "/profile";&lt;br /&gt;    private static final String NONCE = "kllo9940pd9333jh";&lt;br /&gt;    private static final String REQUEST_METHOD = "GET";&lt;br /&gt;    &lt;br /&gt;    @Test&lt;br /&gt;    public void testOAuthService() {&lt;br /&gt;&lt;br /&gt;        Map&amp;lt;String, String&amp;gt; paramMap = new TreeMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;&lt;br /&gt;        //基本的な引数をすべて設定&lt;br /&gt;        paramMap.put("oauth_consumer_key", KEY);&lt;br /&gt;        paramMap.put("oauth_signature_method", "HMAC-SHA1");&lt;br /&gt;        paramMap.put("oauth_timestamp", "1191242096");&lt;br /&gt;        paramMap.put("oauth_version", "1.0");&lt;br /&gt;        paramMap.put("oauth_nonce", NONCE);&lt;br /&gt;        &lt;br /&gt;        String canonicalQS = canonicalize(paramMap);&lt;br /&gt;&lt;br /&gt;        String method = REQUEST_METHOD;&lt;br /&gt;        String http   ="http://" + endpoint + REQUEST_URI ;&lt;br /&gt;        String args   = canonicalQS;&lt;br /&gt;&lt;br /&gt;        String toSign;&lt;br /&gt;        try {&lt;br /&gt;            toSign = URLEncoder.encode(method,"UTF-8")+"&amp;"+&lt;br /&gt;                            URLEncoder.encode(http,"UTF-8")+"&amp;"+&lt;br /&gt;                            URLEncoder.encode(args,"UTF-8");&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        String hmac = hmac(toSign);&lt;br /&gt;        hmac = hmac.substring(0, hmac.length()-2);&lt;br /&gt; &lt;br /&gt;        assertEquals(hmac,"SGtGiOrgTGF5Dd4RUMguopweOSU=");&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private String hmac(String stringToSign) {&lt;br /&gt;        String signature = null;&lt;br /&gt;        byte[] data;&lt;br /&gt;        byte[] rawHmac;&lt;br /&gt;        try {&lt;br /&gt;            String secret = SECRET + "&amp;";&lt;br /&gt;            byte[] secretyKeyBytes = secret.getBytes("UTF-8");&lt;br /&gt;            SecretKeySpec secretKeySpec = new SecretKeySpec(secretyKeyBytes,HMAC);&lt;br /&gt;            Mac mac = Mac.getInstance(HMAC);&lt;br /&gt;            mac.init(secretKeySpec);&lt;br /&gt;            data = stringToSign.getBytes("UTF-8");&lt;br /&gt;            rawHmac = mac.doFinal(data);&lt;br /&gt;            Base64 encoder = new Base64();&lt;br /&gt;            signature = new String(encoder.encode(rawHmac));&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        }&lt;br /&gt;        return signature;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    private String percentEncodeRfc3986(String s) {&lt;br /&gt;        String out;&lt;br /&gt;        try {&lt;br /&gt;            out = URLEncoder.encode(s, "UTF-8").replace("+", "%20")&lt;br /&gt;                    .replace("*", "%2A").replace("%7E", "~");&lt;br /&gt;        } catch (UnsupportedEncodingException e) {&lt;br /&gt;            out = s;&lt;br /&gt;        }&lt;br /&gt;        return out;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private String canonicalize(Map&amp;lt;String, String&amp;gt; sortedParamMap) {&lt;br /&gt;        if (sortedParamMap.isEmpty()) {&lt;br /&gt;            return "";&lt;br /&gt;        }&lt;br /&gt;        StringBuffer buffer = new StringBuffer();&lt;br /&gt;        Iterator&amp;lt;Map.Entry&amp;lt;String, String&amp;gt;&amp;gt; iter = sortedParamMap.entrySet().iterator();&lt;br /&gt;        while (iter.hasNext()) {&lt;br /&gt;            Map.Entry&amp;lt;String, String&amp;gt; kvpair = iter.next();&lt;br /&gt;            buffer.append(percentEncodeRfc3986(kvpair.getKey()));&lt;br /&gt;            buffer.append("=");&lt;br /&gt;            buffer.append(percentEncodeRfc3986(kvpair.getValue()));&lt;br /&gt;            if (iter.hasNext()) {&lt;br /&gt;                buffer.append("&amp;");&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        String cannoical = buffer.toString();&lt;br /&gt;        return cannoical;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;元のコードは&lt;br /&gt;&lt;a href="http://bit.ly/bVSEgt"&gt;http://bit.ly/bVSEgt&lt;/a&gt;&lt;br /&gt;なども参考にしています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-2458260281725619440?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/2458260281725619440/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=2458260281725619440' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2458260281725619440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/2458260281725619440'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/mixioauthrestfuljava.html' title='mixiにOAuthなRESTfulアクセス(Java)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1747499381935936048</id><published>2010-02-10T08:31:00.004+09:00</published><updated>2010-02-10T08:40:00.521+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='surpre'/><category scheme='http://www.blogger.com/atom/ns#' term='bit.ly'/><title type='text'>URL短縮サービスbit.ly</title><content type='html'>Twitterでつぶやけるようにしたものの、&lt;br /&gt;URLを貼り付けたら文章が長くなってしまうので&lt;br /&gt;URL短縮サービスとつなげることにしました。&lt;br /&gt;&lt;br /&gt;まずbit.lyにユーザ登録します。&lt;br /&gt;するとアカウント情報のところにAPIKeyが発行されます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; &lt;br /&gt;String endPoint = "http://api.bit.ly/shorten";&lt;br /&gt;paramMap.put("apiKey", APIKEY);&lt;br /&gt;paramMap.put("login", LOGIN);&lt;br /&gt;paramMap.put("version", VARSION);&lt;br /&gt;paramMap.put("format", FORMAT);&lt;br /&gt;paramMap.put("longUrl", longUrl);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;※paramMapはURLの引数です。&lt;br /&gt;　ちょっとクラス化しててうまく説明できないです。&lt;br /&gt;&lt;br /&gt;URLを指定して、その他引数を渡します。&lt;br /&gt;LOGINにはログイン用に登録したID、&lt;br /&gt;versionには現在"2.0.1"、formatには"xml"を指定します。&lt;br /&gt;※jsonでの取得もあるようです。&lt;br /&gt;&lt;br /&gt;longUrlには変換対象のURLを指定します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;それでURLアクセスして取得してきたRESTに&lt;br /&gt;"sortUrl"タグがありますので&lt;br /&gt;それを利用すればOKです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;いやぁしかし、URL短縮ツールってURL短くするサービスだと思ってましたが&lt;br /&gt;そのURLをアクセス解析なんかに使えるんですね。&lt;br /&gt;&lt;br /&gt;メーリングリストとかでリンク送るときに使えば&lt;br /&gt;アクセス数が簡易的にわかってよいかもですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1747499381935936048?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1747499381935936048/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1747499381935936048' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1747499381935936048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1747499381935936048'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/urlbitly.html' title='URL短縮サービスbit.ly'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8644941200291278158</id><published>2010-02-10T00:48:00.002+09:00</published><updated>2010-02-10T01:04:55.727+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='surpre'/><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='yahoo'/><title type='text'>あっちをたてればこっちがたたず</title><content type='html'>新しいサービスをつくろうとして悩んでます。&lt;br /&gt;OAuthでつなげようと思いながら、それはあれで、あれはそれで。&lt;br /&gt;&lt;br /&gt;結論はY化しようと思います。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8644941200291278158?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8644941200291278158/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8644941200291278158' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8644941200291278158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8644941200291278158'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/blog-post.html' title='あっちをたてればこっちがたたず'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6334748548051659387</id><published>2010-02-09T00:45:00.007+09:00</published><updated>2010-02-09T01:25:34.900+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter4j'/><title type='text'>OAuthとTwitter4J(Slim3とFlexも)</title><content type='html'>先日Flex（AS3）でOAuth認証を行いました。&lt;br /&gt;しかし、セキュリティサンドボックスの問題により、棚上げしました。&lt;br /&gt;セキュリティサンドボックスも何かまとめないとですね。&lt;br /&gt;&lt;br /&gt;って事でWeb側でTwitterにアクセスしてサービスを実現する事にしました。&lt;br /&gt;結局、プロキシになっちゃいました。&lt;br /&gt;まぁ挙動さえ分かってしまえばこっちのもんです。&lt;br /&gt;&lt;br /&gt;ちなみにOAuth部分はTwitter4Jに任せてますので&lt;br /&gt;その挙動を見たければsourceを添付してあげて調べてください。&lt;br /&gt;&lt;br /&gt;※ソースは一部関数化してるものを平らにしているので&lt;br /&gt;  変数名とかはおかしいかも。。。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Twitter twitter = new TwitterFactory().getInstance();&lt;br /&gt;twitter.setOAuthConsumer(KEY, KEY_SECRET);&lt;br /&gt;try {&lt;br /&gt;        RequestToken requestToken = twitter.getOAuthRequestToken();&lt;br /&gt;        String url = requestToken.getAuthorizationURL();&lt;br /&gt;        requestScope("url",url);&lt;br /&gt;        sessionScope("requestToken",requestToken);&lt;br /&gt;} catch (TwitterException e) {&lt;br /&gt; new RuntimeException(e);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まず、Twitterオブジェクトを取得してアプリケーションのキー値を設定します。&lt;br /&gt;そこからURLを取得してきます。それを返します。&lt;br /&gt;&lt;br /&gt;その後、Pinを取得して処理する場合に新たにRequestTokenを作成すると&lt;br /&gt;おかしくなるのでセッションに設定しました。&lt;br /&gt;※requestScope(),sessionScope()はSlim3のメソッドです。&lt;br /&gt;  リクエストやセッションに溜め込んでください。&lt;br /&gt;&lt;br /&gt;そのリクエストを元にURLにアクセスします。&lt;br /&gt;私の場合はFlexなので&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;//リンクを飛ばす&lt;br /&gt;navigateToURL(new URLRequest(oauthUrl));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;って感じになりました。&lt;br /&gt;&lt;br /&gt;ここにアクセスすると横の画像のWebが別ブラウザで表示されます。&lt;br /&gt;Twitterアカウントを入力すると認証され、&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/S3Azw7RZ5dI/AAAAAAAAAFI/oW5c1SIQ0Z8/s1600-h/%E7%84%A1%E9%A1%8C.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 146px;" src="http://3.bp.blogspot.com/_wlXf9TOPv20/S3Azw7RZ5dI/AAAAAAAAAFI/oW5c1SIQ0Z8/s320/%E7%84%A1%E9%A1%8C.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5435901665873618386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pinが表示されます。&lt;br /&gt;。。。。画像で表示されます。選択してコピーして&lt;br /&gt;そのPinを自分のWebページなどで入力します。&lt;br /&gt;&lt;br /&gt;。。。ここでコールバックなどをうまく使えば&lt;br /&gt;多分何手かUIを改善できそうな気がするんですけどね。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/S3AzxFJyrCI/AAAAAAAAAFQ/7GkOtCHq_ts/s1600-h/%E7%84%A1%E9%A1%8C2.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 118px;" src="http://1.bp.blogspot.com/_wlXf9TOPv20/S3AzxFJyrCI/AAAAAAAAAFQ/7GkOtCHq_ts/s320/%E7%84%A1%E9%A1%8C2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5435901668526042146" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;私の場合はそれを元にPinを入力して再度サーバサイドで処理を行いました。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Twitter twitter = new TwitterFactory().getInstance();&lt;br /&gt;twitter.setOAuthConsumer(KEY, KEY_SECRET);&lt;br /&gt;String pin = requestScope("pin");&lt;br /&gt;RequestToken requestToken = sessionScope("requestToken");&lt;br /&gt;&lt;br /&gt;AccessToken accessToken = null;&lt;br /&gt;try {&lt;br /&gt;    accessToken = twitter.getOAuthAccessToken(requestToken, pin);&lt;br /&gt;} catch (TwitterException e) {&lt;br /&gt;    throw new RuntimeException(e);&lt;br /&gt;}&lt;br /&gt;String token = accessToken.getToken();&lt;br /&gt;String tokenSecret = accessToken.getTokenSecret();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;先ほど保存しておいたRequestTokenと取得したPinをリクエストから受け取り、&lt;br /&gt;AccessTokenを取得します。&lt;br /&gt;それによりトークンを取得する事が必要です。&lt;br /&gt;&lt;br /&gt;私はここでSlim3 Datastoreを使用して、トークンを永続化しています。&lt;br /&gt;ちなみにですが、私が作ってるのは認証アプリなので&lt;br /&gt;認証をしたUserオブジェクト(GAE)も保存しています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;その後はログインしたユーザを元に&lt;br /&gt;このトークンを取得してきて処理をします。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Twitter twitter = new TwitterFactory().getInstance();&lt;br /&gt;twitter.setOAuthConsumer(KEY, KEY_SECRET);&lt;br /&gt;&lt;br /&gt;AccessToken accessToken = new AccessToken(data.getToken(),data.getTokenSecret());&lt;br /&gt;twitter.setOAuthAccessToken(accessToken);&lt;br /&gt;twitter.updateStatus(tweet); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;dataは永続化したオブジェクトです。&lt;br /&gt;updateStatus()はtwitter4jのつぶやく機能です。&lt;br /&gt;&lt;br /&gt;こんな感じでサービスを作成しました。&lt;br /&gt;ユーザ情報を保存したくなくて、OAuthに対応しましたが、&lt;br /&gt;色々とツールがあって簡単にできるもんですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6334748548051659387?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6334748548051659387/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6334748548051659387' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6334748548051659387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6334748548051659387'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/oauthtwitter4jslim3flex.html' title='OAuthとTwitter4J(Slim3とFlexも)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wlXf9TOPv20/S3Azw7RZ5dI/AAAAAAAAAFI/oW5c1SIQ0Z8/s72-c/%E7%84%A1%E9%A1%8C.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5821591573728158429</id><published>2010-02-07T08:23:00.002+09:00</published><updated>2010-02-07T09:05:37.031+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OAuth'/><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>TwitterアプリでOAuth認証</title><content type='html'>とあるサービスを作る過程でTwitterクライアントを&lt;br /&gt;作ろうと思い、作り始めました。&lt;br /&gt;始めはユーザIDとパスワードを入力してもらおうと考えていましたが&lt;br /&gt;やはり自分のアプリにそれを保存しておくの億劫になり、&lt;br /&gt;OAuth認証で作る事にしました。&lt;br /&gt;&lt;br /&gt;まず&lt;a href="http://twitter.com/oauth_clients/new"&gt;ここ&lt;/a&gt;に行って&lt;br /&gt;アプリケーションを登録する必要があります。&lt;br /&gt;&lt;br /&gt;登録を終えるとアプリケーションのページができて、&lt;br /&gt;キーが２つ発行されます。&lt;br /&gt;「https://twitter.com/apps」で確認ができます。&lt;br /&gt;ちなみに認証して使用しているアプリケーションを確認するには&lt;br /&gt;「https://twitter.com/account/connections」&lt;br /&gt;に行くと確認できます。&lt;br /&gt;&lt;br /&gt;さてここで開発開始ですが。。。。&lt;br /&gt;Javaの部分でサービスのアクセスを作成していたのですが、&lt;br /&gt;認証部分はFlexで行った方が画面遷移とか簡単そうだったので&lt;br /&gt;Flex側で書くことにしました。&lt;br /&gt;&lt;br /&gt;Twitterさんのサイトに各言語におけるサンプルサイトを紹介しています。&lt;br /&gt;https://twitterapi.pbworks.com/OAuth-Examples&lt;br /&gt;&lt;br /&gt;そこでFlexのサイトがあったので&lt;br /&gt;http://www.coderanger.com/blog/?p=59&lt;br /&gt;これを元に作成しました。&lt;br /&gt;&lt;br /&gt;なのでここのソースを元に説明していきます。&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;private var _twitauth:OAuthManager = new OAuthManager();&lt;br /&gt;_twitauth.addEventListener( OAuthEvent.ON_REQUEST_TOKEN_RECEIVED, onRequestTokenReceived );&lt;br /&gt;_twitauth.addEventListener( OAuthEvent.ON_REQUEST_TOKEN_FAILED, onRequestTokenFailed );&lt;br /&gt;_twitauth.addEventListener( OAuthEvent.ON_ACCESS_TOKEN_RECEIVED, onAccessTokenReceived );&lt;br /&gt;_twitauth.addEventListener( OAuthEvent.ON_ACCESS_TOKEN_FAILED, onAccessTokenFailed );&lt;br /&gt;_twitauth.usePinWorkflow = true;&lt;br /&gt;_twitauth.consumerKey = key.text;&lt;br /&gt;_twitauth.consumerSecret = secret.text;&lt;br /&gt;_twitauth.oauthDomain = "twitter.com";&lt;br /&gt;_twitauth.requestToken();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;この箇所はアクセス後の呼び出される関数を設定して&lt;br /&gt;アプリケーションで取得したキーの設定を行っています。&lt;br /&gt;サンプルではコントロールから取得している感じになっていますが&lt;br /&gt;ここに設定してあげます。&lt;br /&gt;&lt;br /&gt;_twitauth.requestToken();&lt;br /&gt;&lt;br /&gt;で最初のリクエストを行っています。&lt;br /&gt;この関数と同時にアプリケーション認証のサイトを別のブラウザで表示してくれます。&lt;br /&gt;&lt;br /&gt;ここでユーザが許可し認証を行うと&lt;br /&gt;アプリケーションが認証され、PINコードが表示されます。&lt;br /&gt;&lt;br /&gt;そのPINをユーザにテキストボックスなどに入力してもらって&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;private function onSendPin():void&lt;br /&gt;{&lt;br /&gt; _twitauth.requestAccessToken( Number( pin.text ) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;この関数で送ってあげます。&lt;br /&gt;このリクエストで成功した場合「onAccessTokenReceived()」が発生するので&lt;br /&gt;そこでユーザの認証情報を取得できます。&lt;br /&gt;&lt;br /&gt;あとはアプリケーションでこの情報を永続化するなどをして&lt;br /&gt;アクセスを行います。&lt;br /&gt;下の方にあるコードはその情報を使ってつぶやいているコードです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;認証を行うとこのようにアプリケーションが追加されます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/S24DMMfHo5I/AAAAAAAAAFA/PjSsQ2gcF4g/s1600-h/%E7%84%A1%E9%A1%8C.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 128px;" src="http://4.bp.blogspot.com/_wlXf9TOPv20/S24DMMfHo5I/AAAAAAAAAFA/PjSsQ2gcF4g/s320/%E7%84%A1%E9%A1%8C.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5435285308327830418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;おそらくアプリケーションの設定でCallbackURLなどを使って&lt;br /&gt;一部自動化できるような気もしていますが、一応これでつぶやく事ができました。&lt;br /&gt;ただし、このブログ公開時点ではサーバサイドにあげた場合に&lt;br /&gt;アクセスできないという不具合があるので何か間違っているのかもしれません。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;このコードを参考にしてオープンソース化されている方もいらっしゃるので&lt;br /&gt;http://code.google.com/p/q-oauth/&lt;br /&gt;ぜひお使いください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5821591573728158429?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5821591573728158429/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5821591573728158429' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5821591573728158429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5821591573728158429'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/02/twitteroauth.html' title='TwitterアプリでOAuth認証'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wlXf9TOPv20/S24DMMfHo5I/AAAAAAAAAFA/PjSsQ2gcF4g/s72-c/%E7%84%A1%E9%A1%8C.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6943752313041130915</id><published>2010-01-30T12:47:00.002+09:00</published><updated>2010-01-30T12:53:49.092+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Papervision3D'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='Efflex'/><title type='text'>Efflex</title><content type='html'>Efflexを使用していますが、&lt;br /&gt;どうも最新のエフェクトが使いたくて、&lt;br /&gt;ソースをダウンロードしてきました。&lt;br /&gt;&lt;br /&gt;だけど、、、コンパイルエラー。&lt;br /&gt;Papervisionが入ってないからだと、swcを落としてきましたが&lt;br /&gt;ダメでした。調べてみると結構古いバージョン(GreatWhite Alpha)を&lt;br /&gt;使用しているらしく、ダメでした。&lt;br /&gt;&lt;br /&gt;だけど冷静に考えるとswc自身が持っている可能性があると思い&lt;br /&gt;libsに入れてみる。通った～！！！&lt;br /&gt;&lt;br /&gt;って思いましたが単独でエラーになってます。&lt;br /&gt;何点か問題になった点を修正して使えるようになりました。&lt;br /&gt;結構かかりました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6943752313041130915?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6943752313041130915/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6943752313041130915' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6943752313041130915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6943752313041130915'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2010/01/efflex.html' title='Efflex'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1491873247099693668</id><published>2009-11-21T13:22:00.004+09:00</published><updated>2009-11-21T13:30:11.528+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='メール'/><title type='text'>GAEとDoCoMoのアドレス</title><content type='html'>GAEでメール受信を作りましたが、&lt;div&gt;初めに試してもらった人が「xxxxx.@docomo.ne.jp」てアドレスでした。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;どうも@の前に「.」があるとダメみたいで&lt;/div&gt;&lt;div&gt;getFrom()をやると「local part invalid」ってエラーが出てました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;なのでヘッダーの情報を見て、&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;&lt;pre name="code" class="java"&gt; Enumeration&amp;lt;?&amp;gt; enu = aMessage.getAllHeaderLines();  //データ数回繰り返す while ( enu.hasMoreElements() ) {  String line = (String)enu.nextElement();  if ( line.toLowerCase().indexOf("from") &amp;gt;= 0 ) {   //fromを検索して追加   fromAddress.add(line);  } else if ( line.toLowerCase().indexOf("to") &amp;gt;= 0 ) {   //toを検索して追加   toAddress.add(line);  } } &lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre; font-size: -webkit-xxx-large;"&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px; white-space: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre; font-size: -webkit-xxx-large;"&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px; white-space: normal;"&gt;&lt;div&gt;って感じでFromやToを抜き出して、&lt;/div&gt;&lt;div&gt;そこからアドレスを抽出して処理してみました。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;まぁシビアにはまずいかもしれませんが&lt;/div&gt;&lt;div&gt;一応これでメールアドレスを判定する事ができました。&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre; font-size: -webkit-xxx-large; "&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px; white-space: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1491873247099693668?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1491873247099693668/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1491873247099693668' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1491873247099693668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1491873247099693668'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/11/gaedocomo.html' title='GAEとDoCoMoのアドレス'/><author><name>y.hebi</name><uri>http://www.blogger.com/profile/05342428331945613681</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5216863490482443679</id><published>2009-11-15T14:40:00.002+09:00</published><updated>2009-11-15T14:47:15.765+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TitleWindow'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>TitleWindowをリサイズする</title><content type='html'>TitleWindowをリサイズ可能にしようと思い立ち&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://blog.enjoitech.jp/detail.php?aid=137"&gt;http://blog.enjoitech.jp/detail.php?aid=137&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;を元に作成したのだが、スクロールバーなどがあると&lt;/div&gt;&lt;div&gt;かなり挙動不審になりますね。。。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;つうことで&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;onThis_mouseDown() 関数の初めに&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;&lt;pre name="code" class="js"&gt;    if ( event.target != this ) {     return;    }  &lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; white-space: pre-wrap;"&gt;といれると結構安定します。&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; white-space: pre-wrap;"&gt;ちなみに私は&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; white-space: pre-wrap;"&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;    private const SIZE_DRAGAREA:int = 10;   private const SIZE_MIN_WIDTH:int = 50;   private const SIZE_MIN_HEIGHT:int = 50; &lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;位で使います。&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Blogger・・・トラックバックできない。。。&lt;/div&gt;&lt;div&gt;・・・なんかややこしいけどやり方はあるみたい。&lt;/div&gt;&lt;div&gt;やってみるかな。。。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5216863490482443679?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5216863490482443679/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5216863490482443679' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5216863490482443679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5216863490482443679'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/11/titlewindow.html' title='TitleWindowをリサイズする'/><author><name>y.hebi</name><uri>http://www.blogger.com/profile/05342428331945613681</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8077246177584306460</id><published>2009-11-08T08:59:00.002+09:00</published><updated>2009-11-08T10:25:22.922+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='メール受信'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><title type='text'>GAEでメール受信</title><content type='html'>GAEにメール受信する機能が増えたんですね。&lt;br /&gt;またまたやってくれます。。。。って思ってたら&lt;br /&gt;やっぱり限定の機能なんですね。&lt;br /&gt;&lt;br /&gt;・・・まぁそれだけでもすごい事です。&lt;br /&gt;えーと、、、仕組みは&lt;a href="http://code.google.com/intl/ja/appengine/docs/java/mail/receiving.html"&gt;ここ&lt;/a&gt;にあります。&lt;br /&gt;&lt;br /&gt;string@appid.appspotmail.com&lt;br /&gt;&lt;br /&gt;に送ると、&lt;br /&gt;&lt;br /&gt; /_ah/mail/&lt;address&gt;&lt;br /&gt;&lt;br /&gt;に届くみたいですね。。。。&lt;br /&gt;Cronとか駆使して、、、って考えてたんですけど、&lt;br /&gt;開発環境でみる限り、メールを送信したら、サーブレットをPostしてくれるみたいです！&lt;br /&gt;なんだ、、、色々楽ですね。。。&lt;br /&gt;&lt;br /&gt;まず、appengine-web.xmlに&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;inbound-services&amp;gt;&lt;br /&gt;      &amp;lt;service&amp;gt;mail&amp;lt;/service&amp;gt;&lt;br /&gt;    &amp;lt;/inbound-services&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を追加します。&lt;br /&gt;&lt;br /&gt;その後web.xmlに&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;      &amp;lt;servlet-name&amp;gt;mailHandle&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;      &amp;lt;servlet-class&amp;gt;bz.ziro.kanbe.servlet.MailHandlerServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;      &amp;lt;servlet-name&amp;gt;mailHandle&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;      &amp;lt;url-pattern&amp;gt;/_ah/mail/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;～&lt;br /&gt;&lt;br /&gt;    &amp;lt;security-constraint&amp;gt;&lt;br /&gt;      &amp;lt;web-resource-collection&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;/_ah/mail/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;      &amp;lt;/web-resource-collection&amp;gt;&lt;br /&gt;      &amp;lt;auth-constraint&amp;gt;&lt;br /&gt;        &amp;lt;role-name&amp;gt;admin&amp;lt;/role-name&amp;gt;&lt;br /&gt;      &amp;lt;/auth-constraint&amp;gt;&lt;br /&gt;    &amp;lt;/security-constraint&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を追加します。&lt;br /&gt;servletの上はクラス名、下はURLです。&lt;br /&gt;URLは固定ですね。&lt;br /&gt;&lt;br /&gt;下のはセキュリティ設定です。&lt;br /&gt;第三者が触れないようにadmin(アプリ管理者)のみ触れるようにしておきます。&lt;br /&gt;&lt;br /&gt;その後HttpServletを派生したクラスを作成して&lt;br /&gt;doPost()を実装します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; @Override&lt;br /&gt; protected void doPost(HttpServletRequest req, HttpServletResponse resp)&lt;br /&gt;   throws ServletException, IOException {&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            Properties props = new Properties();&lt;br /&gt;            Session session = Session.getDefaultInstance(props, null);&lt;br /&gt;            MimeMessage message = new MimeMessage(session, req.getInputStream());&lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        } catch (MessagingException e) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;        }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これで、メールを受け取ったら動作します。&lt;br /&gt;http://localhost:8080/_ah/admin/&lt;br /&gt;にアクセスすると、inboundMailっていうのがあるので&lt;br /&gt;開発環境ではここから送信できます。&lt;br /&gt;&lt;br /&gt;先だって話したように、URLとメールアドレスが連動しているので&lt;br /&gt;何のメールかとかをToで判断したりすればOKだと思います。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8077246177584306460?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8077246177584306460/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8077246177584306460' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8077246177584306460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8077246177584306460'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/11/gae.html' title='GAEでメール受信'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6692372033528801987</id><published>2009-11-08T01:37:00.002+09:00</published><updated>2009-11-08T01:45:07.100+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='リリース'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>FlexのリリースビルドをAntで</title><content type='html'>Flexのリリースビルドを簡単にAntでやろうとしたらハマりました(&gt;_&lt;)&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html:collapse"&gt;&lt;br /&gt;&amp;lt;project name="kanbeMng" default="release" basedir="."&amp;gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;taskdef resource="flexTasks.tasks" classpath="D:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\ant\lib\flexTasks.jar"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="FLEX_HOME" value="D:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="APP_ROOT" value="C:\Documents and Settings\Administrator\My Documents\Flex Builder 3\kanbeMng"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="SRC_ROOT" value="${APP_ROOT}\src"/&amp;gt;&lt;br /&gt; &amp;lt;property name="mxmlc.jar" location="${FLEX_HOME}/lib/mxmlc.jar"/&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;property name="debugDir"   value="bin-debug"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="releaseDir" value="bin-release"/&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;property name="targetDir" value="D:/workspace/kanbe/war/mng"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="targetBlankDir" value="D:/workspace/kanbe-blank/war/mng"/&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;property name="flashFile" value="KanbeMng.swf"/&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="release" depends="release-build"&amp;gt;&lt;br /&gt;  &amp;lt;move file="${SRC_ROOT}\${flashFile}" todir="${releaseDir}" overwrite="true"/&amp;gt;&lt;br /&gt;  &amp;lt;copy todir="${targetDir}" file="${debugDir}/${flashFile}" overwrite="true"/&amp;gt;&lt;br /&gt;  &amp;lt;copy todir="${targetBlankDir}" file="${releaseDir}/${flashFile}" overwrite="true"/&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="release-build"&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;mxmlc file="${SRC_ROOT}\KanbeMng.mxml" &lt;br /&gt;      debug="false"&lt;br /&gt;      actionscript-file-encoding="UTF-8"&lt;br /&gt;      keep-generated-actionscript="true" &lt;br /&gt;      incremental="true"&amp;gt;&lt;br /&gt;   &lt;br /&gt;   &amp;lt;compiler.library-path dir="${APP_ROOT}\libs" append="true"&amp;gt;&lt;br /&gt;    &amp;lt;include name="Efflex_v0.03_fx3_fp9.swc" /&amp;gt;&lt;br /&gt;   &amp;lt;/compiler.library-path&amp;gt;&lt;br /&gt;   &lt;br /&gt;   &amp;lt;compiler.source-path path-element="${SRC_ROOT}"/&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;/mxmlc&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;/target&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;私のわかる程度に説明します。&lt;br /&gt;&lt;br /&gt;まず、自分の環境に合わせて、設定をします。&lt;br /&gt;なんか無駄なものもありそうですね。。。 ...mxmlc.jarはいらないっすね。&lt;br /&gt;&lt;br /&gt;でmxmlcタグを作成します。&lt;br /&gt;swcがある場合はそれを読み込みましょう！&lt;br /&gt;&lt;br /&gt;ん～キャッシュがウンタラカンタラが難しかったです。&lt;br /&gt;もう少しわかりすく書きたいっすけどね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6692372033528801987?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6692372033528801987/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6692372033528801987' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6692372033528801987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6692372033528801987'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/11/flexant.html' title='FlexのリリースビルドをAntで'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-738572857898925521</id><published>2009-10-08T08:20:00.002+09:00</published><updated>2009-10-08T08:30:11.141+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='FileReference'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='認証'/><title type='text'>GAE＋Flex＋ファイルアップロード＋認証</title><content type='html'>GAE上でFlexを使用してファイルアップロードを行っているのですが&lt;br /&gt;どうもうまくいかない状態でした。&lt;br /&gt;まぁオススメはできませんが回避策を一応書いておきます。&lt;br /&gt;&lt;br /&gt;FireReference.uploadはセキュリティ系の問題なのか&lt;br /&gt;クッキーを送信できません。&lt;br /&gt;&lt;a href="http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/net/URLRequestHeader.html"&gt;ここ&lt;/a&gt;のにupload()のURLRequestHeaderのところに記述があります。&lt;br /&gt;&lt;br /&gt;GAEでは認証アプリ内ではクッキーを使用して認証を確認しているようで&lt;br /&gt;JSESSIONIDとACSIDを送信することが不可能なようです。&lt;br /&gt;&lt;br /&gt;なのでGAE上でFileReferenceを利用してアップロードをすると&lt;br /&gt;アップロード時に認証エラーでアップロードができないようです。&lt;br /&gt;&lt;br /&gt;そこで、私の場合はアップロードのURLを認証から外して独自認証することで切り抜けました。&lt;br /&gt;Flexが送信するRequestに引数をjsessionidを指定しておいて&lt;br /&gt;認証のかかってないURLの処理上でSessionからIDを取得して同一かを判定して切り抜けました。&lt;br /&gt;&lt;br /&gt;まぁセキュリティ上は微妙でしょうけど、&lt;br /&gt;一応認証を受けてないと使えないようにはしました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;で、、、ここで気をつけなければいけないのは&lt;br /&gt;FileReferenceで渡すURLRequest.dataをObjectではなく、&lt;br /&gt;URLVariablesにすることです。&lt;br /&gt;そうしないとRequestでmultipartにならず、&lt;br /&gt;multipartで値を受け取れないからです。(slim3)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-738572857898925521?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/738572857898925521/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=738572857898925521' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/738572857898925521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/738572857898925521'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/10/gaeflex.html' title='GAE＋Flex＋ファイルアップロード＋認証'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6934939421694506837</id><published>2009-08-28T00:31:00.004+09:00</published><updated>2009-08-29T15:23:00.627+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RoR'/><category scheme='http://www.blogger.com/atom/ns#' term='redmine'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Redmineインストール(Linux)</title><content type='html'>やっぱwin32だと重いので、Linuxにインストールします。&lt;br /&gt;&lt;br /&gt;まずRubyは&lt;br /&gt;http://www.ruby-lang.org/ja/downloads/&lt;br /&gt;から落としてきます。&lt;br /&gt;バージョンは1.8系じゃないと何かとエラーになります。&lt;br /&gt;&lt;br /&gt;んでそれを解凍して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;します。&lt;br /&gt;&lt;br /&gt;で&lt;br /&gt;&lt;br /&gt;# ruby -v&lt;br /&gt;&lt;br /&gt;とやってインストールされたことを確認します。&lt;br /&gt;&lt;br /&gt;その後rubygemsを落として来て解凍してそのディレクトリに入って、&lt;br /&gt;&lt;br /&gt;# ruby setup.rb&lt;br /&gt;&lt;br /&gt;とやります。&lt;br /&gt;これでrubygemsはインストール完了(&gt;_&lt;)v&lt;br /&gt;&lt;br /&gt;でその後にrailsを&lt;br /&gt;&lt;br /&gt;# gem install rails -v 2.2.2&lt;br /&gt;&lt;br /&gt;とやります。これで準備完了。&lt;br /&gt;&lt;br /&gt;さて、いよいよredmineです。。。。&lt;br /&gt;という前にDBをインストールしなければっ！&lt;br /&gt;&lt;br /&gt;一番相性の良いMySQLにしますかね？&lt;br /&gt;&lt;br /&gt;http://dev.mysql.com/downloads/mysql/5.0.html&lt;br /&gt;&lt;br /&gt;に行って、V5.0を落としてきます。&lt;br /&gt;V5.1でも良いんですけど、相性が悪いみたいです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;MySQLをインストールした後、データベースを作っておきましょう！&lt;br /&gt;えーとそれは&lt;br /&gt;http://secondarykey.blogspot.com/search/label/MySQL&lt;br /&gt;この辺から作ってください！&lt;br /&gt;&lt;br /&gt;create database redmine character set utf8;&lt;br /&gt;データベースを作成する場合はUTF8を指定します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;でその後に&lt;br /&gt;&lt;br /&gt;http://rubyforge.org/frs/?group_id=1850&lt;br /&gt;&lt;br /&gt;ここから最新版の0.8.4を落としてきます。&lt;br /&gt;で解凍して、config/database.yml を作成して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;production:&lt;br /&gt;  adapter: mysql&lt;br /&gt;  database: redmine&lt;br /&gt;  host: localhost&lt;br /&gt;  username: red&lt;br /&gt;  password: mine &lt;br /&gt;  encoding: utf8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;って感じで書き込みます。&lt;br /&gt;&lt;br /&gt;# rake db:migrate RAILS_ENV=production&lt;br /&gt;&lt;br /&gt;を行うとテーブルを作成してくれます。&lt;br /&gt;&lt;br /&gt;# ruby script/server -e production&lt;br /&gt;&lt;br /&gt;で実行して&lt;br /&gt;&lt;br /&gt;http://~~~~:3000/&lt;br /&gt;&lt;br /&gt;でアクセスしてadmin/adminでログインします。&lt;br /&gt;&lt;br /&gt;※ruby installでプロキシがある場合は&lt;br /&gt;  [-p http://~~~~~]って付け加えると大丈夫です(--)ﾉｼ&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6934939421694506837?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6934939421694506837/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6934939421694506837' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6934939421694506837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6934939421694506837'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/08/redminelinux.html' title='Redmineインストール(Linux)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7297711324241126360</id><published>2009-08-28T00:20:00.001+09:00</published><updated>2009-08-28T00:21:43.375+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RoR'/><category scheme='http://www.blogger.com/atom/ns#' term='redmine'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Redmine</title><content type='html'>・・・んーやっぱWin32よりLinuxが早いね(-.-;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7297711324241126360?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7297711324241126360/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7297711324241126360' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7297711324241126360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7297711324241126360'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/08/redmine.html' title='Redmine'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1674167546626553502</id><published>2009-07-25T16:51:00.004+09:00</published><updated>2009-07-25T17:03:10.108+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='BigTable'/><category scheme='http://www.blogger.com/atom/ns#' term='一覧'/><title type='text'>GAEでデータビュー</title><content type='html'>GoogleAppEngineのプラグイン1.2.2から。。。なのかは知りませんが&lt;br /&gt;登録したデータをデータービューで見ることが可能になりました。&lt;br /&gt;アプリケーションの起動中に&lt;br /&gt;&lt;br /&gt;http://localhost:8080/_ah/admin/datastore&lt;br /&gt;&lt;br /&gt;にアクセスすればOKです。&lt;br /&gt;これでデータを見ることができますね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1674167546626553502?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1674167546626553502/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1674167546626553502' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1674167546626553502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1674167546626553502'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/07/gae_25.html' title='GAEでデータビュー'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7593126961321464438</id><published>2009-07-18T15:29:00.002+09:00</published><updated>2009-07-18T15:31:27.786+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaMail'/><title type='text'>GAEでメール送信</title><content type='html'>GAEでメール送信するにはJavaMailを使用します。&lt;br /&gt;・・・特段技術的なことを書くまでもないのですが受信はできません。&lt;br /&gt;送信時はアプリの管理者がFromになる必要があります。&lt;br /&gt;って全部マニュアルに書いてありますけど。。。&lt;br /&gt;&lt;br /&gt;少しメールに関連したサービスの立ち上げを&lt;br /&gt;やろうとしたのですが頓挫したので一応参考まで。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7593126961321464438?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7593126961321464438/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7593126961321464438' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7593126961321464438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7593126961321464438'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/07/gae.html' title='GAEでメール送信'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1860765223166458360</id><published>2009-07-13T21:32:00.003+09:00</published><updated>2009-07-13T21:36:51.987+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Application'/><category scheme='http://www.blogger.com/atom/ns#' term='正規表現'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='RegExp'/><title type='text'>ドメインの切り替え</title><content type='html'>HTTPサービスにアクセスする際に&lt;br /&gt;ローカルで試す時と、デプロイした時の動作を変更したい。&lt;br /&gt;そんな時にこの方法です。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;var domain = "http://localhost:8080/";&lt;br /&gt;var url:String = Application.application.url;&lt;br /&gt;var httpExp:RegExp = new RegExp("http://[^/]*/");&lt;br /&gt;&lt;br /&gt;if ( httpExp.test(url) ) {&lt;br /&gt;  domain = httpExp.exec(url).toString();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まぁ取得を外出しにすればよいのですが、&lt;br /&gt;手軽にこういう感じもあるんですね。&lt;br /&gt;&lt;br /&gt;Flexで開発している間は、&lt;br /&gt;「file://」でアクセスするので&lt;br /&gt;mx.core.Applicationが持ってるURLではif文には入らないです。&lt;br /&gt;入った場合は変換を実行しています。&lt;br /&gt;&lt;br /&gt;って感じです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1860765223166458360?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1860765223166458360/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1860765223166458360' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1860765223166458360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1860765223166458360'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/07/blog-post.html' title='ドメインの切り替え'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1213650841035073786</id><published>2009-07-12T16:08:00.004+09:00</published><updated>2009-07-12T16:10:07.857+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>FlexのExplorer</title><content type='html'>Flex4を前にしてやるのもなんですが、&lt;br /&gt;なかなか検索でトップに出ないの備忘録で。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://examples.adobe.com/flex3/componentexplorer/explorer.html"&gt;Flex3のコンポーネント&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://examples.adobe.com/flex3/consulting/styleexplorer/Flex3StyleExplorer.html"&gt;Flex3のスタイル&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1213650841035073786?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1213650841035073786/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1213650841035073786' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1213650841035073786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1213650841035073786'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/07/flexexplorer.html' title='FlexのExplorer'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5130844141731180678</id><published>2009-06-28T18:23:00.003+09:00</published><updated>2009-06-28T18:28:09.246+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velocity'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><title type='text'>GAEでVelocity</title><content type='html'>少しテンプレートエンジンを使いたいなぁ。。。って思ったので&lt;br /&gt;Velocityを使うことにしたんだけど、&lt;br /&gt;GAEはファイルシステムはないので、、、って思ってたら&lt;br /&gt;メモリ上で展開できるみたい。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;VelocityContext context = new VelocityContext();&lt;br /&gt;StringWriter writer = new StringWriter();&lt;br /&gt;String template = &lt;br /&gt; "テンプレートのテストです[${name}]" + &lt;br /&gt; "";&lt;br /&gt;context.put("name", "なまえー");  &lt;br /&gt;Velocity.evaluate(context, writer, "vecocityTest", template);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これでwriterに設定できます。&lt;br /&gt;テンプレートを「com.google.appengine.api.datastore.Text」で&lt;br /&gt;保存すれば使えそうですね。&lt;br /&gt;&lt;br /&gt;実行にはVelocity、commons-lang、commons-collectionが必要です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5130844141731180678?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5130844141731180678/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5130844141731180678' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5130844141731180678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5130844141731180678'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/gaevelocity.html' title='GAEでVelocity'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1850088664940735791</id><published>2009-06-27T17:38:00.006+09:00</published><updated>2010-12-11T12:25:07.523+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>GAEで派生データを登録</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;少し前に試した時にダメだったので諦めていたのですが、&lt;br /&gt;再度チャレンジしたらOKだったので投稿しておきます。&lt;br /&gt;&lt;br /&gt;親クラスを準備します。&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;package bz.ziro.slim3.test.model;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.util.Date;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import javax.jdo.JDOHelper;&lt;br /&gt;import javax.jdo.annotations.Extension;&lt;br /&gt;import javax.jdo.annotations.IdGeneratorStrategy;&lt;br /&gt;import javax.jdo.annotations.IdentityType;&lt;br /&gt;import javax.jdo.annotations.PersistenceCapable;&lt;br /&gt;import javax.jdo.annotations.Persistent;&lt;br /&gt;import javax.jdo.annotations.PrimaryKey;&lt;br /&gt;import javax.jdo.annotations.Version;&lt;br /&gt;import javax.jdo.annotations.VersionStrategy;&lt;br /&gt;&lt;br /&gt;import com.google.appengine.api.users.User;&lt;br /&gt;&lt;br /&gt;@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")&lt;br /&gt;@Version(strategy = VersionStrategy.VERSION_NUMBER)&lt;br /&gt;public class Parent implements Serializable {&lt;br /&gt;&lt;br /&gt;    private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;    @SuppressWarnings("unused")&lt;br /&gt;    private static final Logger logger = Logger.getLogger(Parent.class.getName());&lt;br /&gt;&lt;br /&gt;    @PrimaryKey&lt;br /&gt;    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt;    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")&lt;br /&gt;    private String key;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    @Persistent&lt;br /&gt;    private User creator;&lt;br /&gt;    @Persistent&lt;br /&gt;    private Date createDate;&lt;br /&gt;    @Persistent&lt;br /&gt;    private User editor;&lt;br /&gt;    @Persistent&lt;br /&gt;    private Date editDate;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the key&lt;br /&gt;     */&lt;br /&gt;    public String getKey() {&lt;br /&gt;        return key;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param key&lt;br /&gt;     *            the key to set&lt;br /&gt;     */&lt;br /&gt;    public void setKey(String key) {&lt;br /&gt;        this.key = key;&lt;br /&gt;    }&lt;br /&gt;    public User getCreator() {&lt;br /&gt;        return creator;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setCreator(User creator) {&lt;br /&gt;        this.creator = creator;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Date getCreateDate() {&lt;br /&gt;        return createDate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setCreateDate(Date createDate) {&lt;br /&gt;        this.createDate = createDate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public User getEditor() {&lt;br /&gt;        return editor;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setEditor(User editor) {&lt;br /&gt;        this.editor = editor;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Date getEditDate() {&lt;br /&gt;        return editDate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setEditDate(Date editDate) {&lt;br /&gt;        this.editDate = editDate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the version&lt;br /&gt;     */&lt;br /&gt;    public long getVersion() {&lt;br /&gt;        return (Long) JDOHelper.getVersion(this);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;でこのクラスを派生した子クラスを準備します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;package bz.ziro.slim3.test.model;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import javax.jdo.JDOHelper;&lt;br /&gt;import javax.jdo.annotations.IdentityType;&lt;br /&gt;import javax.jdo.annotations.PersistenceCapable;&lt;br /&gt;import javax.jdo.annotations.Persistent;&lt;br /&gt;import javax.jdo.annotations.Version;&lt;br /&gt;import javax.jdo.annotations.VersionStrategy;&lt;br /&gt;&lt;br /&gt;@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")&lt;br /&gt;@Version(strategy = VersionStrategy.VERSION_NUMBER)&lt;br /&gt;public class Child extends Parent implements Serializable {&lt;br /&gt;&lt;br /&gt;    private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;    @SuppressWarnings("unused")&lt;br /&gt;    private static final Logger logger = Logger.getLogger(Child.class.getName());&lt;br /&gt;&lt;br /&gt;    @Persistent&lt;br /&gt;    private String name;&lt;br /&gt;    @Persistent&lt;br /&gt;    private String detail;&lt;br /&gt;    public void setName(String name) {&lt;br /&gt;        this.name = name;&lt;br /&gt;    }&lt;br /&gt;    public String getName() {&lt;br /&gt;        return name;&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * @param detail セットする detail&lt;br /&gt;     */&lt;br /&gt;    public void setDetail(String detail) {&lt;br /&gt;        this.detail = detail;&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * @return detail&lt;br /&gt;     */&lt;br /&gt;    public String getDetail() {&lt;br /&gt;        return detail;&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * @return the version&lt;br /&gt;     */&lt;br /&gt;    public long getVersion() {&lt;br /&gt;        return (Long) JDOHelper.getVersion(this);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これで準備完了です。&lt;br /&gt;ChildオブジェクトをGAE(JDO,BigTable)で登録すれば&lt;br /&gt;Parentの属性も登録できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;実装の通り、登録ユーザや登録日付などテーブル内にある同一の属性を&lt;br /&gt;親クラスを利用することにより、はしょることができます。&lt;br /&gt;まぁ私の場合は更新時などにオブジェクトに都度同一の実装が必要になり&lt;br /&gt;困っていたので助かります。&lt;br /&gt;&lt;br /&gt;JDOを知った時に論理モデル(つうかUML記述？)をそのまま使えるなぁ。。。&lt;br /&gt;って思ってやったらダメだったんですけど、やっぱできるんですね。&lt;br /&gt;&lt;br /&gt;ちなみにDataNucleusでJDBC(HSQLDB)で同じようにやると&lt;br /&gt;Parentテーブルがにもデータがあって。。。って感じになった記憶があります。&lt;br /&gt;※同一のエンティティではないです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ちなみにSlim3のDaoでMetaクラスを利用して検索式を作成しても&lt;br /&gt;ChildMetaに存在しないのでエラーになります。&lt;br /&gt;問い合わせるかはもう少し試してからにしようと思ってます。&lt;br /&gt;&lt;br /&gt;&lt;B&gt;2009/07/08 ※再度試したらSlim3でも動作しました。&lt;/B&gt;&lt;br /&gt;&lt;B&gt;2009/07/26 ※再度試したらSlim3で動作。。。っていうかGAEで動作しませんでした。&lt;br /&gt;ので、Embeddedの話で記述します。&lt;/B&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1850088664940735791?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1850088664940735791/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1850088664940735791' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1850088664940735791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1850088664940735791'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/gae.html' title='GAEで派生データを登録'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4246862352772174348</id><published>2009-06-27T14:42:00.008+09:00</published><updated>2010-12-11T12:25:38.018+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><title type='text'>Slim3で開発を始める。</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Slim3はGAE用に最適化され開発されているフレームワークで&lt;br /&gt;すごくシンプルに開発できるように工夫されています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;今回は現在のSlim3での開発をおさらいしてみましょう。&lt;br /&gt;まだ開発中ですので違う手法になっている可能性もあるので&lt;br /&gt;十分に気をつけていただければ幸いです。&lt;br /&gt;※eclipseでの開発です。&lt;br /&gt;&lt;br /&gt;まず、「http://slim3.googlecode.com/svn」にSVNでアクセスして&lt;br /&gt;「trunk/slim3-blank」からチェックアウトを行います。&lt;br /&gt;ライブラリを落とし込んで来て作成するのもよいのですが&lt;br /&gt;genで使用しているaptの設定などがあるのでblankで作成しておくのが良いでしょう。&lt;br /&gt;&lt;br /&gt;で現在、aptの設定がプロジェクト名に依存しているので&lt;br /&gt;プロジェクト名を変更した場合それを変更する必要があります。&lt;br /&gt;プロジェクトで右クリック「プロパティ」をクリック&lt;br /&gt;「Javaコンパイラー」→「注釈処理」→「ファクトリーパス」において&lt;br /&gt;編集で「lib/slim3-genEA1-SNAPSHOT.jar」を再度指定します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;war/WEB-INF/web.xmlの中にある&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt; &amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;slim3.rootPackage&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;slim3&amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;    &amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;slim3.staticPackages&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;model&amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;の部分をオリジナルの名前空間に変更します。&lt;br /&gt;「slim3.rootPackage」が自分の作成するアプリケーションのルートパッケージで&lt;br /&gt;指定した位置がHotReloadingの対象になります。&lt;br /&gt;「slim3.staticPackages」がHOTの対象外のパッケージを設定します。&lt;br /&gt;カンマ区切りで指定できます。(モデルのパッケージは必ず指定してください)&lt;br /&gt;&lt;br /&gt;これで開発の準備は完了です。&lt;br /&gt;&lt;br /&gt;プロジェクトのルートにあるbuild.xmlで必要なクラスは&lt;br /&gt;自動生成をして開発を進めていきます。&lt;br /&gt;&lt;br /&gt;「gen-model」：エンティティ,Daoとそれぞれのテストクラスを出力してくれます。&lt;br /&gt;「gen-controller」：controller,jspとそれぞれのテストクラスを出力してくれます。&lt;br /&gt;※それぞれを指定する場合、パッケージ名は必要ありません。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;build.xmlのprojectタグにある「name="xxxx"」を&lt;br /&gt;自分のプロジェクト名に変更してあげる必要があります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;「gen-controller」で「index」と指定すると&lt;br /&gt;ひとまずアプリケーションとして動作できるようになります。&lt;br /&gt;※既存のjspやcontrollerは消しておいた方が良いかな。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4246862352772174348?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4246862352772174348/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4246862352772174348' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4246862352772174348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4246862352772174348'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/slim3_27.html' title='Slim3で開発を始める。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8730774417284240736</id><published>2009-06-21T11:34:00.003+09:00</published><updated>2009-06-21T15:38:41.079+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='認証'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><category scheme='http://www.blogger.com/atom/ns#' term='DIGEST'/><title type='text'>SVNの設定(認証)</title><content type='html'>さて、SVNのインストールが終わったので設定します。&lt;br /&gt;Apacheのhttpd.confに&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;Location /svn/mog&amp;gt;&lt;br /&gt;  DAV svn&lt;br /&gt;  SVNPath /home/svn/mog&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;を追加します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;svnadmin create /home/svn/mog&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を行うとリポジトリが作成されます。&lt;br /&gt;これでクライアントからアクセスできるはずですが&lt;br /&gt;apacheの起動ユーザに対して権限があることが条件です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さてDIGEST認証を使うにはApacheにDIGEST認証モジュールが必要です。&lt;br /&gt;※Apacheのモジュールでインストールしてあれば問題ありません。&lt;br /&gt;&lt;br /&gt;ソースのmodules/aaaに移動して&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/usr/local/apache2/bin/apxs -D DEV_RANDOM -c ./mod_auth_digest.c&lt;br /&gt;/usr/local/apache2/bin/apxs -i -a -n auth_digest mod_auth_digest.la&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と行うとhttpd.confにLoadModuleが追加されるはずです。&lt;br /&gt;これで準備はOK&lt;br /&gt;&lt;br /&gt;Apacheに&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;Location /svn/test&amp;gt;&lt;br /&gt;&lt;br /&gt;  DAV svn&lt;br /&gt;  SVNPath /home/svn/test&lt;br /&gt;&lt;br /&gt;  AuthType Digest&lt;br /&gt;  AuthName "SVN AUTH"&lt;br /&gt;  AuthUserFile /home/svn/.htdigest&lt;br /&gt;  Require valid-user&lt;br /&gt;&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;って感じで追加します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;htdigest -c /home/svn/.htdigest "SVN AUTH" username&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;でパスワードを入力してApacheを再起動します。&lt;br /&gt;で再起動すればOKです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8730774417284240736?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8730774417284240736/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8730774417284240736' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8730774417284240736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8730774417284240736'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/svn_21.html' title='SVNの設定(認証)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6664112265502135650</id><published>2009-06-20T16:00:00.005+09:00</published><updated>2009-06-22T08:24:40.792+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>SVNをインストール</title><content type='html'>ソースを管理していたCVSのディスクがぶっ飛び、&lt;br /&gt;せっかくなんでSVNをインストールしようと思い立つ&lt;br /&gt;&lt;br /&gt;前準備で&lt;br /&gt;&lt;br /&gt;http://www.oracle.com/technology/software/products/berkeley-db/index.html&lt;br /&gt;※ごめんなさい。。。後述しますが、、、いらないかも。&lt;br /&gt;&lt;br /&gt;からBerkeleyDBをダウンロードしてきて&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;cd dist/build-unix&lt;br /&gt;../dist/configure &lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;を行います。&lt;br /&gt;build-unixに入ってからconfigureを行うのがポイントです。&lt;br /&gt;&lt;br /&gt;/usr/local/BerkeleyDB.4.7&lt;br /&gt;ができています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;echo "/usr/local/BerkeleyDB.4.7/lib" &amp;gt;&amp;gt; /etc/ld.so.conf&lt;br /&gt;/sbin/ldconfig&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を行って共有ライブラリに追加しておきます。&lt;br /&gt;&lt;br /&gt;でApacheをインストールします。&lt;br /&gt;http://www.apache.jp/misc/download.html&lt;br /&gt;などから持ってきます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;./configure --enable-modules=most --enable-shared=max --enable-dav=yes --with-berkeley-db=/usr/local/BerkeleyDB.4.7&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を行います。&lt;br /&gt;モジュールをすべて入れています。&lt;br /&gt;&lt;br /&gt;次にいよいよSubversionです。&lt;br /&gt;http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=74&lt;br /&gt;からダウンロードしてきます。&lt;br /&gt;sqlliteのソースなどがいるのでdepsもダウンロードしておきます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;./configure --with-apxs=/usr/local/apache2/bin/apxs \&lt;br /&gt;--with-apr=/usr/local/apache2/bin/apr-1-config \&lt;br /&gt;--with-apr-util=/usr/local/apache2/bin/apu-1-config&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;一応これで完了です。&lt;br /&gt;・・・んーと。。。文献だとberkeleyを&lt;br /&gt;configureに設定していたんですけど。。。&lt;br /&gt;なんかうまくいかなかったので外しました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6664112265502135650?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6664112265502135650/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6664112265502135650' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6664112265502135650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6664112265502135650'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/svn.html' title='SVNをインストール'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5347181740653765708</id><published>2009-06-13T20:26:00.004+09:00</published><updated>2009-06-14T11:30:58.816+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='ガツン'/><category scheme='http://www.blogger.com/atom/ns#' term='Seasar'/><title type='text'>ガツンとSlim3</title><content type='html'>はてさて「Seasar Conference 2009 Spring」行ってきました。&lt;br /&gt;行ってきたというより、ひがさんの話を聞いただけですけど。&lt;br /&gt;&lt;br /&gt;まぁ単純に感想を言うと、為になったというか。。。&lt;br /&gt;バイトを連れて言ったのですがわかりやすくてとても&lt;br /&gt;参考になったというところでしょうか。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;「ガツン」の節で始まるとは少し予想してませんでしたけど。&lt;br /&gt;&lt;br /&gt;で、ひがさんに感化されたわけではないのですが&lt;br /&gt;あんまりこういうことは書かんのようにしていますが一応言っておきます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;まぁ言語はなんでも良いんですよ。&lt;br /&gt;ようは作るものだとか作りたいものに対してどうなのか？&lt;br /&gt;&lt;br /&gt;Perlでも優れたシステムはあるし、RoRでもへなちょこなシステムはある。&lt;br /&gt;※あくまでPerlは古いって意味合いだけ使ってますし&lt;br /&gt;  RoRは言語じゃないですけど、新しいって意味で使ってます。&lt;br /&gt;&lt;br /&gt;言語は言語屋さんにお任せして(もちろん要望等は出しましょう)&lt;br /&gt;私らはシステムを向きましょう。&lt;br /&gt;&lt;br /&gt;だから私は「システムに絶対はない」と言うとるわけでして。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5347181740653765708?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5347181740653765708/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5347181740653765708' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5347181740653765708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5347181740653765708'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/06/slim3.html' title='ガツンとSlim3'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7941414020376982807</id><published>2009-05-31T21:56:00.005+09:00</published><updated>2010-12-11T12:26:16.670+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='limit'/><category scheme='http://www.blogger.com/atom/ns#' term='Order'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='Meta'/><title type='text'>Slim3でおーだーばい。</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;ShopMeta shopMeta = new ShopMeta();&lt;br /&gt;List&amp;lt;Shop&amp;gt; list = from(Shop.class).range(0,10).orderBy(shopMeta.createDate.desc()).getResultList();&lt;br /&gt;List&amp;lt;BeanMap&amp;gt; shopList = new ArrayList&amp;lt;BeanMap&amp;gt;();&lt;br /&gt;for (Shop b : list) {&lt;br /&gt;  BeanMap m = new BeanMap();&lt;br /&gt;  BeanUtil.copy(b, m);&lt;br /&gt;  shopList.add(m);&lt;br /&gt;}&lt;br /&gt;requestScope("newShopList", shopList);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;んー。。。エクセレント。なんかきれいです。&lt;br /&gt;なんか直感的なソースが良いですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7941414020376982807?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7941414020376982807/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7941414020376982807' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7941414020376982807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7941414020376982807'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3_3810.html' title='Slim3でおーだーばい。'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5609055569002749866</id><published>2009-05-31T21:51:00.004+09:00</published><updated>2010-12-11T12:27:41.786+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='検索'/><category scheme='http://www.blogger.com/atom/ns#' term='Meta'/><category scheme='http://www.blogger.com/atom/ns#' term='認証'/><category scheme='http://www.blogger.com/atom/ns#' term='ユーザ'/><title type='text'>Slim3でユーザの検索</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   UserService userService = UserServiceFactory.getUserService();&lt;br /&gt;   User user = userService.getCurrentUser();&lt;br /&gt;&lt;br /&gt;   ShopMeta shopMeta = new ShopMeta();&lt;br /&gt;         List&amp;lt;Shop&amp;gt; list = from(Shop.class).where(shopMeta.creator.eq(user)).getResultList();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ShopMetaは自動的に作られます。(aptとかをプロジェクトで設定します)&lt;br /&gt;creatorはJDOで保存しているカラムの一部です。&lt;br /&gt;※aptについては今勉強中です。後日設定方法を書きます。&lt;br /&gt;&lt;br /&gt;なんかおしゃれになってきましたね。&lt;br /&gt;もし私がゴクウだったら「おらワクワクしてきたぞ状態」です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5609055569002749866?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5609055569002749866/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5609055569002749866' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5609055569002749866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5609055569002749866'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3_31.html' title='Slim3でユーザの検索'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-619148825965367563</id><published>2009-05-26T23:13:00.006+09:00</published><updated>2010-12-11T12:28:12.900+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='ResourceBundle'/><category scheme='http://www.blogger.com/atom/ns#' term='Taglib'/><title type='text'>Slim3でリソース表示(訂正)</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;※以下コメントを受けまして、少し訂正を入れています。&lt;br /&gt;　訂正と言うか注釈ですね。。。&lt;br /&gt;&lt;br /&gt;Slim3を触っています。&lt;br /&gt;&lt;span style="font-style:italic;"&gt;構築中っていうことでまだ単純な機能が足りません。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;※訂正：単純な機能ではなく、私のスキルが足りなかったようです。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ん。。。JSPにリソースを表示したい。。。&lt;br /&gt;ってことでオリジナルで作ってみました。&lt;br /&gt;&lt;span style="font-style:italic;"&gt;おそらく近日本家で実装されますんで&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;※訂正：コメントより、作られるのではなくJSTLで既にあるようです。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;taglib作成の参考として読んでください。&lt;br /&gt;&lt;br /&gt;まずtldファイルを作成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html:collapse"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;taglib xmlns="http://java.sun.com/xml/ns/j2ee"&lt;br /&gt;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"&lt;br /&gt;  version="2.0"&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;description&amp;gt;Mog resource library&amp;lt;/description&amp;gt;&lt;br /&gt;  &amp;lt;display-name&amp;gt;Mog resource&amp;lt;/display-name&amp;gt;&lt;br /&gt;  &amp;lt;tlib-version&amp;gt;1.1&amp;lt;/tlib-version&amp;gt;&lt;br /&gt;  &amp;lt;short-name&amp;gt;res&amp;lt;/short-name&amp;gt;&lt;br /&gt;  &amp;lt;uri&amp;gt;http://mog.ziro.bz/resource&amp;lt;/uri&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;function&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;&lt;br /&gt;    resource bundle get&lt;br /&gt;    &amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;get&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;function-class&amp;gt;bz.ziro.mog.jsp.Resource&amp;lt;/function-class&amp;gt;&lt;br /&gt;    &amp;lt;function-signature&amp;gt;java.lang.String get(java.lang.String)&amp;lt;/function-signature&amp;gt;&lt;br /&gt;    &amp;lt;example&amp;gt;&lt;br /&gt;      ${f:get(param)}&lt;br /&gt;    &amp;lt;/example&amp;gt;&lt;br /&gt;  &amp;lt;/function&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/taglib&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;で作成したところにあるfunction-classを生成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;package bz.ziro.mog.jsp;&lt;br /&gt;&lt;br /&gt;import java.util.ResourceBundle;&lt;br /&gt;&lt;br /&gt;public final class Resource {&lt;br /&gt;&lt;br /&gt; private static ResourceBundle resources = ResourceBundle.getBundle("application");&lt;br /&gt; &lt;br /&gt; public static String get(String aKey) {&lt;br /&gt;  return resources.getString(aKey);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ResourceBundleの生成に使っている"application"はクラスパス＋名称になります。&lt;br /&gt;のでこの設定だとクラスパス直下にapplication.propertiesやapplication_ja.propertiesを&lt;br /&gt;作成しておきます。※ResourceBundleは国際化されています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;%@taglib prefix="res" uri="http://mog.ziro.bz/resource"%&amp;gt;&lt;br /&gt;&lt;br /&gt;${res:get("mog.l.title")}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;で表示することができます。&lt;br /&gt;uriに指定するのはtldのuriに記述したURIです。&lt;br /&gt;こういうtaglib作成があるんですね。Slim3のFunctionを参考にさせてもらいました。&lt;br /&gt;&lt;br /&gt;TDDってもんを完全に守ったこともない僕にはまだまだ。。。&lt;br /&gt;それでもコミッタを夢見るの巻きでした。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-619148825965367563?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/619148825965367563/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=619148825965367563' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/619148825965367563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/619148825965367563'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3_26.html' title='Slim3でリソース表示(訂正)'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8064912741155317377</id><published>2009-05-25T01:08:00.003+09:00</published><updated>2009-05-25T01:12:10.039+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='Struts'/><title type='text'>Slim3Struts廃止・・・</title><content type='html'>Struts本命の僕には悲しいニュースです。&lt;br /&gt;&lt;br /&gt;ただ。。。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://event.seasarfoundation.org/sc2009spring/" title="Seasar Conference 2009 Spring - 6/13(土) 東京, 法政大学市ヶ谷キャンパス 外濠校舎6階"&gt;&lt;img src="http://event.seasarfoundation.org/sc2009spring/img/common/conf2009spring_Half.gif" width="234" height="60" alt="Seasar Conference 2009 Spring - 6/13(SAT), Tokyo"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ここで面白い話が聞けそうです！&lt;br /&gt;ちょっくら行く予定です。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8064912741155317377?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8064912741155317377/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8064912741155317377' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8064912741155317377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8064912741155317377'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3struts.html' title='Slim3Struts廃止・・・'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1927799930224256212</id><published>2009-05-23T15:04:00.003+09:00</published><updated>2009-05-23T15:09:13.559+09:00</updated><title type='text'>HTMLにFlashを埋め込む</title><content type='html'>http://code.google.com/p/swfobject/&lt;br /&gt;&lt;br /&gt;からswfobject.jsを取ってきて読み込みます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;script type="text/javascript" src="assets/js/swfobject.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;div id="flashcontent_container"&amp;gt;&lt;br /&gt;FlashPlayerがない&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;JavaSctiprなどで埋め込みます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;  var so = new SWFObject("MogPlayer.swf", "MogPlayer", "260", "400", "9");&lt;br /&gt;  so.addParam("allowScriptAccess", "always");&lt;br /&gt;  so.addParam("menu", "false");&lt;br /&gt;  so.addParam("scale", "noscale");&lt;br /&gt;  so.setAttribute("id", "playerWrapper");&lt;br /&gt;  so.write("flashcontent_container");&lt;br /&gt;  &lt;br /&gt;  SWFID = "playerWrapper";&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1927799930224256212?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1927799930224256212/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1927799930224256212' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1927799930224256212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1927799930224256212'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/htmlflash.html' title='HTMLにFlashを埋め込む'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7103243999806198018</id><published>2009-05-23T15:00:00.002+09:00</published><updated>2009-05-23T15:04:01.590+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RadioButton'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>FlexでRadioButton</title><content type='html'>Flexでラジオボタンを設定します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;            &amp;lt;mx:RadioButtonGroup id="answer"/&amp;gt;&lt;br /&gt;            &amp;lt;mx:RadioButton id="answer1" groupName="answer" value="1" label="選択肢１" width="100%"/&amp;gt;&lt;br /&gt;            &amp;lt;mx:RadioButton id="answer2" groupName="answer" value="2" label="選択肢２" width="100%"/&amp;gt;&lt;br /&gt;            &amp;lt;mx:RadioButton id="answer3" groupName="answer" value="3" label="選択肢３" width="100%"/&amp;gt;&lt;br /&gt;            &amp;lt;mx:RadioButton id="answer4" groupName="answer" value="4" label="選択肢４" width="100%"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;でラジオボタンを作成します。&lt;br /&gt;その後スクリプトなどでRadioButtonGroupで指定したIDのselectedValueを利用して&lt;br /&gt;どれが選択されているかがわかります。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;             if ( nowAnswer == answer.selectedValue ) {&lt;br /&gt;              Alert.show("正解！");&lt;br /&gt;             } else {&lt;br /&gt;              Alert.show("ブー");&lt;br /&gt;             }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7103243999806198018?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7103243999806198018/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7103243999806198018' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7103243999806198018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7103243999806198018'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/flexradiobutton.html' title='FlexでRadioButton'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5336001400244637739</id><published>2009-05-16T17:15:00.002+09:00</published><updated>2009-05-16T17:17:51.474+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セッション'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Javaでセッション管理</title><content type='html'>JavaのWebアプリでオブジェクトをセッションに&lt;br /&gt;登録、削除した時にイベントを発生する場合&lt;br /&gt;HttpSessionBindingListenerをimplementするとイベントを発生することができます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Account implements HttpSessionBindingListener {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void valueBound(HttpSessionBindingEvent arg0) {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void valueUnbound(HttpSessionBindingEvent arg0) {&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;って感じです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5336001400244637739?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5336001400244637739/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5336001400244637739' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5336001400244637739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5336001400244637739'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/java.html' title='Javaでセッション管理'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3447571339145030378</id><published>2009-05-16T08:28:00.002+09:00</published><updated>2009-05-16T08:35:32.865+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='DataNucleus'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><title type='text'>DataNucleusでJDBC接続</title><content type='html'>datanucleus.propertiesを作成して&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.jdo.JDOPersistenceManagerFactory&lt;br /&gt;&lt;br /&gt;javax.jdo.option.ConnectionDriverName=org.hsqldb.jdbcDriver&lt;br /&gt;javax.jdo.option.ConnectionURL=jdbc:hsqldb:hsql://localhost/sealion_db&lt;br /&gt;javax.jdo.option.ConnectionUserName=sa&lt;br /&gt;javax.jdo.option.ConnectionPassword=&lt;br /&gt;javax.jdo.option.Mapping=hsql&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;クラスパスのトップにおいて&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; private static final PersistenceManagerFactory pmfInstance =&lt;br /&gt;        JDOHelper.getPersistenceManagerFactory("datanucleus.properties");&lt;br /&gt;    public static PersistenceManagerFactory get() {&lt;br /&gt;        return pmfInstance;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;でPersistenceManagerFactoryを取得します。&lt;br /&gt;&lt;br /&gt;これと同様にMETA-INF/jdoconfig.xmlを作成して&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"&lt;br /&gt;   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;   xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig"&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;persistence-manager-factory name="transactions-optional"&amp;gt;&lt;br /&gt;       &amp;lt;property name="javax.jdo.PersistenceManagerFactoryClass"&lt;br /&gt;           value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="javax.jdo.option.ConnectionURL" value="appengine"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="javax.jdo.option.NontransactionalRead" value="true"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="javax.jdo.option.NontransactionalWrite" value="true"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="javax.jdo.option.RetainValues" value="true"/&amp;gt;&lt;br /&gt;       &amp;lt;property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/&amp;gt;&lt;br /&gt;   &amp;lt;/persistence-manager-factory&amp;gt;&lt;br /&gt;&amp;lt;/jdoconfig&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;と行います。&lt;br /&gt;その場合は&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; private static final PersistenceManagerFactory pmfInstance =&lt;br /&gt;        JDOHelper.getPersistenceManagerFactory("transactions-optional");&lt;br /&gt;    public static PersistenceManagerFactory get() {&lt;br /&gt;        return pmfInstance;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;って感じになります。&lt;br /&gt;何個もセッションを用意する場合は、指定子（transactions-optional）を&lt;br /&gt;変更して追加します。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3447571339145030378?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3447571339145030378/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3447571339145030378' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3447571339145030378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3447571339145030378'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/datanucleusjdbc.html' title='DataNucleusでJDBC接続'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8022355420340237126</id><published>2009-05-15T13:03:00.002+09:00</published><updated>2009-05-15T13:07:03.704+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DataNucleus'/><category scheme='http://www.blogger.com/atom/ns#' term='NULL'/><category scheme='http://www.blogger.com/atom/ns#' term='HSQLDB'/><title type='text'>HSQLDBとDataNucleus</title><content type='html'>hsqldb-1.9.0-alpha2を使ってたら&lt;br /&gt;スキーマを作成するところで&lt;br /&gt;&lt;br /&gt;java.sql.SQLException: unexpected token: NULL&lt;br /&gt;&lt;br /&gt;と出ます。&lt;br /&gt;DataNucleusのせいだと思っていたのですが&lt;br /&gt;良く調べたら、create tableで&lt;br /&gt;&lt;br /&gt;    "NAME" VARCHAR(256) NULL,&lt;br /&gt;&lt;br /&gt;みたいな指定ができないようです。&lt;br /&gt;何か久々に無駄につかれた。&lt;br /&gt;※同時に２個調査しようとするのが悪い&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8022355420340237126?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8022355420340237126/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8022355420340237126' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8022355420340237126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8022355420340237126'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/hsqldbdatanucleus.html' title='HSQLDBとDataNucleus'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7704403065080726523</id><published>2009-05-11T20:32:00.003+09:00</published><updated>2009-05-11T20:40:47.511+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DataNucleus'/><category scheme='http://www.blogger.com/atom/ns#' term='Enhance'/><title type='text'>DataNucleusをEclipseで使う</title><content type='html'>GAEだと勝手にEnhancerが動作していますが&lt;br /&gt;JDOを単独で使うと都度「実行」を行っていました。&lt;br /&gt;・・・しかしなんかあるだろうと思ったら本家にありました。&lt;br /&gt;&lt;br /&gt;http://sourceforge.net/project/showfiles.php?group_id=222750&amp;package_id=273215&lt;br /&gt;&lt;br /&gt;ここからJARをダウンロードしてきて&lt;br /&gt;Eclipseのpluginディレクトリに追加します。&lt;br /&gt;Eclipseを再起動するとプロジェクトの右クリックに&lt;br /&gt;「DataNucleus」が追加されます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/SggNoBywYEI/AAAAAAAAAE0/bxawASo-dbs/s1600-h/enhance.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 105px;" src="http://3.bp.blogspot.com/_wlXf9TOPv20/SggNoBywYEI/AAAAAAAAAE0/bxawASo-dbs/s320/enhance.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5334528739947601986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wlXf9TOPv20/SggNnw2UftI/AAAAAAAAAEs/gataYrLeDKw/s1600-h/add.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 96px;" src="http://2.bp.blogspot.com/_wlXf9TOPv20/SggNnw2UftI/AAAAAAAAAEs/gataYrLeDKw/s320/add.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5334528735399149266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この画像の通り、AddするとDataNucleusがサポートされます。&lt;br /&gt;その後Autoを設定しておくと更新ごとにEnhanceしてくれます。&lt;br /&gt;※プロジェクトの設定でLog4Jのファイルを変更しないとエラーが出ます。&lt;br /&gt;&lt;br /&gt;スキーマなどもここで動作します。&lt;br /&gt;これで少し開発が簡単にいくかな？&lt;br /&gt;※POJOからxmlファイルの作成もしてくれそうですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7704403065080726523?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7704403065080726523/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7704403065080726523' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7704403065080726523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7704403065080726523'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/datanucleuseclipse.html' title='DataNucleusをEclipseで使う'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wlXf9TOPv20/SggNoBywYEI/AAAAAAAAAE0/bxawASo-dbs/s72-c/enhance.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8766731474867983793</id><published>2009-05-09T07:55:00.003+09:00</published><updated>2009-05-09T12:43:11.246+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='DataNucleus'/><title type='text'>DataNucleusを動かしてみる</title><content type='html'>GAEやSlim3を動作させてきました。&lt;br /&gt;せっかくなのでSlim3を生で使いたいと思い立ちました。&lt;br /&gt;Hibernate,S2DAOなどを使って。。。と思いましたが&lt;br /&gt;せっかくなのでDataNucleusを使ってHSQLDBにアクセスしたと思います。&lt;br /&gt;※とは言ってもサンプルです。&lt;br /&gt;&lt;br /&gt;まず、DataNucleusのページから&lt;br /&gt;http://sourceforge.net/project/showfiles.php?group_id=222750&lt;br /&gt;&lt;br /&gt;・core&lt;br /&gt;・rdbms&lt;br /&gt;・enhancer&lt;br /&gt;・sample&lt;br /&gt;&lt;br /&gt;をダウンロードしてきます。&lt;br /&gt;&lt;br /&gt;ObjectWebのASMサイトから&lt;br /&gt;http://forge.ow2.org/project/download.php?group_id=23&amp;file_id=9309&lt;br /&gt;&lt;br /&gt;・asm&lt;br /&gt;&lt;br /&gt;をダウンロードしてきて&lt;br /&gt;&lt;br /&gt;Log4Jから&lt;br /&gt;http://logging.apache.org/log4j/1.2/download.html&lt;br /&gt;&lt;br /&gt;・Log4J&lt;br /&gt;&lt;br /&gt;をダウンロードしてきます。&lt;br /&gt;ApacheJDOから。。。といきたいところですが&lt;br /&gt;JDOの2.3が必要ですので&lt;br /&gt;http://www.datanucleus.org/downloads/maven2/javax/jdo/jdo2-api/&lt;br /&gt;&lt;br /&gt;・JDO&lt;br /&gt;&lt;br /&gt;をダウンロードしてきます。&lt;br /&gt;HSQLDBから&lt;br /&gt;http://sourceforge.net/project/platformdownload.php?group_id=23316&amp;sel_platform=14519&lt;br /&gt;&lt;br /&gt;・HSQLDB&lt;br /&gt;&lt;br /&gt;をダウンロードしてきます。&lt;br /&gt;&lt;br /&gt;JDOの2.3ってGAEでも使ってるんですけど良いんでしょうね。&lt;br /&gt;※SNAPSHOTからea(アーリーアクセス？)に代わってますね。&lt;br /&gt;&lt;br /&gt;解凍してきたHSQLDBの&lt;br /&gt;demo/runServer.bat実行してDBを立ち上げます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;で、DataNucleusのsampleを解凍してeclipseに展開します。&lt;br /&gt;でダウンロードしてきたそれぞれのjarをlibディレクトリなどに展開。&lt;br /&gt;jarをクラスパスに追加してMainを実行します！&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・・あれ？うごかない。。。&lt;br /&gt;って調べていたら&lt;br /&gt;JDOの設定ファイル「package.jdo」がない。。。&lt;br /&gt;あれ？ormファイルならある。。。なんかの仕様変更ですかね。。。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;http://www.datanucleus.org/products/accessplatform_1_0/guides/jdo/tutorial.html&lt;br /&gt;&lt;br /&gt;にあるjdoファイルをコピーして作成します。&lt;br /&gt;・・・それでも実行してもダメでした。&lt;br /&gt;&lt;br /&gt;buildファイルなら実行可能なんですが、、、&lt;br /&gt;GAEで見たことあるような、、、&lt;br /&gt;&lt;br /&gt;おー！Enhancerですね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;「org.datanucleus.enhancer.DataNucleusEnhancer」を&lt;br /&gt;「src\java\org\datanucleus\samples\jdo\tutorial\package.jdo」を引数にして&lt;br /&gt;実行する必要があります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・これで実行できますがこれは何の為にやってるんだか。。。&lt;br /&gt;&lt;br /&gt;ひとまずこれで実行可能になります。&lt;br /&gt;さぁ開発開始だぁー！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8766731474867983793?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8766731474867983793/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8766731474867983793' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8766731474867983793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8766731474867983793'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/datanucleus.html' title='DataNucleusを動かしてみる'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3942055952038787487</id><published>2009-05-07T20:06:00.004+09:00</published><updated>2009-05-07T20:10:15.443+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Indexes'/><title type='text'>JDO関連のデプロイ後の遅延</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/SgLA7P-GswI/AAAAAAAAAEk/Lb3b-Fo8Uow/s1600-h/indexes.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 117px;" src="http://3.bp.blogspot.com/_wlXf9TOPv20/SgLA7P-GswI/AAAAAAAAAEk/Lb3b-Fo8Uow/s320/indexes.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5333037032891921154" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;GAEのアプリケーション管理画面の&lt;br /&gt;「DataStore」→「Indexes」を見ると画像のような画面が出ます。&lt;br /&gt;ここの「Serving」が「Building」ってなってると&lt;br /&gt;パーシスタントクラスの関連を構築中だって意味になります。&lt;br /&gt;&lt;br /&gt;こないだやった時は半日(途中睡眠があるのでもう少し早いかも)かかりました。&lt;br /&gt;デプロイした後試せるのは結構時間がかかります。&lt;br /&gt;&lt;br /&gt;http://code.google.com/intl/ja/appengine/kb/general.html#indexes&lt;br /&gt;&lt;br /&gt;ここにいろいろ書いてあります。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3942055952038787487?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3942055952038787487/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3942055952038787487' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3942055952038787487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3942055952038787487'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/jdo.html' title='JDO関連のデプロイ後の遅延'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_wlXf9TOPv20/SgLA7P-GswI/AAAAAAAAAEk/Lb3b-Fo8Uow/s72-c/indexes.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7000182428427392689</id><published>2009-05-07T19:56:00.004+09:00</published><updated>2009-05-07T20:04:21.131+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='パス'/><category scheme='http://www.blogger.com/atom/ns#' term='URL'/><title type='text'>Slim3でディレクトリを表現</title><content type='html'>Slim3では設定ファイル「slim3_configuration.properties」に&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;slim3.controllerPackage=bz.ziro.mog.slim3.controller&lt;br /&gt;slim3.viewPrefix=/WEB-INF/jsp&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;という風にパッケージとJSPのディレクトリを記述して&lt;br /&gt;URL(ディレクトリ)を表現していきます。&lt;br /&gt;デモアプリにもあるように。。。なんかいっぱいコントローラーが出来上がってくると&lt;br /&gt;&lt;br /&gt;・管理が煩雑になるのでは。。。&lt;br /&gt;・いやいやきっと抜け道がある。。。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・後者でした。&lt;br /&gt;「mng」というディレクトリを作ってその下に&lt;br /&gt;アプリケーションを画像の通りに構築します。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_wlXf9TOPv20/SgK_kKxAhAI/AAAAAAAAAEc/4hTh46NEpAs/s1600-h/dir.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 208px; height: 245px;" src="http://1.bp.blogspot.com/_wlXf9TOPv20/SgK_kKxAhAI/AAAAAAAAAEc/4hTh46NEpAs/s320/dir.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5333035536846193666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_wlXf9TOPv20/SgK_kBtqtnI/AAAAAAAAAEU/b-DFtDTOR84/s1600-h/pkg.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 217px; height: 162px;" src="http://3.bp.blogspot.com/_wlXf9TOPv20/SgK_kBtqtnI/AAAAAAAAAEU/b-DFtDTOR84/s320/pkg.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5333035534416262770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;「/mng/」にアクセスすると、MngControllerが動作してくれます。&lt;br /&gt;※JSPは「mng下にファイルです」&lt;br /&gt;「/mng/shop/」にアクセスすると mng.ShopControllerが動作してくれます。&lt;br /&gt;※JSPは「mng/shop下にファイルです」&lt;br /&gt;&lt;br /&gt;やっぱこのくらいのことは考えてあるんですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7000182428427392689?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7000182428427392689/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7000182428427392689' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7000182428427392689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7000182428427392689'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3_07.html' title='Slim3でディレクトリを表現'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_wlXf9TOPv20/SgK_kKxAhAI/AAAAAAAAAEc/4hTh46NEpAs/s72-c/dir.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3461142502322452694</id><published>2009-05-07T19:47:00.004+09:00</published><updated>2010-12-11T12:27:12.460+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='FormFile'/><title type='text'>GAEにデータを保存</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さて、Slim3を手に入れ、Strutsでアップロードを可能にした私は&lt;br /&gt;ついにデータを保存するということに挑戦。&lt;br /&gt;っていうか簡単なんですけどね。&lt;br /&gt;&lt;br /&gt;単純にBlobデータを使いました。&lt;br /&gt;ファイルをアップロードして&lt;br /&gt;FormFileからInputStreamを取り出して&lt;br /&gt;ByteArrayOutputStreamを利用して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  ByteArrayOutputStream baos = new ByteArrayOutputStream();&lt;br /&gt;  InputStream stream = aFile.getInputStream();&lt;br /&gt;  byte[] buffer = new byte[8192];&lt;br /&gt;  //終了まで読み込み続ける&lt;br /&gt;  while (stream.read(buffer) != -1) {&lt;br /&gt;   baos.write(buffer);&lt;br /&gt;  }&lt;br /&gt;  Blob imageBlob = new Blob(baos.toByteArray());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;[com.google.appengine.api.datastore.Blob]ですね。&lt;br /&gt;を生成します。&lt;br /&gt;&lt;br /&gt;これをJDOで永続化してBigTableに保存します。&lt;br /&gt;&lt;br /&gt;でそれを検索して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   Image image = getPersistentImage(Long.valueOf(shopId),Long.valueOf(imageId));&lt;br /&gt;   Blob blob = image.getImage();&lt;br /&gt;   rtnByte = blob.getBytes();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;※ImageってのはBlobを保存したパーシスタントクラスです。&lt;br /&gt;&lt;br /&gt;取得します。&lt;br /&gt;これをストリームに描きだしたりすると画像が出ます！&lt;br /&gt;&lt;br /&gt;Blobを見た時からこれをやりたかったんですけどね。&lt;br /&gt;Slim3の力を借りてここまでたどり着きました！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-3461142502322452694?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/3461142502322452694/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=3461142502322452694' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3461142502322452694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/3461142502322452694'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/gae.html' title='GAEにデータを保存'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5075223058681488580</id><published>2009-05-05T02:45:00.005+09:00</published><updated>2010-12-11T12:26:39.041+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>ひとまずGAEでSlim3を動かしてみよう！</title><content type='html'>&lt;strong style="color:red;font-weight:bold;"&gt;&lt;br /&gt;すでにこの設定などは古くなっている可能性があります。&lt;br /&gt;&lt;br /&gt;Slim3の開発はこんなブログより正式ドキュメントが有効です。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3appengine/"&gt;Slim3サイト&lt;/a&gt;&lt;br /&gt;非公式と言われていますが充実した日本語サイトもあります。&lt;br /&gt;&lt;a href="http://sites.google.com/site/slim3documentja/"&gt;Slim3日本語サイト&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;GAEでSlim3の使い方をやってみます！&lt;br /&gt;&lt;br /&gt;みなさん。SVNでアクセスは可能ですか？&lt;br /&gt;http://slim3.googlecode.com/svn&lt;br /&gt;だったら上記にリポジトリパスを設定しましょう。&lt;br /&gt;※eclipseっす。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_wlXf9TOPv20/Sf8q1qhuyZI/AAAAAAAAAEM/mpqIFkYdHQ8/s1600-h/slim3_svn.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 146px;" src="http://2.bp.blogspot.com/_wlXf9TOPv20/Sf8q1qhuyZI/AAAAAAAAAEM/mpqIFkYdHQ8/s320/slim3_svn.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5332027585267157394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ここから「slim3-demo」チェックアウトして、&lt;br /&gt;後はGAEでデプロイするだけです。&lt;br /&gt;&lt;br /&gt;※アプリケーションIDは自分のアプリケーションに設定して、&lt;br /&gt;　バージョンも１つにしましょう。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;思いのほかデプロイが簡単でびっくりしています！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5075223058681488580?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5075223058681488580/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5075223058681488580' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5075223058681488580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5075223058681488580'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/gaeslim3.html' title='ひとまずGAEでSlim3を動かしてみよう！'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_wlXf9TOPv20/Sf8q1qhuyZI/AAAAAAAAAEM/mpqIFkYdHQ8/s72-c/slim3_svn.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1375186689521767641</id><published>2009-05-04T19:17:00.003+09:00</published><updated>2009-05-04T19:44:41.616+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Slim3'/><category scheme='http://www.blogger.com/atom/ns#' term='ファイルアップロード'/><title type='text'>押してもだめならSlim3化</title><content type='html'>GAEにてファイルアップロードを行っていました。&lt;br /&gt;&lt;br /&gt;ひがやすを氏がStrutsでのファイルアップロードを成功したようで&lt;br /&gt;オープンソースらしいので少しお知恵を拝借しようと。。。&lt;br /&gt;http://d.hatena.ne.jp/higayasuo/20090411/1239460908&lt;br /&gt;&lt;br /&gt;と思い少しソース(＋ブログ)を眺めていたら。。。&lt;br /&gt;「俺は一体何をしているのだろうと。。。」&lt;br /&gt;と思ってしまいました。&lt;br /&gt;※ちなみに「S3MultipartRequestHandler」を利用して&lt;br /&gt;　やっているみたいですね。&lt;br /&gt;久々にソース（＋ブログ）に感動しました。&lt;br /&gt;&lt;br /&gt;Seasarには結構前にトライしましたが&lt;br /&gt;客先に乗せるのは困難だと判断して少し離れていましたが&lt;br /&gt;Slim3の考えには賛同できる気がします。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ってことでソースを借りるのではなく「On」させてもらおうと。。。&lt;br /&gt;まぁ挫折の可能性は高いですが。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1375186689521767641?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1375186689521767641/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1375186689521767641' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1375186689521767641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1375186689521767641'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/05/slim3.html' title='押してもだめならSlim3化'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5827670053043666054</id><published>2009-04-30T01:42:00.003+09:00</published><updated>2009-04-30T01:47:09.051+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><title type='text'>久し振りの間隔</title><content type='html'>最近JDOを触っています。&lt;br /&gt;GAEを触ることがきっかけで行い始めましたけど、&lt;br /&gt;電子工学を習ったころ、&lt;br /&gt;プログラミング初のオブジェクト指向、&lt;br /&gt;Webを触り始めた頃、&lt;br /&gt;ハードウェアを触り始めたころ。。。&lt;br /&gt;その辺りの新鮮さを感じているところです。&lt;br /&gt;&lt;br /&gt;新しいというより、、、&lt;br /&gt;なんか今まで習ってきたことを復習させられていて&lt;br /&gt;楽しい感じに近いです。&lt;br /&gt;&lt;br /&gt;ん。。。いいっすね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5827670053043666054?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5827670053043666054/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5827670053043666054' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5827670053043666054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5827670053043666054'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/blog-post_30.html' title='久し振りの間隔'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7453828901364868075</id><published>2009-04-29T18:34:00.000+09:00</published><updated>2009-04-29T18:38:18.913+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='バージョン管理'/><title type='text'>GAEのバージョン管理</title><content type='html'>ローカルでの動作確認もありますが&lt;br /&gt;デプロイした状況での確認も必要になります。&lt;br /&gt;&lt;br /&gt;そこでデプロイのバージョニングを行います。&lt;br /&gt;&lt;br /&gt;http://appengine.google.com/にアクセスすると&lt;br /&gt;自分のアプリケーションの管理画面になると思います。&lt;br /&gt;対象のアプリケーションを選択して&lt;br /&gt;右にあるVersionsをクリックすると&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/Sfge8dOwRPI/AAAAAAAAADs/HC-8CsybKf8/s1600-h/version.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 117px;" src="http://4.bp.blogspot.com/_wlXf9TOPv20/Sfge8dOwRPI/AAAAAAAAADs/HC-8CsybKf8/s320/version.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5330044182980478194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;という画面が出力されます。&lt;br /&gt;ここのバージョンはeclipseのプロジェクトの設定で&lt;br /&gt;[Google]→[App Engine]でデプロイメントのバージョンになります。&lt;br /&gt;※１～の整数を指定します。&lt;br /&gt;&lt;br /&gt;指定したバージョンでデプロイして&lt;br /&gt;上記画面で右にあるURLでテストが行えます。&lt;br /&gt;ちなみに初めて試した時に例外を見事発生させました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7453828901364868075?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7453828901364868075/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7453828901364868075' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7453828901364868075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7453828901364868075'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gae_4120.html' title='GAEのバージョン管理'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wlXf9TOPv20/Sfge8dOwRPI/AAAAAAAAADs/HC-8CsybKf8/s72-c/version.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4584749725503418313</id><published>2009-04-29T18:10:00.003+09:00</published><updated>2009-04-29T18:26:04.739+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='関連'/><title type='text'>JDOの１対多</title><content type='html'>結構はまりました。&lt;br /&gt;&lt;a href="http://code.google.com/p/datanucleus-appengine/issues/detail?id=28&amp;can=7"&gt;ここ&lt;/a&gt;にあるようにバグにより&lt;br /&gt;親のオブジェクト、子のオブジェクトのキーはKeyにする必要があるようです。&lt;br /&gt;※子は仕様にも記述してありますけどね。&lt;br /&gt;&lt;br /&gt;まず親側のクラスを&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;class Shop {&lt;br /&gt;&lt;br /&gt;    @PrimaryKey&lt;br /&gt;    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt;    private Key key;&lt;br /&gt;&lt;br /&gt;    @Persistent(mappedBy = "shop")&lt;br /&gt;    private List&amp;lt;Image&amp;gt; imageList;&lt;br /&gt;&lt;br /&gt;・・・getter,setterは未記述&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と記述します。&lt;br /&gt;Keyは通常のIDENTITY(Longで自動設定した場合)と同一で、特に登録などの際に&lt;br /&gt;設定する必要はありません。&lt;br /&gt;&lt;br /&gt;そして子のクラスを&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;class Image {&lt;br /&gt;&lt;br /&gt;    @PrimaryKey&lt;br /&gt;    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt;    private Key key;&lt;br /&gt;&lt;br /&gt;    @Persistent&lt;br /&gt;    private Shop shop;&lt;br /&gt;・・・getter,setterは未記述&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;というように記述します。&lt;br /&gt;&lt;br /&gt;で登録は以下のようにします。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   PersistenceManager pm = SessionManager.get().getPersistenceManager();&lt;br /&gt;   Transaction tx = null;&lt;br /&gt;   try {&lt;br /&gt;    String id = mogForm.getId();&lt;br /&gt;    Long lngId = Long.valueOf(id);&lt;br /&gt;&lt;br /&gt;    tx = pm.currentTransaction();&lt;br /&gt;    tx.begin();&lt;br /&gt;&lt;br /&gt;    log.warning(id);&lt;br /&gt;    Shop oldShop = pm.getObjectById(Shop.class, lngId);&lt;br /&gt;    &lt;br /&gt;    List&amp;lt;Image&amp;gt; imageList = oldShop.getImageList();&lt;br /&gt;    if ( imageList == null ) {&lt;br /&gt;     imageList = new ArrayList&amp;lt;Image&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    imageList.add(image);&lt;br /&gt;    image.setShop(oldShop);&lt;br /&gt;    &lt;br /&gt;    tx.commit();&lt;br /&gt;   } finally {&lt;br /&gt;    if ( tx != null &amp;&amp; tx.isActive() ) {&lt;br /&gt;     tx.rollback();&lt;br /&gt;    }&lt;br /&gt;    pm.close();&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Shopを検索してImageListを取得して&lt;br /&gt;そこに追加を行ってコミットをかけています。&lt;br /&gt;トランザクションをかけてあげないとエラーになります。&lt;br /&gt;このクラスを登録するというより、親に追加して更新しているイメージです。&lt;br /&gt;※子の追加でも可能かは検証してません。&lt;br /&gt;&lt;br /&gt;扱っているShopクラスのidの値は&lt;br /&gt;KeyクラスのgetId()により取得したLong値(Stringで使ってる)になります。&lt;br /&gt;そのまま使用すると"Shop(4)"みたいな値になって検索の際にエラーになります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・あぁ。。。やっとこさ関連が実装できた！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4584749725503418313?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4584749725503418313/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4584749725503418313' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4584749725503418313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4584749725503418313'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/jdo_29.html' title='JDOの１対多'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-8925557980820073405</id><published>2009-04-26T09:03:00.001+09:00</published><updated>2009-04-26T09:04:53.746+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='削除'/><title type='text'>JDOで削除</title><content type='html'>JDOのオブジェクトを削除します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;  PersistenceManager pm = SessionManager.get().getPersistenceManager();&lt;br /&gt;  try {&lt;br /&gt;   Shop oldShop = pm.getObjectById(Shop.class, Long.valueOf(id));&lt;br /&gt;   pm.deletePersistent(oldShop);&lt;br /&gt;  } finally {&lt;br /&gt;   pm.close();&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;更新時と同じくgetObjectById()でオブジェクトを取得して&lt;br /&gt;deletePersistent()で削除を行います。&lt;br /&gt;&lt;br /&gt;簡単ですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-8925557980820073405?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/8925557980820073405/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=8925557980820073405' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8925557980820073405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/8925557980820073405'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/jdo_5041.html' title='JDOで削除'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-5360013938999085528</id><published>2009-04-26T09:01:00.001+09:00</published><updated>2009-04-26T09:03:07.402+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='更新'/><title type='text'>JDOで更新</title><content type='html'>JDOで更新を行います。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  String id     = mogForm.getId();&lt;br /&gt;  PersistenceManager pm = SessionManager.get().getPersistenceManager();&lt;br /&gt;  try {&lt;br /&gt;   Shop oldShop = pm.getObjectById(Shop.class, Long.valueOf(id));&lt;br /&gt;&lt;br /&gt;   String name   = mogForm.getName();&lt;br /&gt;   String detail = mogForm.getDetail();&lt;br /&gt;   String url    = mogForm.getUrl();&lt;br /&gt;&lt;br /&gt;   oldShop.setName(name);&lt;br /&gt;   oldShop.setDetail(detail);&lt;br /&gt;   oldShop.setUrl(url);&lt;br /&gt;   oldShop.setEditor(user);&lt;br /&gt;   oldShop.setEditDate(new Date());&lt;br /&gt;&lt;br /&gt;  } finally {&lt;br /&gt;   pm.close();&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;getObjectById()を利用して検索を行います。&lt;br /&gt;&lt;br /&gt;取得してきたオブジェクトを更新してclose()するだけです。&lt;br /&gt;簡単ですね。&lt;br /&gt;&lt;br /&gt;Keyを利用した検索もあるみたい。※それは後日&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-5360013938999085528?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/5360013938999085528/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=5360013938999085528' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5360013938999085528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/5360013938999085528'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/jdo_26.html' title='JDOで更新'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7659998210218162769</id><published>2009-04-25T15:50:00.003+09:00</published><updated>2009-04-25T15:54:44.461+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='User'/><title type='text'>GAEでオブジェクト比較</title><content type='html'>GAEでログインしたユーザだけのデータを表示したい。&lt;br /&gt;&lt;br /&gt;そう思い立ちました。。。がっ！&lt;br /&gt;JDOのオブジェクト比較にSQLってどうするんだろ？&lt;br /&gt;と思い立ちしばし、、、&lt;br /&gt;&lt;br /&gt;でできました。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  UserService userService = UserServiceFactory.getUserService();&lt;br /&gt;  User user = userService.getCurrentUser();&lt;br /&gt;&lt;br /&gt;  PersistenceManager pm = SessionManager.get().getPersistenceManager();&lt;br /&gt;  Query query = pm.newQuery(Shop.class);&lt;br /&gt;&lt;br /&gt;  query.setFilter("creator == crrentUser");&lt;br /&gt;     query.declareParameters("com.google.appengine.api.users.User crrentUser");&lt;br /&gt;     &lt;br /&gt;  try {&lt;br /&gt;   List&amp;lt;Shop&amp;gt; shopList = (List&amp;lt;Shop&amp;gt;)query.execute(user);&lt;br /&gt;   for ( Shop oldShop : shopList ) {&lt;br /&gt;    Shop newShop = new Shop(oldShop);&lt;br /&gt;    shopForm.addShop(newShop);&lt;br /&gt;   }&lt;br /&gt;  } finally {&lt;br /&gt;   query.closeAll();&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Query::setFilter()でSQLイメージを作って&lt;br /&gt;Query::declareParameters()で型を宣言します。&lt;br /&gt;Query::execute()で比較するオブジェクトを設定しておきます。&lt;br /&gt;&lt;br /&gt;これでOKですね！&lt;br /&gt;ログインしたユーザのみの機能もこれでOKですね。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7659998210218162769?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7659998210218162769/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7659998210218162769' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7659998210218162769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7659998210218162769'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gae_25.html' title='GAEでオブジェクト比較'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7495481448201331827</id><published>2009-04-25T01:42:00.002+09:00</published><updated>2009-04-25T01:48:48.900+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Singleton'/><title type='text'>ひとまずSingleton！</title><content type='html'>さぁ、ひとまず、GoogleAppEngineの&lt;br /&gt;データベースを使うにはSingletonパターンを勉強しましょう！&lt;br /&gt;&lt;br /&gt;データベースのリソースを極力使わないのが&lt;br /&gt;システム設計の基本なんですが&lt;br /&gt;まず最初に行わなければいけないのは&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package bz.ziro.test.jdo;&lt;br /&gt;&lt;br /&gt;import javax.jdo.JDOHelper;&lt;br /&gt;import javax.jdo.PersistenceManagerFactory;&lt;br /&gt;&lt;br /&gt;public class SessionManager {&lt;br /&gt; private static final PersistenceManagerFactory pmfInstance =&lt;br /&gt;        JDOHelper.getPersistenceManagerFactory("transactions-optional");&lt;br /&gt;    public static PersistenceManagerFactory get() {&lt;br /&gt;        return pmfInstance;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;です。&lt;br /&gt;こうすることで&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;  PersistenceManagerFactory pmf = SessionManager.get();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;使うことができます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;いやぁ。。。JDOを真面目に勉強してたらびっくりしました。&lt;br /&gt;JDOってJavaの規格なんですね。。。&lt;br /&gt;それでjarを拾いにいったらApacheで&lt;br /&gt;そのjarだけでは実装できませんって言われて&lt;br /&gt;やばっ！って思ってたら&lt;br /&gt;googleもdatanucleusっていうやつを使ってるんですね。&lt;br /&gt;※ってよく見たらreferenceにも書いてありました！！&lt;br /&gt;&lt;br /&gt;ん～やっぱGoogleさんの考えてることはわからん、、、&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7495481448201331827?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7495481448201331827/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7495481448201331827' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7495481448201331827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7495481448201331827'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/singleton.html' title='ひとまずSingleton！'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6779129371577858299</id><published>2009-04-23T23:04:00.002+09:00</published><updated>2009-04-23T23:21:40.190+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Struts'/><title type='text'>GAEでStruts</title><content type='html'>さて我が心のフレームワークStruts1.3を&lt;br /&gt;GAEで展開したいと思います。&lt;br /&gt;&lt;br /&gt;えーと。。。ひとまずblankアプリからですかね？&lt;br /&gt;まずStrutsのappをおとしてきて、blankのwarを展開します。&lt;br /&gt;&lt;br /&gt;で、、、展開したディレクトリから&lt;br /&gt;jspはプロジェクトのwar下に置きます。&lt;br /&gt;&lt;br /&gt;index.jspとpages/Welcome.jsp&lt;br /&gt;&lt;br /&gt;WEB-INF下のlibとxmlファイル３つ。。。&lt;br /&gt;web.xmlは上書きするかはお任せします。&lt;br /&gt;&lt;br /&gt;これらを展開します。&lt;br /&gt;&lt;br /&gt;でsrc下にある「MessageResources.properties」をsrcにコピーします。&lt;br /&gt;&lt;br /&gt;でappengine-web.xmlに&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;sessions-enabled&amp;gt;true&amp;lt;/sessions-enabled&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;を追記します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;でデプロイ。これで動作します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;。。。素直にGWTにするべきか悩ましい。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6779129371577858299?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6779129371577858299/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6779129371577858299' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6779129371577858299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6779129371577858299'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gaestruts.html' title='GAEでStruts'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1000270100755571196</id><published>2009-04-21T18:24:00.006+09:00</published><updated>2009-04-25T09:11:14.051+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='データベース'/><title type='text'>JDOで保存と検索</title><content type='html'>さぁGAEでデータベースを取り扱ってみましょう！&lt;br /&gt;&lt;br /&gt;JDOを利用して行うことができるようです。&lt;br /&gt;JDOは。。。平たく言うとオブジェクトを保存できる仕組みとでもいいましょうか。。。&lt;br /&gt;&lt;br /&gt;下準備は「src/META-INF」に&lt;br /&gt;jdoconfig.xmlを準備する必要があります。&lt;br /&gt;&lt;br /&gt;これはeclipseのプラグインでプロジェクトを作成した場合に&lt;br /&gt;勝手にできあがってるみたいです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;それとパーシスタントクラスを準備する必要があります。&lt;br /&gt;このクラスはPOJOと呼ばれる単純なクラスを準備します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import javax.jdo.annotations.IdGeneratorStrategy;&lt;br /&gt;import javax.jdo.annotations.IdentityType;&lt;br /&gt;import javax.jdo.annotations.PersistenceCapable;&lt;br /&gt;import javax.jdo.annotations.Persistent;&lt;br /&gt;import javax.jdo.annotations.PrimaryKey;&lt;br /&gt;&lt;br /&gt;import com.google.appengine.api.users.User;&lt;br /&gt;&lt;br /&gt;@PersistenceCapable(identityType = IdentityType.APPLICATION)&lt;br /&gt;public class Project {&lt;br /&gt;&lt;br /&gt;    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt;    @PrimaryKey&lt;br /&gt; private Long id;&lt;br /&gt;    @Persistent&lt;br /&gt;    private String name;&lt;br /&gt;    @Persistent&lt;br /&gt;    private String detail;&lt;br /&gt;    @Persistent&lt;br /&gt;    private User creator;&lt;br /&gt;    @Persistent&lt;br /&gt;    private User editor;&lt;br /&gt;&lt;br /&gt;・・・・(getter と setterも準備)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;残したいデータを準備するのですが&lt;br /&gt;大事なのは「@～」っていう記述方法です。&lt;br /&gt;アノテーションと呼ばれるコメントにより、特性を決める技術です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@PersistenceCapable(identityType = IdentityType.APPLICATION)&lt;br /&gt;でこのアプリケーションで一意であるデータということ&lt;br /&gt;&lt;br /&gt;@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt;保存対象でありIDENTITY(一意)であるということ&lt;br /&gt;&lt;br /&gt;@PrimaryKey&lt;br /&gt;プライマリーであるということ&lt;br /&gt;&lt;br /&gt;@Persistent&lt;br /&gt;保存対象である&lt;br /&gt;&lt;br /&gt;ということを意味します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さぁこれで保存する準備はできました。&lt;br /&gt;画面を作成して保存して一覧に出すようにしてみましょう！&lt;br /&gt;&lt;br /&gt;まず実行するJSPを準備&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;form name="testForm" action="./JDOServlet" method="post"&amp;gt;&lt;br /&gt;&amp;lt;input type="text" name="name"&amp;gt;&lt;br /&gt;&amp;lt;textarea name="detail"&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;&amp;lt;input type="submit"&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まぁ普通のHTMLファイルでもOKですね。&lt;br /&gt;でJDOServletをweb.xmlに記述します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;  &amp;lt;servlet&amp;gt;&lt;br /&gt;    &amp;lt;servlet-name&amp;gt;JDOTestServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;    &amp;lt;servlet-class&amp;gt;bz.ziro.test.servlet.JDOServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;  &amp;lt;/servlet&amp;gt;&lt;br /&gt; &lt;br /&gt;  &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;    &amp;lt;servlet-name&amp;gt;JDOTestServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;    &amp;lt;url-pattern&amp;gt;/secure/JDOServlet&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;  &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;※servletタグとservlet-mappigタグは順番に並べてください。&lt;br /&gt;&lt;br /&gt;で少し長いですがサーブレットは以下のようになります。&lt;br /&gt;※折りたたんであるので広げてください。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:collapse"&gt;&lt;br /&gt;public class JDOServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * &lt;br /&gt;  */&lt;br /&gt; private static final long serialVersionUID = 1234131818439520488L;&lt;br /&gt;&lt;br /&gt; private static PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");&lt;br /&gt; @Override&lt;br /&gt; protected void doPost(HttpServletRequest req, HttpServletResponse resp)&lt;br /&gt;   throws ServletException, IOException {&lt;br /&gt;  &lt;br /&gt;  UserService userService = UserServiceFactory.getUserService();&lt;br /&gt;  User user = userService.getCurrentUser();&lt;br /&gt;&lt;br /&gt;  String name = req.getParameter("name");&lt;br /&gt;  String detail = req.getParameter("detail");&lt;br /&gt;&lt;br /&gt;  Project project = new Project();&lt;br /&gt;  project.setName(name);&lt;br /&gt;  project.setDetail(detail);&lt;br /&gt;  project.setCreator(user);&lt;br /&gt;  &lt;br /&gt;  PersistenceManager pm = pmfInstance.getPersistenceManager();&lt;br /&gt;  try {&lt;br /&gt;   pm.makePersistent(project);&lt;br /&gt;  } finally {&lt;br /&gt;   pm.flush();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Query query = pm.newQuery(Project.class);&lt;br /&gt;  try {&lt;br /&gt;   List&amp;lt;Project&amp;gt; projectList = (List&amp;lt;Project&amp;gt;)query.execute();&lt;br /&gt;   PrintWriter writer = resp.getWriter();&lt;br /&gt;   resp.setContentType("text/html");&lt;br /&gt;   if (projectList.iterator().hasNext()){&lt;br /&gt;    writer.println("&amp;lt;table&amp;gt;");&lt;br /&gt;    writer.println("&amp;lt;tr&amp;gt;");&lt;br /&gt;    writer.println("&amp;lt;td&amp;gt;id&amp;lt;/td&amp;gt;");&lt;br /&gt;    writer.println("&amp;lt;td&amp;gt;name&amp;lt;/td&amp;gt;");&lt;br /&gt;    writer.println("&amp;lt;td&amp;gt;detail&amp;lt;/td&amp;gt;");&lt;br /&gt;    writer.println("&amp;lt;/tr&amp;gt;");&lt;br /&gt;    for ( Project pro : projectList ) {&lt;br /&gt;     writer.println("&amp;lt;tr&amp;gt;");&lt;br /&gt;     writer.println("&amp;lt;td&amp;gt;" + pro.getId() + "&amp;lt;/td&amp;gt;");&lt;br /&gt;     writer.println("&amp;lt;td&amp;gt;" + pro.getName() + "&amp;lt;/td&amp;gt;");&lt;br /&gt;     writer.println("&amp;lt;td&amp;gt;" + pro.getDetail() + "&amp;lt;/td&amp;gt;");&lt;br /&gt;     writer.println("&amp;lt;/tr&amp;gt;");&lt;br /&gt;    }&lt;br /&gt;    writer.println("&amp;lt;/table&amp;gt;");&lt;br /&gt;   } else {&lt;br /&gt;   }&lt;br /&gt;  } finally {&lt;br /&gt;   query.closeAll();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;まずProjectのオブジェクトを準備しています。&lt;br /&gt;でPersistenceManagerでmakeします。&lt;br /&gt;これがinsert行為になります。&lt;br /&gt;&lt;br /&gt;まだpmは使うのでflushだけして&lt;br /&gt;Queryクラスで一覧を取得してきます。&lt;br /&gt;このQueryクラスでwhere文やlimit文、Order文などを記述します。&lt;br /&gt;&lt;br /&gt;でPrintWriterでHTMLに記述をしています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さぁベタな文法ですがいかがだったでしょうか？&lt;br /&gt;※PMFなどをSingletonパターンを利用しないと&lt;br /&gt;　もう一回インスタンスを取得するとExceptionになります。&lt;br /&gt;&lt;br /&gt;http://gae.ziro.bz/secure/test.jsp&lt;br /&gt;&lt;br /&gt;でお試しできます。&lt;br /&gt;※ごめんなさい。Creatorユーザでユーザを保存していますので&lt;br /&gt;　試すとアカウントの情報が残ります。&lt;br /&gt;　間違っても何かに使ったりしませんのでお試しください。&lt;br /&gt;&lt;br /&gt;※ごめんなさい。現在はStrutsによる実装になってしまいました。&lt;br /&gt;&lt;br /&gt;・・・さてトランザクションとかもやらんとな。。。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1000270100755571196?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1000270100755571196/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1000270100755571196' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1000270100755571196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1000270100755571196'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/jdo.html' title='JDOで保存と検索'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-4565876757009014329</id><published>2009-04-20T17:24:00.003+09:00</published><updated>2009-04-20T20:12:37.083+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='認証'/><title type='text'>GAEで認証アプリケーション（続）</title><content type='html'>さて情報の取得方法は&lt;a href="http://secondarykey.blogspot.com/2009/04/gae.html"&gt;前項&lt;/a&gt;でやりました。&lt;br /&gt;&lt;br /&gt;大事なのはアプリケーションを認証で守ることです。&lt;br /&gt;※前項では認証を行っただけ&lt;br /&gt;&lt;br /&gt;日頃からJ2EEの認証JAAS使っといてよかった。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;    &amp;lt;security-constraint&amp;gt;&lt;br /&gt;        &amp;lt;web-resource-collection&amp;gt;&lt;br /&gt;            &amp;lt;url-pattern&amp;gt;/secure/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;        &amp;lt;/web-resource-collection&amp;gt;&lt;br /&gt;        &amp;lt;auth-constraint&amp;gt;&lt;br /&gt;            &amp;lt;role-name&amp;gt;*&amp;lt;/role-name&amp;gt;&lt;br /&gt;        &amp;lt;/auth-constraint&amp;gt;&lt;br /&gt;    &amp;lt;/security-constraint&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;とweb.xmlに記述すると&lt;br /&gt;/secure/～というURLは認証を通らないといけなくなります。&lt;br /&gt;&lt;br /&gt;JSPなどにこのURLに関係するリンクを貼り、押下してみると&lt;br /&gt;認証されないと行けないことがわかります。&lt;br /&gt;&lt;br /&gt;なお、role-nameで「*」を指定していますが&lt;br /&gt;アプリケーションの設定で管理者になっている「admin」というロールと&lt;br /&gt;世間一般のGoogleアカウントがあるようです。(こっちは不明)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-4565876757009014329?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/4565876757009014329/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=4565876757009014329' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4565876757009014329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/4565876757009014329'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gae_20.html' title='GAEで認証アプリケーション（続）'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-7696946261895823565</id><published>2009-04-20T00:09:00.002+09:00</published><updated>2009-04-20T20:25:44.671+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>GAEでGroovy！</title><content type='html'>はてさて知人がGroovyを使いたいということだったので&lt;br /&gt;何となくですがやってしまいました。&lt;br /&gt;&lt;br /&gt;まずweb.xmlに&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;GroovyServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;groovy.servlet.GroovyServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;GroovyServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;*.groovy&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を追加します。&lt;br /&gt;って独自クラスを作ろうとしてたら&lt;br /&gt;GroovyにServletてびっくりしました。&lt;br /&gt;&lt;br /&gt;servletとservlet-mappingは&lt;br /&gt;まとめて記述する必要があるので&lt;br /&gt;独自のサーブレットがある場合は気をつけて編集しましょう。&lt;br /&gt;&lt;br /&gt;でwar/WEB-INF/groovyというディレクトリを作成して&lt;br /&gt;test.groovyファイルを作成します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="css"&gt;&lt;br /&gt;html.html {&lt;br /&gt;    head {&lt;br /&gt;        title "Hello"&lt;br /&gt;    }&lt;br /&gt;    body {&lt;br /&gt;        p "Hello Groovy World!"&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;これでデプロイして「ドメイン/test.groovy」でアクセスすれば&lt;br /&gt;Groovy動作が完了しますね。簡単です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;このソースの前にScriptEngineManagerを使って&lt;br /&gt;文字列実行できるかテストしたんですけど。。。。&lt;br /&gt;ScriptEngineManagerってJava6標準なんですね。驚きました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・あー忘れてました。Groovyのjarが必要ですね。&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Download"&gt;Groovyの本家&lt;/a&gt;からバイナリでもダウンロードして&lt;br /&gt;jarをクラスライブラリに追加しないと動作しません。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-7696946261895823565?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/7696946261895823565/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=7696946261895823565' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7696946261895823565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/7696946261895823565'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gaegroovy.html' title='GAEでGroovy！'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-6697013479128996868</id><published>2009-04-19T22:54:00.002+09:00</published><updated>2009-04-19T23:09:15.308+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDO'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><title type='text'>GAEでJDO</title><content type='html'>すっごい！！！JDOまで行っちゃうなんて！！！&lt;br /&gt;&lt;br /&gt;PersistenceManagerFactoryをSingletonで作成して&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・ってこれをパッケージングして&lt;br /&gt;自分のクラス構造してたらQueryがあった。。。スゴイ。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;うん。すごい。&lt;br /&gt;またJDOについては書きます！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-6697013479128996868?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/6697013479128996868/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=6697013479128996868' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6697013479128996868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/6697013479128996868'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gaejdo.html' title='GAEでJDO'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-1543332205251277589</id><published>2009-04-19T14:58:00.004+09:00</published><updated>2009-04-19T15:08:06.969+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='認証'/><title type='text'>GAEで認証アプリケーション</title><content type='html'>GoogleAppEngineで認証できるアプリケーションを作成してみましょう！&lt;br /&gt;&lt;br /&gt;サンプルにもある通り、&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;    UserService userService = UserServiceFactory.getUserService();&lt;br /&gt;    User user = userService.getCurrentUser();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と行うとユーザがログインしているかどうかがわかります。&lt;br /&gt;userがnullの場合はログインしてない状況です。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;userService.createLogoutURL(request.getRequestURI()&lt;br /&gt;userService.createLoginURL(request.getRequestURI())&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と行うとログイン、ログアウトのパスを取得できるので&lt;br /&gt;それに対してAタグを書いてあげます。&lt;br /&gt;&lt;br /&gt;引数の「request.getRequestURI()」は&lt;br /&gt;ログイン後に戻るページですので変更すれば画面の遷移を変えることができます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ここで彷徨ってしまったのは&lt;br /&gt;独自ドメイン時のログイン画面です。&lt;br /&gt;私の作ったアプリケーションの認証を作成しようとしたら&lt;br /&gt;GoogleAppsの認証画面が出てきました。&lt;br /&gt;&lt;br /&gt;「えー独自ドメインは自分のドメインの認証なのっ！」&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;・・・と勘違いしちゃいましたが違いました。&lt;br /&gt;どうやらアプリケーションを作成した時に&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_wlXf9TOPv20/Seq9bMEL1FI/AAAAAAAAADk/OPS2cLqOQbk/s1600-h/auth.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 185px;" src="http://4.bp.blogspot.com/_wlXf9TOPv20/Seq9bMEL1FI/AAAAAAAAADk/OPS2cLqOQbk/s320/auth.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5326277784111928402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;でドメイン認証をチェックしたみたいです。&lt;br /&gt;・・・１時間位さまよいました。。。&lt;br /&gt;逆に考えれば独自認証のアプリも作れるってことですね！&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;はてさて情報の取得やログインへの遷移は可能になりましたが&lt;br /&gt;大事なのはアプリケーションのセキュリティです。&lt;br /&gt;&lt;br /&gt;・・・ってJAASを使用した方なら簡単ですね。&lt;br /&gt;web.xmlを設定してあげればOKです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ほぼ&lt;br /&gt;&lt;a href="http://secondarykey.blogspot.com/2008/12/tomcat.html"&gt;ここ&lt;/a&gt;と同じだと思いますが&lt;br /&gt;server.xmlはいらないし「manage」っていうロールはないですね。&lt;br /&gt;adminはアプリの管理者がそういう扱いになりそうです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2618695401132183697-1543332205251277589?l=secondarykey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://secondarykey.blogspot.com/feeds/1543332205251277589/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2618695401132183697&amp;postID=1543332205251277589' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1543332205251277589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2618695401132183697/posts/default/1543332205251277589'/><link rel='alternate' type='text/html' href='http://secondarykey.blogspot.com/2009/04/gae.html' title='GAEで認証アプリケーション'/><author><name>Yuzo Hebishima</name><uri>https://profiles.google.com/118188062200362902377</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-NBdjNVUFco8/AAAAAAAAAAI/AAAAAAAAAbM/A-WAreDHIUs/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_wlXf9TOPv20/Seq9bMEL1FI/AAAAAAAAADk/OPS2cLqOQbk/s72-c/auth.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2618695401132183697.post-3538930254660876187</id><published>2009-04-19T10:29:00.003+09:00</published><updated>2009-04-19T11:03:16.226+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>GoogleAppEngine for Java</title><content type='html'>先日一部公開されましたGoogleAppEngineのJava版を使ってみましょう。&lt;br /&gt;&lt;br /&gt;まずEclipseにプラグインをインストールします。&lt;br /&gt;3.4の場合は以下のサイトでOKです。&lt;br /&gt;http://dl.google.com/eclip
