LoginSignup
8
9

More than 5 years have passed since last update.

CompojureとjQueryでWebアプリを作る No.5(JSONデータを返す)

Last updated at Posted at 2014-07-20

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。

JSON受信

大丈夫そうっすね。

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9