scala on slim3 on GAE with twitter4j で OAuth認証してタイムラインがとれた


scala on slim3 on GAE with twitter4j で OAuth認証してタイムラインがとれたので、ソースをメモっておく。

まずは、Twitterアプリケーション画面twitterにアプリケーション追加

注意すべきなのは、「アプリケーションの種類」の設定。一度、アプリケーション登録したあと、編集するとこれが選択できるようになっているので、「ブラウザアプリケーション 」を選択しておく。「コールバックURL」は適当でヨシ。

参考サイト:TwitterのOAuthでCallbackさせるときの注意点 - speg03の雑記帳

IndexControllerを作成

ant gen-scala-controller

を実行。pathを求められるので、「/」と入れてやる。

これで、

  • package.projectName.controller.IndexController.scala
  • /war/index.jsp

が出来上がる。

/war/index.jsp には手をつけず、IndexController.scala を以下のようにコード。

package package.projectName.controller

import twitter4j.Twitter
import twitter4j.TwitterException
import twitter4j.TwitterFactory
import twitter4j.User
import twitter4j.ResponseList
import twitter4j.http.{AccessToken, RequestToken}
import org.slim3.controller.{Navigation, Controller}

class IndexController extends Controller {
  override def run():Navigation =  {
    return redirect(getAuthenticationURL())
	}

  def getAuthenticationURL():String = {
    var twitter:Twitter = new TwitterFactory().getInstance()
    twitter.setOAuthConsumer("Twitter登録時に表示されたConsumer key", "Twitter登録時に表示されたConsumer secret")
    sessionScope("twitter", twitter)	//セッションに保持

    // ■リクエストトークンの作成
		var requestToken:RequestToken = twitter.getOAuthRequestToken(callbackUrl())

    sessionScope("requestToken", requestToken)	//セッションに保持
    println("AuthenticationURL : " + requestToken.getAuthenticationURL())
		return requestToken.getAuthenticationURL()
  }

  def callbackUrl():String = {
    var url:StringBuffer = request.getRequestURL()
    println("requestUrl : " + url.toString())
    url.append("callback")
    println("callbackUrl : " + url.toString())
    return url.toString()
  }
}

CallbackControllerを作成

ant gen-scala-controller

を実行。pathを求められるので、「/callback」と入れてやる。

これで、

  • package.projectName.controller.CallbackController.scala
  • /war/callback.jsp

が出来上がる。


/war/callback.jsp には手をつけず、CallbackController.scala を以下のようにコード。

package package.projectName.controller

import org.slim3.controller.Controller
import org.slim3.controller.Navigation
import twitter4j.{Twitter, TwitterException}
import twitter4j.http.RequestToken

class CallbackController extends Controller {

  override def run():Navigation =  {

    try {
      validateTwitter()
    } catch {
      case e:TwitterException => var message = "Failed to get timeline: " + e.getMessage()
      requestScope("message", message)
    }
    return redirect("menu"); //次画面へリダイレクト
  }

  def validateTwitter():Twitter = {
    var twitter:Twitter = sessionScope("twitter")                 //セッションから取得
    var requestToken:RequestToken = sessionScope("requestToken")  //セッションから取得
    var verifier:String = asString("oauth_verifier")               //リクエストから取得
    twitter.getOAuthAccessToken(requestToken, verifier)           //認証の確認
    request.getSession().removeAttribute("requestToken")          //セッションから削除
    return twitter
  }
}

MenuControllerを作成

ant gen-scala-controller

を実行。pathを求められるので、「/menu」と入れてやる。

これで、

  • package.projectName.controller.MenuController.scala
  • /war/menu.jsp

が出来上がる。


MenuController.scala を以下のようにコード。

package package.projectName.controller

import org.slim3.controller.Controller
import org.slim3.controller.Navigation
import java.util.List
import twitter4j.{Status, Twitter}
import scala.collection.jcl.Conversions.convertList

class MenuController extends Controller {

    override def run() =  {
      var twitter:Twitter = sessionScope("twitter")
      var statuses = twitter.getHomeTimeline()
      requestScope("statuses", statuses)

      forward("menu.jsp")
    }
}

menu.jsp を以下のようにコード

<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Menu</title>
</head>
<body>
<p>Hello Menu !!!</p>
    <c:forEach var="e" items="${statuses}" varStatus="s">
        <c:out value="${s.count}" />
        ${f:h(e.text)}
        <hr />
    </c:forEach>
</body>
</html>

これで、http://localhost:8080 にアクセスすれば、Oauth認証を認可されて、タイムラインが取得可能!

一番参考にしたサイト:Slim3 Twitter4Jメモ(Hishidama's GAE Slim3 Twitter4J Memo)
こちらも参考:Young risk taker.: [Scala Tips] Java型からScalaのラッパー型への明示的変換を仲介してくれるライブラリ




尚、開発環境は、@kmizu さんに教えてもらって、IntelliJ IDEA を使用。結構安定したScalaエディターを使えます。Eclipseプロジェクトと互換性があるので、Eclipseでプロジェクトを作るところまでやって、IntelliJ IDEAに取り込みました。ただ、GAEのプラグインはIntelliJ IDEAの有償版でしか使うことができません。なので、IntelliJ IDEAでコーディングして、あとはコマンドプロンプトでant を実行して、compileしたり、{project}\lib\appengine-java-sdk-1.3.1\bin\dev_appserver.cmd を叩いたりしていました。また、何故か、java.util や java.lang 系のクラスが、エディタ上エラーに見えてしまいます。しかし、Scalaにはこれらのクラスは普通に使えるので、コンパイルは通ります。開発環境はまだまだ微妙っすね。