About smegy things


by smeg_head
カレンダー
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

s2jsf エラーページ

サンプルにも、エラーページの出しかたとかが、書いてなかったので、
(s2jsf-exampleにエラーページのサンプルはありました^^;)
s2jsf-exampleの employeeを調べてみました。
s2jsfのErrorPageManagerImplを使うようです。
s2jsfBlankでエラーページの機能を使ってみます。

strutsの例外処理とかみたいに、メッセージに対応した例外クラスを
用意してその例外が飛んだら、エラーページでそのメッセージを表示
する仕組みのようです。

エラーページの定義は、jsf.diconに書いてありました。コメントに
なってたところを、参考に変更しました。

jsf.dicon

  <component class="org.seasar.jsf.runtime.ErrorPageManagerImpl">
    <initMethod name="addErrorPage">
      <arg>@TestException@class</arg>
      <arg>"/error.html"</arg>
    </initMethod>
  </component>

エラーページを管理するのが、
org.seasar.jsf.runtime.ErrorPageManagerImplで、 initMethod で、
例外クラスとエラーページを指定しているみたいです。
まだ作ってないけど、例外クラスをTestExceptionとして、エラーページ
として、/error.htmlを指定した。

TestExceptionの前に、examples.jsf.exception.AppRuntimeException
を参考にして基になる例外クラスを作った。
#eclipse3.1を使いはじめたんだけど、Serializableなクラスは
#serialVersionUIDを定義するように警告が出た。
#まあ、害もないからいっか。

BaseException.java

import java.text.MessageFormat;
import java.util.ResourceBundle;

/*
* Created on 2005/07/02
* $Id$
*/

public class BaseException extends RuntimeException {
  private static final long serialVersionUID = -200052554991919634L;
  private static final Object[] EMPTY_ARGS = new Object[0];
  private static final String BUNDLE_NAME = "appMessages";
  
  private String messageId;
  private Object[] args;
  public BaseException(String messageId) {this(messageId, EMPTY_ARGS);}
  public BaseException(String messageId, Object[] args) {this(messageId, args, null);}
  public BaseException(String messageId, Object[] args, Throwable cause) {
    initCause(cause);
    this.messageId = messageId;
    this.args = args;
  }
  
  public Object[] getArgs() {return args;}
  public String getMessageId() {return messageId;}
  public String getMessage() {
    ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
    String pattern = bundle.getString(messageId);
    return MessageFormat.format(pattern, args);
  }
}

BaseExceptionを継承して、TestExceptionを作成。
TestException.java

/*
* Created on 2005/07/02
* $Id$
*/

public class TestException extends BaseException {
  private static final long serialVersionUID = -6631291006030705175L;
  public TestException() {
    super("TestMessage"); //messageキーを指定
  }
}


BaseException.BUNDLE_NAME で指定されたプロパティファイル
(s2jsfBlankに入ってる)にTestExceptionのコンストラクタで
指定した messageキーを定義した。

#appMessages_ja.properties

TestMessage=error :-)


簡単のために、index.htmlを表示するときにアクション呼出し
してそこで例外が出ることとする。

<html xmlns:m="http://www.seasar.org/maya"
  m:action="#{testAction.init}">
<body>
Hello
</body>
</html>


app.diconに直接testActionを書いちゃう。(これが原因で後で
エラーになった。)

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
  "http://www.seasar.org/dtd/components.dtd">
<components>
  <include path="jsf.dicon"/>
  <component name="testAction" class="TestAction" instance="request"/>
</components>


実際に例外を投げるクラスTestActionを作る。

/*
* Created on 2005/07/02
* $Id$
*/

public class TestAction {
  public String init() {
    if (true) throw new TestException();
    return null;
  }
}


エラーページを用意する。

<html xmlns:m="http://www.seasar.org/maya">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp"/>
<title>ERROR PAGE</title>
</head><body>
  <h1>ERROR</h1>
  ERROR発生
</body></html>


じゃアクセスしてみるか、とhttp://localhost:8080/s2jsf-blank/
を表示させると、エラーです。

org.seasar.framework.exception.EmptyRuntimeException: [ESSR0007]S2Containerはnullあるいは空であってはいけません
  org.seasar.framework.container.factory.SingletonS2ContainerFactory.getContainer(SingletonS2ContainerFactory.java:46)
  org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:40)


何だっけこれ?

app.diconに書いた以下の行を、jsf.diconに持ってったら、エラーが
出なくなった。

  <component name="testAction" class="TestAction" instance="request"/>

なんでだろう。

実行結果

ERROR


  ERROR発生
  
  error :-)

とりあえず、これで、アクションでthrowした例外によってエラーページで
メッセージを表示することができた。
[PR]
by smeg_head | 2005-07-02 20:55 | s2jsf