jQueryを使ってAjaxを実装するとIEでのみエラーが起きた

JavaScriptって、数年前だったら大したチェックしかできないと思っていたのですが、最近は見方が変わっています。
特に、DOM操作なんかができると知ってからは、「こんなにいろいろなことができるんだ」と関心しています。(気づくの遅い)

そんなわけでJavaScript関係のライブラリも勉強中です。ライブラリは現状では乱立状態で、どれを使えばいいのか本当に迷ってしまいます。今は「jQuery」というのを使っています。この後は「Yahoo!UIライブラリ」というのを勉強しようと考えています。

JavaのJSP、jQueryと、Ajaxを使って、ためしにいろいろ作っているのですが、Ajax関係でちょっとハマったのでメモしておきます。

あるページから、jQueryのAjaxメソッドを使って、サーバーサイドのJSPを呼び出しています。
このJSPはAjaxで呼び出されることを前提としていて、HTMLを出力するのではなく、JSONオブジェクトを出力するようにしています。
つまり、JSPといってもこんな感じで動的にJavaScriptを出力しています。

{
result: ["${var}", ]
}

そしたら、Firefoxでは動作するのに、なぜかIEでは「System error」というエラーが出て通信が完了しないのです。
ちなみにエラーというのは、クライアントに返ってJavaScriptで発生します。jQueryの中で発生しています。

jQueryの方にデバッグ文を入れて、やっと原因が分かりました。
JSPでは、pageディレクティブのpageEncoding属性で、”Windows-31J”というシフトJIS相当のエンコーディングを指定しています。するとレスポンスヘッダに
Content-type: text/html; charset=Windows-31J
Content-type: application/json; charset=Windows-31J
といった出力がされます。このContent-Typeだと、IEでjQuery内のメソッドで、Ajax通信をした後に、System errorとなってしまうのです。

回避策としては、charset=Shift_JISとか、UTF-8となればOKでした。
Shift_JISだと、「~」や「丸1」といった文字が返却できなかったので、UTF-8で返却することにしました。

2007/08/11追記
feedtailor Inc. 大石裕一の開発ブログ」さんで指摘されているように、JSONを返却するにはMimeTypeをapplication/jsonにしたほうがよさそうです。


livedoor Readerの既読が更新されない!

shock

Title: OMG Not again 1
Username: leonbidon
License: stock.xchng License

なんだか、今日のlivedoor Readerは不具合が多発しているようで、既読にしたはずの記事が未読に戻ってしまいます。
「この機能に不具合が発生するだけで、こんなにもストレスがたまるものか」と思ってしまいました。
全部見終わったー、Rと。えーっ!また未読!?」ってショックを受けてしまいます。

この不具合は耐え難い、みなさん困らないものだろうかと思ったら、即アナウンスが出ていました。
マイフィードが表示されない不具合について(livedoor Reader 開発日誌)

私は、RSSリーダーで、サイトの更新チェックをしています。特に最近愛用しているのが、livedoor ReaderというWebで提供されているソフトです。「WebベースのRSSリーダーなんて」当初は思っていたのですが、家と会社で情報を共有できるので、今ではスタンドアロンなRSSリーダーなんて考えられません。

ユーザーインターフェースもとても良くできています。これを使って一日の中で短時間に大量のサイトの更新情報を閲覧しています。
閲覧するといっても、タイトルだけ見て読み飛ばすのがほとんどです。

おそらく、1日に500ページ以上はタイトルをチェックしているはずです。これはlivedoor Readerを使う前までは、考えられない情報チェックの効率です。

どんな感じでチェックしているかというと、
1.まずlivedoor Readerの未読件数が100件と表示されているのを見て、閲覧しにいきます。(この未読件数の表示は、拙作のLDReader Notifierを使うとよろし)
2.ショートカットキーがたくさん割り当てられているので、SキーやJキーを使って、目に入るタイトルをパンパンと、目に入れていきます。
3.途中で、注目したいタイトルが出た場合には、読み飛ばすのをとめて、概要を読み、Pキーでピンを付けておきます。
4.最後にOキーで、ピンをつけたページを全部開いて、じっくりと読みます。

100件ぐらい未読記事があっても、ほとんど読み飛ばすので、Oキーで開くまでは1,2分しかかかっていません。
たったこれだけの時間で、livedoor Readerに登録してある、多数のサイトの更新チェックが済んでいるかと思うと、「なんて効率がよいんだろう」と思ってしまいます。

一方で、仕事中に中断して更新チェックしているのは、仕事の集中力が低下しそうなので、あんまり頻繁に開かないように気をつけておきます。


JSPタグファイルは楽チン

JSP2.0は、理解しやすく、使いやすいなあと常々思っています。
今日は、JSP2.0からの新機能で、非常に便利だが、あまり知られていない「タグファイル」について簡単に紹介します。

従来からのJSPでは、「カスタムタグ」という機能で、JSPでのHTMLコードの再利用が可能でした。
しかし、このカスタムタグは作るのが面倒だったため、フレームワーク作成以外では、あまり流行っていなかったです。

今回紹介するタグファイルは、このカスタムタグと同等の機能を持ちつつ、作成を簡単にしたものです。
どれぐらい簡単かというと、これぐらい違います。

カスタムタグ タグファイル
タグハンドラクラスの作成
TLDファイルの作成
web.xmlでのTLD宣言 任意
taglibディレクティブの記述
tagファイルの作成

タグファイルの場合は、カスタムタグで使用するTLDファイルが必要ないです。
代わりにタグファイル自身に、同様のTLDファイルで記述するような属性の定義が記述できます。

タグファイルの作成

方法はとても簡単です。なぜなら、基本的な記述の仕方はJSPと同じだからです。
この点においてもカスタムタグと比べて記述が楽です。(カスタムタグの場合は、JSPWriterオブジェクトを取得して、println()などでHTMLコードを出力していた)

ここでは、掛け算をするためのタグファイルを作成します。使い方としては、次のような使い方を想定します。

このように記述すると、3*5=15と表示するようにします。
簡単なのですぐにコードを示します。

(sample.tag)
<%@ tag pageEncoding="utf-8"%>
<%@ attribute name="val1" type="java.lang.Integer" required="true"%>
<%@ attribute name="val2" type="java.lang.Integer" required="true"%>
${val1} * ${val2} = ${val1 * val2}

これをsample.tagというファイル名にして、WEB-INF/tagsディレクトリに置くことにします。
読めばわかるように、JSPと同じ記法で記述できます。
<%@ attribute %>というのが、このタグの属性で、2つの属性を持つことが読み取れます。

JSPからの利用

JSPから使用するには、カスタムタグと同じようにtaglibディレクティブの宣言を必要とします。
タグファイルの場合は、カスタムタグと違って、tagdir属性を使ってタグファイルを格納したフォルダを指定します。
したがって、JSPはこんな感じになります。

(sample.jsp)
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>






sample.tagで指定したように、2つの属性val1,val2を指定します。これだけ。
タグハンドラクラスのコンパイルも、TLDファイルの作成も不要です。なんて便利なんでしょう。
sample.tagというファイル名だから、というタグ名になっています。

今回紹介したのはタグファイルの、もっとも基本的な部分です。
さらに詳細な使い方は、こちらが参考になります。

タグファイル JSP -TECHSCORE-
Tomcat5の新機能第2回:EL式とタグファイル – STACK(*)