Last active
August 29, 2015 14:17
-
-
Save windymelt/df49e4a8c093c7816f17 to your computer and use it in GitHub Desktop.
Play 2.3.x でShift_JISのパーセントエンコーディングされたデータを受け取る
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package controllers | |
import play.api._ | |
import play.api.mvc._ | |
import play.api.data._ | |
object Application extends Controller { | |
def hoge = Action(parse.tolerantText) { request ⇒ // 生の文字列で受け取る。 | |
// 修正したリクエストでimplicit宣言する。 | |
// あたかも最初からパースされたフォームデータが渡されたような状態にする。 | |
// Formを使う部分はこのRequestを使うようになる。 | |
implicit val newRequest = PercentEncoding.extractSJISRequest(request) | |
/* ... */ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* パーセントエンコードされたフォームデータをパースするためのライブラリ */ | |
libraryDependencies += "org.apache.httpcomponents" % "httpclient" % "4.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package controllers | |
import play.api.mvc.{ Headers, Request } | |
object PercentEncoding { | |
import java.net.URI | |
import scala.collection.JavaConversions._ | |
import org.apache.http.client.utils.URLEncodedUtils | |
import org.apache.http.NameValuePair | |
def extractSJISRequest(request: Request[String]) = { | |
// パーセントエンコードされたStringが格納されているbodyを取得する。 | |
val body = request.body | |
// ライブラリ独自のクラスであるNameValuePairのSeqに変換する。 | |
// URLEncodedUtils.parseはList<NameValuePair>を返すが、 | |
// scala.collection.JavaConversions._ をimportしているのでList(Java) -> Seq(Scala)に暗黙変換される。 | |
// URLEncodedUtilsは、本来はbodyではなくURL内でのパーセントエンコーディングを想定しているので、 | |
// ダミーURLを作成してそのクエリという体でパースさせる。 | |
val parsed: Seq[NameValuePair] = URLEncodedUtils.parse(new URI("http://example.com/?" + body), "Shift_JIS") | |
// Seq[NameValuePair]をPlayでフォームデータの表現として使用されるMap[String, Seq[String]]に変換する。 | |
// 通常、application/x-www-form-urlencodedで渡ってきたデータはMap[String, Seq[String]]となるが、 | |
// ここで本来のデータ形式を再現する。 | |
val newBody = parsed.map { pair ⇒ (pair.getName, Seq(pair.getValue)) }.toMap | |
// あたかも最初からフォームとしてパースされていたようなリクエストを用意する。 | |
// bodyだけが変更されており、その他のパラメータはオリジナルのまま。 | |
// 型もRequest[String]ではなくRequest[Map[String, Seq[String]]]になっている。 | |
new Request[Map[String, Seq[String]]] { | |
override def body: Map[String, Seq[String]] = newBody // すげかえる | |
override def uri: String = request.uri | |
override def remoteAddress: String = request.remoteAddress | |
override def queryString: Map[String, Seq[String]] = request.queryString | |
override def method: String = request.method | |
override def headers: Headers = request.headers | |
override def path: String = request.path | |
override def version: String = request.version | |
override def tags: Map[String, String] = request.tags | |
override def id: Long = request.id | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment