Server側からtextデータしか返却できないとServer側もClient側もいろいろと面倒なので、CompojureでJSONデータを返却できるようにしてみる。
ring関連のライブラリを使用する(project.cljの変更)
この変更は使うライブラリが増えるので、project.cljファイルも変更対象。
追加するのはring関連のライブラリ。
project.clj
(defproject greet "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.6.0"]
[compojure "1.1.8"]
;↓の2つのS式を追加。カッコのネストに注意。
[ring/ring-core "1.2.0"]
[ring/ring-json "0.2.0"]]
:plugins [[lein-ring "0.8.11"]]
:ring {:handler greet.handler/app}
:profiles
{:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring-mock "0.1.5"]]}}
:web-content "public")
Server側(handler.clj)の変更
続いてhandler.cljの変更。変更する点は、
- ring関連で使用する関数のrequire宣言を追加
- POSTの返却データをclojureの連想配列データ化
- Webアプリ全体のレスポンスのJSON化(をしている感じ?)
の3本立て。ではコードを記載。尚、見やすさの為に前回のコメントは全て削除してある。
handler.clj
(ns greet.handler
(:require [compojure.core :refer :all]
[compojure.handler :as handler]
[compojure.route :as route]
;次の2つのS式を追加。カッコのネストに注意。
;ring関連で使用する関数のrequire宣言を追加している。
[ring.util.response :refer [resource-response response]]
[ring.middleware.json :as middleware]))
(defroutes app-routes
(GET "/" [] "Hello World")
(POST "/post_name" [first_name last_name]
;POSTの返却データをclojureの連想配列データ化。
;生成した連想配列データは、response関数で括る事。
(response {:value (format "Hello, %s %s" first_name last_name)}))
(route/files "/")
(route/resources "/")
(route/not-found "Not Found"))
(def app
;Webアプリ全体のレスポンスのJSON化(をしている感じ?)
(-> (handler/api app-routes)
(middleware/wrap-json-body)
(middleware/wrap-json-response)))
これでServer側から返却されるデータがJSON化される。
Client側(greet.html)の変更
実は前回の「動作確認(異常系)」と似ている。
修正項目は、
-
ajax
メソッドのdataType
を"json"
に変更 - responseで受信したデータがJSONデータになっているので、success時のイベントハンドラ内のロジックをJSONから必要なデータを抽出して使うように変更
の2つ。
greet.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1");</script>
<script type="text/javascript">
function greet(first_name, last_name) {
$("#greeting_area").text("** Loading... **");
$.ajax({
type: "post",
// ajaxメソッドのdataTypeを"json"に変更
dataType: "json",
data: {
"first_name": first_name,
"last_name": last_name
},
cache: true,
url: "http://localhost:3000/post_name",
success: function (greet_message) {
// 受け取ったgreet_messageはJSONデータなので、
// メンバ変数?のvalueに挨拶文が格納されている。
$("#greeting_area").text(greet_message.value);
},
error: function(xhr, status, err) {
var message = "Error occured: status=" + status + ", err=" + err;
$('#greeting_area').html(message);
}
});
}
$(function(){
$("#greet_button").click(function() {
var first_name = $("input[name='first_name']").val();
var last_name = $("input[name='last_name']").val();
greet(first_name, last_name);
return false;
});
})
</script>
</head>
<body>
<form action="unused">
<table>
<tr>
<td>First Name:</td>
<td><input name="first_name" type="text" value="" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input name="last_name" type="text" value="" /></td>
</tr>
</table>
<div><input id="greet_button" type="submit" value="Greet" /></div>
</form>
<div id="greeting_area"></div><br/>
</body>
</html>
これでOKなはず。
動作確認
例によっていつものhttp://localhost:3000/greet.htmlにアクセスし、First NameとLast Nameを入力してGreetボタンをクリックする。
次のように表示されればOK。
大丈夫そうっすね。