年末にStrutsの話題(手順と具体例)を書きました(年末だったので見てない人が居るかもしれないので、さいごにその手順について、かいてあるところを付けておきます)。
そして、この前、Strutsタグを使わないでActionを呼び出す方法と、XMLで書き出す方法(これ、訂正してあります)を書きました。
今日は、その2つをあわせて、AJAXでStrutsのActionを呼び出す方法です。
■仕様
以下のような画面で、
「打ち終わった!」ボタンをクリックしたら、サーバーのStrutsのActionにアクセスして、正解率を受け取り、その内容を表示します。
アクセスするサーバーのURL http://127.0.0.1/stest/shori.do
引数 nyuryoku=入力された内容
(入力された内容は Formのinputタグのtextのid=nyuryokuから取り出します)
サーバーからの返り値のXML
<?xml version="1.0" ?> <kekka> <ritu>ここに値が入ります</ritu> </kekka> |
(上記< > は本当は半角、”ここに値が入ります”のところに実際の値が入る)
■必要なもの
サーバー側の必要なもの、ActionFormやActionなどについては、
Strutsタグを使わないでActionを呼び出す方法や、一番下の年末までのシリーズで書きました。
出力XMLのためのJSPについては、XMLで書き出す方法(これ、訂正してあります)に書きました。
あとは、サーバーのActionを呼び出して、結果を受け取り、表示するクライアント側(AJAX)のHTMLファイルが必要です。
■ソース
その結果を受け取り、表示するクライアント側(AJAX)のHTMLファイルを以下に示します。
<?xml version="1.0"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>早打ちの練習</title> <script language="javascript" type="text/javascript"> //************************ここから********************// //--------------------------------------// // 共通変数 // //--------------------------------------// var httpObj; var timer; // タイムアウト用 //*==============================================// //* 関数:getRitu() *// // 内容:サーバーアクセス *// //*==============================================// function getRitu() { // データ取り出し sendData = document.getElementById('nyuryoku').value; // 引数設定 msg = "nyuryoku=" + encodeURIComponent(sendData); // サーブレット呼び出し httpRequest("http://127.0.0.1:8080/stest/shori.do","POST",msg); } //*==============================================// //* 関数:DataOut() *// // 内容:値を取得して帰ってきた *// //*==============================================// function DataOut() { // 返り値XMLの取得 xtree = httpObj.responseXML; // 値の取得 // kekka:xtree.childNodes.item(1) (item 0は、XML宣言) // ritu:xtree.childNodes.item(1).childNodes.item(0) buf = xtree.childNodes.item(1).childNodes.item(0).text; // 結果を設定 document.getElementById('ritu').firstChild.nodeValue=buf; } //************ここ以降は、HTTPアクセスの決まり文句***********// //*==============================================// //* 関数:httpRequest() *// // 内容:XML読み取り開始 *// //*==============================================// function httpRequest(target_url,hosiki,msg) { try { if(window.XMLHttpRequest) { httpObj = new XMLHttpRequest(); } else if(window.ActiveXObject) { httpObj = new ActiveXObject("Microsoft.XMLHTTP"); } else { alert('エラーです'); return; } } catch(e) { alert('エラーです'); return; } // タイマーセット timer = setInterval("timeoutError()",60000); //60秒にセット // データを取得する httpObj.open(hosiki, target_url, true); httpObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); httpObj.onreadystatechange = DataRead; httpObj.send(msg); return; } //*==============================================// //* 関数:timeoutError() *// // 内容:タイムアウト *// //*==============================================// function timeoutError() { clearInterval(timer); // タイマーとめる httpObj.abort(); alert('タイムアウトです'); } //*==============================================// //* 関数:DataRead() *// // 内容:XML読み取ったあと *// //*==============================================// function DataRead() { if ( httpObj.readyState == 4 ) { clearInterval(timer); // タイマーとめる if ( httpObj.status == 200) { DataOut(); } } } //************************ここまで********************// </script> </head> <body bgcolor="#ffffff"> <H1>早うちの練習</H1> 以下の文を打とう!<BR /> <B>This is a pen</B><BR /> <form method="post"> <input type="text" id="nyuryoku" name="nyuryoku" size="20" /><BR /> <input type="button" name="do" value="打ち終わった!" onClick="getRitu()"/><BR /> </form> <BR /> 正解率(パーセント):<p id="ritu"> </p> </body> </html> |
(上記 < > ¥は本当は半角)
■説明
AJAXでPOSTでサーバーアクセスする内容に関しては、
AJAXでXMLHttpRequestのopenをPOST、sendに内容を送っても送信できない時に以前書きましたので、そちらをみてくださいませ。そこと、
getRituという、サーバーアクセスしているところと、
DataOutという、書き出ししているところだけが違います。
(リンク先のLoadがgetRituにかわっています。呼び出すときも、ロード時とボタンが押されたときでちがいます)。
で、これらの関数については、見ていただければ分かると思います。
DataOutは、今回は構造が分かっているので、いつものようにgetElementsByTagNameを使っていません。が、やってることはわかると思います。
なお、注意点は、むしろ、HTMLのほうで、”正解率(パーセント):”のあと、
<p id="ritu"> </p>
のところ、pタグのあと、全角の空白をいれてから、/pタグをかいています。
このわけは、document.getElementById('ritu')の(=pタグの)、はじめの子供(これがテキスト、ここでは全角の空白に)の値にセットするようにしたいからです。
もし、ここに全角空白がないと、はじめのときは、firstChildがないので、その場合はaddするとか、手続きが入ってめんどうになるので、はじめに全角空白をいれています。
ということで、こんかいは、ここまで。
■ふろく:年末に書いた、Strutsの手順
<<手順>>
1.画面遷移を考える。
2.(別にやんなくてもいいけど)それを以下のように図にしておくと、あとで楽です
3.画面のJSPを作成します
4.Strutsタグをいれて、JSPを修正します
5.画面に対応するActionFormを作ります
6.Submitでサーバーで処理するところに対応する、Actionを作ります
7.struts-config.xmlを設定します
8.モデルを作って、Actionから呼び出します
・リンク先は、それぞれのことを書いたエントリ。
なお、1~4までは、おなじ、1つのエントリにまとめて書いています。