JAX-RSのリファレンス実装、Jerseyの使い方(2)

前回は基本となるアノテーションを軸に、きわめて単純なRESTサービスを構築する手順を紹介しました。今回はやはりRESTといえばXML/JSONということで、XMLやJSONを返すサービスを構築しましょう。

(前回と言っても、ポストしたのがだいたい1年前の日付だということにたった今気づきました。)

XMLを返す

次のようなリソースクラスを作成します。

jerseytest.resources.LocalDocumentResource

package jerseytest.resources;

import java.io.IOException;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

@Path("/indianTeas")
public class LocalDocumentResource {
	@GET
	public Document getDocument() {
		try {
			File f = new File("/path/to/indianTeas.xml");
			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(f);
			return doc;
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}
}

少しコード量が増えたもののやっていることは単純で、ローカルにあるXMLファイルをDocumentオブジェクトにして返しているだけです。 続きを読む JAX-RSのリファレンス実装、Jerseyの使い方(2)

やっとわかった、java.util.logging

こんばんは。先日ブログの設定をいじっていたら、全てのページ(管理画面も!)でPHPエラーが表示されてかなり気落ちしました。PHPを書くのは久しぶりだったので、どこか書き間違えたんでしょう・・・。

さて、今日はロギングの話をします。

ロギングと言えばlog4jですが、JavaSEにもロギングを扱うための標準APIがあります(1.4から)。それがjava.util.loggingです。標準APIであるにも関わらず、なぜか情報が少ないんですね。簡単なプログラムを書こうとして、ついでだから標準API使ってみるか、と思い立つも、結局設定の仕方がわからずにlog4jに戻ったことが何度かありました。

まず使ってみる

まずは一番簡単な使い方から。

Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("Loggerテストです。info");
logger.severe("Loggerテストです。severe");

これだけです。このコードを実行すると、私のマシンでは以下の出力が得られます。

2011/11/05 23:34:29 Sample1 main
情報: Loggerテストです。info
2011/11/05 23:34:29 Sample1 main
致命的: Loggerテストです。severe

簡単ですね。 続きを読む やっとわかった、java.util.logging

私の参考書の選び方

別に喧伝するようなことではないのですが、そういえばこんなことを気にしているなあ、と思ったので書いてみます。

参考書を買おうとして書店に行くと、思っている事柄についての参考書が大抵何冊かはあるものです。そういうとき、私はだいたい次のようなポイントを見ています。

  1. 色は2色まで。
  2. 脚注・傍注欄がないこと。注釈専用ページなどもってのほか。
  3. 表紙がシンプル。

これは好みで言っているわけではなくて、ちゃんと理由があります。

なぜ参考書を読むのか?

そこに参考書があるから、ではありません。

何か知りたいと思っていることがあるからです。つまりその参考書を読んで知りたい内容を理解できて初めて、その参考書を読む価値があるというものです。

参考書として重要なのは、内容が巧く解説されているかでしょう。

色は2色まで

これは、著者の文章表現力を示します。テキストは2色、図表には3色使ってあってもいいと思います。

たくさんの色を使わなければ解説できないということは、端的に言って文章が下手だと考えて差し支えありません。

脚注・傍注欄がないこと

これは、著者の文章の流れを作る力を示します。

一連の内容を滞りなく理解させるためには、文章の流れを途切れさせないことが重要です。脚注・傍注はその文章の流れを断ち切るもの、まして注釈ページなどその最たるものです。

必要な解説は全て本文中で為されるべきなのです。

表紙がシンプル

これは、著者の考え方を示します。

装丁には著者の趣向が象徴的に表れるものです。そしてある事柄について焦点を当て、ブレの無いまとまった解説をするためには、整理された知識に拠るシンプルな説明が効果的と言えます。

 

・・・というところです。ついでに前書きと目次を眺めてから、違和感がなければ買うことが多いです。

これらを全て満たす参考書であれば、だいたいハズレたことはありません。

JAXBの簡単な解説(1)

JavaとXML間のバインディングを行うJAXB

JavaオブジェクトからXMLへ変換したい、またはXMLからJavaオブジェクトへ変換したい、ということはよくあるものです。

方法はいくつか考えられますが、JavaSE6 にある標準技術 JAXB (Java Architecture for XML Binding) では、この変換を手軽に実装できるようになっています。その使い方を解説しようと思います。

JAXBの考え方

まずはJAXBの考え方を俯瞰しておきます。

続きを読む JAXBの簡単な解説(1)

Guavaのススメ

Guava: Google Core Libraries for Java 1.5+

GoogleのJavaユーティリティライブラリで、Apache Commons の Lang、Collectionsなどに替わる機能を提供してくれるものです。コンパクトながら、かゆいところに手が届く良質なAPIになっていると思います。

いくつかの機能を紹介します。

コレクションの全ての要素を変換したい

List<A>を基にしてList<B>を作るとします。

ライブラリを使わない場合はこんな感じになるでしょう。

List<B> blist = new ArrayList<B>(alist.size());
for (A a : alist) {
  blist.add(new B(a));
}

Guavaを使う場合は次のように書きます。

List<B> blist = Lists.transform(alist, new Function<A, B>(){
  @Override
  public B apply(A a) {
    return new B(a);
  }
});

おや? どこかで見たような・・・。そう、Commons CollectionsのListUtilsと似ています。が、あちらはジェネリクスを使わないので、ダサいキャストが必要になります。

このリスト変換の利点は、要素を使う時(リストから要素を取り出そうとした時)に初めて変換が行われるところにあります。 続きを読む Guavaのススメ

MySQLのレプリケーションを監視するシェルスクリプト

SHOW SLAVE STATUSG でスレーブの状態をチェックして、問題がありそうな場合はメールを送信するスクリプトのメモです。

意図としては、

  • スレーブプロセスが走ってるか
  • エラーが起きてないか
  • 遅延が許容範囲内か(30秒)

ちなみにMySQLそのものに接続できないとかの場合はこのスクリプトでは対応できません。

#! /bin/sh
#
# watch replication
#

ALERT_TO="{mail-destination}";
ALERT_SUBJECT="[MySQL] replication alert";

CHECK_COMMAND="SHOW SLAVE STATUS\G";
ALLOW_DELAY_SECONDS=30;

echo "$CHECK_COMMAND";
slave_status=`mysql -u {user} -e "$CHECK_COMMAND"`;
echo "$slave_status";

# set variables from status
eval "`echo "$slave_status" | sed -ne 's/: (.*)/="1"/p'`";

if [ "$Slave_IO_Running" != "Yes"  ]; then
    msg="Slave_IO_Running : $Slave_IO_Runningn";
fi

if [ "$Slave_SQL_Running" != "Yes" ]; then
    msg="${msg}Slave_SQL_Running : $Slave_SQL_Runningn";
fi

if [ "$Last_Errno" != "0" ]; then
    msg="${msg}Last_Error : [${Last_Errno}] $Last_Errorn";
fi

if [ "$Seconds_Behind_Master" -gt $ALLOW_DELAY_SECONDS ]; then
    msg="${msg}Seconds_Behind_Master : $Seconds_Behind_Mastern";
fi

if [ "$msg" != "" ]; then
    echo "n-- Need alert mail --";
    echo "$msg";
    (echo "${msg}n${CHECK_COMMAND}n${slave_status}" | mailx -s "$ALERT_SUBJECT" "$ALERT_TO");
fi

JAX-RSのリファレンス実装、Jerseyの使い方(1)

標準のAPIを使ってプログラムを書いておくと色々と都合がいいので、RESTfulなWebサービスを作成しようとするときはJAX-RSを使いたいものです。

JavaEE6には初めから入っているJAX-RSですが、現場ではTomcat5.5(もちろんJava5です)とかが頑張っているのでそのままでは使えません。Apache Tomcat 5.5 と、JAX-RSのリファレンス実装である Jersey 1.4 を使って、単純なRESTサービスを実装する手順を紹介します。

インストールする

まずはJersey1.4のインストールから。Maven2を使っている場合は、java.netのリポジトリを設定します。

(pom.xml に以下を追加)
<repositories>
    <repository>
        <id>maven2-repository.dev.java.net</id>
        <name>Java.net Repository for Maven</name>
        <url>http://download.java.net/maven/2/</url>
        <layout>default</layout>
    </repository>
</repositories>

サーバアプリケーション側のライブラリは以下です。

(pom.xml に以下を追加)
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.4</version>
</dependency>

jarをそのまま使いたい場合は、 http://jersey.java.net/ のDownloadからライブラリをダウンロードしてクラスパスに含めましょう。 続きを読む JAX-RSのリファレンス実装、Jerseyの使い方(1)

例外処理を考える(2)

前回はJavaの例外処理の仕組みについて簡単にまとめました。今回からは実際の例外の扱いについて具体的に考えていきたいと思います。

次の2つの場合を順に考えることにしましょう。

  1. 例外に対処する
  2. 例外を発生させる

例外に対処するときの考え方

何に失敗したのか?

J2SEの標準APIを使っていても、スローされる例外に対処しなければならない機会はそれなりにあるものです。よくあるのはファイル入出力関連・ネットワーク関連・DB関連でしょう。いずれもJVMの外の世界とやりとりするため、予測不可能な事態が発生する可能性は高いと言えます。例外をスローするメソッドが多いのもうなずけます。

「いや、NullPointerExceptionとかIndexOutOfBoundsExceptionをよく見るよ」という方、それはプログラミングエラーです。ご自身のコードをよく見直したほうがいいと思います・・・。

ともあれ、具体的に見てみましょう。ローカルファイルからテキストを読み込んで出力する単純なプログラムを考えてみます。(対処方法はこれから考えていくので、とりあえず例外をキャッチしたらスタックトレースを出力するようにしました) 続きを読む 例外処理を考える(2)

XPath処理エンジンjaxenを使う

デフォルトのXPathは遅くて使い物にならない、と思ったらjaxenを試してみましょう。

jaxen: universal Java XPath engine

使い方はごく簡単です。

XPath xpath = new DOMXPath("/foo/bar");
List<?> nodes = xpath.selectNodes(document);

しかもこのjaxen、universalと謳っているだけあって扱えるのはデフォルトのDOMだけではありません。dom4j, JDOM, XOMを扱えます。使い方はみんな同じで、newするクラスが違うだけです。

ちなみにdom4jとXOMはXPathの処理でjaxenを呼んでいるようです(dom4jの実装は見てないですが)。

XOMでは

nu.xom.Node node;
Nodes nodes = node.query("/foo/bar");

このとき、jaxenのベースクラスを継承したクラスを使ってXPathの評価を行っています。

ちなみにMavenを使っている場合は、pom.xmlに

<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.1.1</version>
</dependency>

を追加すれば使用可能になります。