My Photo

April 04, 2012

サーブレット・JSPメモ018:Struts:Struts設定ファイルを分割した際のパス

環境
JDK 1.6.0_24
Struts 1.3.10

Struts関連の記事:
サーブレット・JSPメモ015:Struts:StrutsタグライブラリでInvalidCancelException
サーブレット・JSPメモ016:Struts:validator-rules.xml
サーブレット・JSPメモ017:Struts:Tilesの利用

モジュール分割するとモジュールごとにStruts設定ファイルを指定できる。下記は web.xml のモジュール分割の設定の例である。

<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
  </init-param>
  <init-param>
    <param-name>config/admin</param-name>
    <param-value>/WEB-INF/struts-config-admin.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

上記の設定の場合、アプリケーションルートが "http://localhost:8080/example/" の場合、adminモジュールには "http://localhost:8080/example/admin/" 以下のURLでアクセスでき、その設定ファイルは struts-config-admin.xml である。
その struts-config-admin.xml のaction要素やforward要素のパス(path属性の値ではなく実際のパスを指定する値)は /admin からの相対パスになる。

<action path="/toTestAction" type="org.apache.struts.actions.ForwardAction" parameter="/user.jsp" />
<action path="/testAction" type="chap06.TestAction" name="sample_userForm"
  parameter="method">
	<forward name="success" path="/sub/result.jsp" />
</action>

struts-config.admin.xml の上記のようなaction要素がある場合、parameter属性の値 "/user.jsp" の user.jsp はadminディレクトリに、forward要素のpath属性の値 "/result.jsp" の result.jsp はadmin/subディレクトリになければならない。

April 02, 2012

サーブレット・JSPメモ017:Struts:Tilesの利用

環境
JDK 1.6.0_24
Struts 1.3.10

Struts関連の記事:
サーブレット・JSPメモ015:Struts:StrutsタグライブラリでInvalidCancelException
サーブレット・JSPメモ016:Struts:validator-rules.xml

Tilesを利用するには struts-config.xml のplug-in要素での設定のほかに、web.xml のinit-param要素で以下の設定をする必要がある。

<init-param>
	<param-name>chainConfig</param-name>
	<param-value>org/apache/struts/tiles/chain-config.xml</param-value>
</init-param>

参考ページ:Struts1.3でTilesタグライブラリを使う|localhost:1981

March 27, 2012

サーブレット・JSPメモ016:Struts:validator-rules.xml

環境
JDK 1.6.0_24
Struts 1.3.10

Struts関連の記事:
サーブレット・JSPメモ015:Struts:StrutsタグライブラリでInvalidCancelException

本ではValidatorの設定ファイルは WEB-INF フォルダに置いて

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
	<set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml" />
</plug-in>

と設定するとある。しかしStrutsが提供するValidatorの検証ルールの設定ファイル validator-rules.xml は Struts 1.3.10 では struts-core-1.3.10.jar に含まれていて、パスは /org/apache/struts/validator/validator-rules.xml である。
よって、設定は

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
	<set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml" />
</plug-in>

とする。Strutsを利用するなら/WEB-INF/lib フォルダに struts-core のjarファイルがあるはずなので、validator-rules.xml をjarファイルから取り出したり自分で作ったりする必要はない。
独自の検証ルールを作る場合は別に設定ファイル(validator-rules-2.xml とか)を作って WEB-INF フォルダに置いて struts-config.xml に追記すればよい。

サーブレット・JSPメモ015:Struts:StrutsタグライブラリでInvalidCancelException

いまさらStrutsの勉強中。「Apache Struts アプリケーション開発入門」という本を読んでいる。
Struts1.2の頃の本なので、本に載っているサンプルコードがそのままでは動かなかったりすることがたまにある。
そういうところをメモ。

環境
JDK 1.6.0_24
Struts 1.3.10

Strutsタグライブラリのhtml:cancelタグを使い、表示されたページのキャンセルボタンを押したら以下のような例外が発生した。

2012/03/27 18:30:40 org.apache.catalina.core.StandardWrapperValve invoke
致命的: サーブレット action のServlet.service()が例外を投げました
org.apache.struts.action.InvalidCancelException
	at org.apache.struts.chain.commands.AbstractValidateActionForm.isCancelled(AbstractValidateActionForm.java:73)
	at org.apache.struts.chain.commands.AbstractValidateActionForm.execute(AbstractValidateActionForm.java:111)
	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
...

struts-config.xmlのaction要素の子要素に
<set-property property="cancellable" value="true"/>
というのを書いてやれば例外は発生しなくなる。

<action path="/operateUser" type="OperateUserAction" name="userForm" parameter="method">
	<set-property property="cancellable" value="true"/>
	<forward name="create" path="/create.jsp" />
	<forward name="update" path="/update.jsp" />
	<forward name="delete" path="/delete.jsp" />
	<forward name="cancelled" path="/cancelled.jsp" />
</action>

参考サイト:Struts 1.2.9のInvalidCancelException - 忘れないようにメモしておこうかな。

March 23, 2012

サーブレット・JSPメモ014:タグライブラリの利用

タグライブラリを利用するには、タグライブラリのクラスファイルにクラスパスを通す。jarファイルの場合は /WEB-INF/libにファイルを置く。
JSPファイルにはtaglibディレクティブを書く。

<%@ taglib uri="<URI>" prefix="<プレフィックス>" %>

URIの指定方法には下記の3通りの方法がある。jarファイルとしてアーカイブされているタグライブラリは3番目の方法が大体は使えるので、web.xml にtaglib要素を書く必要はほとんどの場合ない。

  1. TLDファイルの物理パスを直接指定する。コンテキストルートからのパスかJSPからの相対パスで指定する。
  2. web.xml において定義されたTLDファイルのURIを指定する。 jsp-config要素の子要素のtaglib要素でtldファイルのパスとURIをマッピングする。
    <jsp-config>
      <taglib>
        <taglib-uri>http://taglib-sample.or.jp/taglibs/sample.tld</taglib-uri>
        <taglib-location>/WEB-INF/tld/sample.tld</taglib-location>
      </taglib>
    </jsp-config>
    
    そしてそのURIをtaglibディレクティブのURIとする。
    <%@ taglib uri="http://taglib-sample.or.jp/taglibs/sample.tld" prefix="s" %>
    

  3. TLDファイルで定義されているURIを指定する。TLDファイルでtaglib要素の子要素uriの値をJSPファイルのtaglibディレクティブのURIとする。

February 20, 2012

サーブレット・JSPメモ013:データソース・JNDIの利用

Tomcatでデータソース・JNDIを利用してデータベースに接続する場合、META-INF/context.xml に以下のように記述する(データベースはMySQL)。
Eclipseで動的WEBプロジェクトの場合、Server.xml にそのWEBアプリのContext要素があるので、そちらに Resource要素を書いてもよい。

context.xmlの例
<Context>
    <Resource name="jdbc/mysql" auth="Container"
        type="javax.sql.DataSource"
        username="java" password="password"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost/java_sample_db" />
</Context>

name は任意の名前。この名前を使ってデータソースを取得する。
auth を "Application" とすると認証はアプリ側で行うことになる。
username と password はデータベースに接続するためのユーザ名とパスワード。
driverClass はJDBCドライバのクラス名。
url は getConnection() で直接コネクションを取得するときのURLと同じ。

サンプルコード

package websample;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class DataSourceTest extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/plain");
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();

		try {
			InitialContext initialContext = new InitialContext();
			DataSource dataSource
				= (DataSource) initialContext.lookup("java:comp/env/jdbc/mysql");
			Connection conn = dataSource.getConnection();
			out.println("success: connection=" + conn);

		} catch (SQLException e) {
			throw new ServletException(e);
		} catch (NamingException e) {
			throw new ServletException(e);
		}
	}
}

javax.naming.InitialContext はJNDIを利用する際の窓口で、ファイルシステムにたとえるとルートディレクトリである。

関連する以前の記事:MySQLメモ002:JDBCによる接続

参考ページ:JavaによるWebアプリケーション入門

サーブレット・JSPメモ012:Eclipseで開発している場合のjarファイルを置く場所

動的WEBプロジェクトでWEBアプリを開発している場合、
そのWEBアプリだけで使うjarファイルは、

<プロジェクト>/WebContent/WEB-INF/lib

に置く。
すべてのWEBアプリで使うjarファイルは

<Tomcatのフォルダ>/lib

に置く。ここにあるjarファイルは、プロジェクトのビルドパスの Apache Tomcat v6.0 に入る。

February 17, 2012

サーブレット・JSPメモ011:DB接続するWEBアプリでリロード時に致命的なエラーが出る

参考サイト:MemoryLeakProtectionとJDBC - 人類みんなごくつぶし

サーブレットの入門書のサンプルアプリをEclipse上で動かしていたら、ソース修正によりオートリロードが発生した時にコンソールに

致命的: The web application [/hogehoge] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
というエラーが出た。
「致命的」とか言ってるしなんだろうと思ってググッたら、上記のページに行き当たった。
DBCP というもののバグで別にアプリがまずいわけじゃないらしい。
#DBCP = DataBase Connection Pool でも気になるならWEBアプリの終了時に以下のようなコードでドライバーを外せばエラーはでなくなるとのこと。

Enumeration drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
    Driver driver = drivers.nextElement();
    DriverManager.deregisterDriver(driver);
}

MySQLメモ002:JDBCによる接続

JDBCドライバのダウンロード

以下からダウンロード。
MySQL :: Download Connector/J

動的WEBプロジェクトへのJDBCドライバの導入

プロジェクトの WebContent/WEB-INF/lib フォルダを選択し、
コンテキストメニューでインポートを選択し、
インポート・ソースの選択で一般>ファイルシステム
としてドライバのjarファイルをインポートする。

サンプルアプリ

package appsample;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBSample {

  /**
   * DBへのコネクションを取得する。
   */
  public static Connection getConnection()
      throws ClassNotFoundException, SQLException {

    Class.forName("com.mysql.jdbc.Driver");

    // ホスト名:localhost データベース名:java_sample_db
    // ユーザ:java パスワード:password
    Connection conn = DriverManager.getConnection(
        "jdbc:mysql://localhost/java_sample_db",
        "java", "password");
    return conn;
  }

  public static void main(String[] args) throws Exception {

    String updateSql
      = "UPDATE ACCOUNT SET MONEY=? WHERE NAME=?";
    Connection conn = null;
    PreparedStatement ps = null;
    Statement stmt = null;

    try {
      conn = DBManager.getConnection();
      ps = conn.prepareStatement(updateSql);

      // PreparedStatementを使用した更新
      ps.setInt(1, 6000);
      ps.setString(2, "ボブ");
      int count = ps.executeUpdate();

      // 更新件数の表示
      System.out.println("update count=" + count);

      // 検索
      stmt = conn.createStatement();
      String selectSql = "SELECT * FROM ACCOUNT";
      ResultSet rs = stmt.executeQuery(selectSql);

      while (rs.next()) {
        System.out.println(
          "ID=" + rs.getInt("ID")
          + ",NAME=" + rs.getString("NAME")
          + ",MONEY=" + rs.getInt("MONEY"));
      }

    } finally {
      if (ps != null) {
        try {
          ps.close();
        } catch (Exception e) {
          // nop
        }
      }
      if (stmt != null) {
        try {
          stmt.close();
        } catch (Exception e) {
          // nop
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (Exception e) {
          // nop
        }
      }
    }
  }
}

参考ページ:JavaでJDBCを用いてMySQLへ接続する (前編) - devel-log.tar.gz

February 15, 2012

サーブレット・JSPメモ010:web.xmlのjsp-property-group要素

web.xmlのjsp-config要素の子要素にjsp-property-group要素がある。これを使って複数のJSPに一括で設定をすることができる。
url-pattern要素でURLのパターンから設定するJSPを指定する。
include-prelude、include-code要素には、共通するヘッダ・フッタを指定する。
include-prelude要素に共通部分(pageディレクティブ、taglibディレクティブなど)をまとめたヘッダ用JSPファイルを指定すればいいことありそうだ。たとえば使用するタグライブラリを変更する場合、ヘッダ用JSPのtaglibディレクティブの修正だけで済み、個々のJSPは変更なしで済む。

<jsp-config>
  <jsp-property-group>
    <url-pattern>/products/*</url-pattern>
    <page-encoding>UTF-8</page-encoding>
    <scripting-invalid>false</scripting-invalid>
    <is-xml>false</is-xml>
    <include-prelude>/common/products_header.jsp</include-prelude>
    <include-code>/common/products_footer.jsp</include-code>
  </jsp-property-group>
</jsp-config>
参考ページ:@IT:Java TIPS -- 個別のJSPページでJSTL宣言を省略する
June 2021
Sun Mon Tue Wed Thu Fri Sat
    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      
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof