Code Log

プログラミングの勉強メモを残していきます。

Tomcat上のサーブレットで、データベースから値をselectするためのcontext.xmlやweb.xmlの書き方


<スポンサーリンク>

RDB:MySQL
データベース名:test
テーブル名:members
テーブルの中身

mysql> select * from members;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | takashi | 20   |
|  2 | satoshi | 30   |
+----+---------+------+
2 rows in set (0.00 sec)

ディレクトリ構成は以下のとおりで、コンテキストルート(Eclipseでtomcatプロジェクトを作るなら、プロジェクト名)の直下にWEB-INFとMETA-INFをおきます。

├─sample-web
│  │  build.xml
│  │
│  ├─bin
│  ├─META-INF
│  │      context.xml
│  │
│  ├─src
│  ├─WEB-INF
│  │  │  web.xml
│  │  │
│  │  ├─classes
│  │  │  └─sample
│  │  │          SampleServlet.class
│  │  │
│  │  ├─lib
│  │  │      mysql-connector-java-5.0.8-bin.jar
│  │  │
│  │  └─src
│  │      └─sample
│  │              SampleServlet.java
│  │
│  └─work

META-INFの下にはcontext.xmlをおきます。
WEB-INFの下にはweb.xmlをおきます。WEB-INF/libには必要なjarを配置しましょう。

まず、context.xmlの書き方ですが、以下のように書きます。

<Context reloadable="true">
	<Resource name="jdbc/test" auth="Container"
		type="javax.sql.DataSource"
		username="root"
		password="1234"
		driverClassName="com.mysql.jdbc.Driver"
		url="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8"
		validationQuery="Select 1"/>
</Context>

英語ですが、以下のサイトがわかりやすいです。
https://confluence.atlassian.co.jp/display/DOC/Configuring+a+MySQL+Datasource+in+Apache+Tomcat


MySQL以外のDBを使っても、ここのcontext.xmlを修正すれば、JDBCを入れ替えることが可能です。

web.xmlは以下のように書きます。

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">

  <servlet>
    <servlet-name>sample</servlet-name>
    <servlet-class>sample.SampleServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>sample</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

  <resource-ref>
  	<res-ref-name>jdbc/test</res-ref-name>
  	<res-type>javax.sql.DataSource</res-type>
  	<res-auth>Container</res-auth>
  </resource-ref>
</web-app>

resource-refのタグで、res-ref-nameという子要素があるんですが、ここでcontext.xmlで設定した内容を参照しているわけです。

では、サーブレットを見てみます。

package sample;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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 SampleServlet extends HttpServlet {
	private DataSource ds;

	public void init() throws ServletException {
		try {
			ds = (DataSource) (new InitialContext()).lookup("java:comp/env/jdbc/test");
		} catch (NamingException e) {
			throw new ServletException();
		}
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res)
					throws ServletException, IOException {
		try {
			Connection con = ds.getConnection();

			Statement stmt = con.createStatement();
			String sql = "select * from members";
			ResultSet rs = stmt.executeQuery(sql);
			while (rs.next()) {
				String name = rs.getString("name");
				String age = rs.getString("age");
				System.out.println("名前:" + name);
				System.out.println("年齢:" + age);
			}

		} catch (SQLException e) {

			e.printStackTrace();
		}
	}
}

データソースを引っ張ってきているのは以下の部分です。

ds = (DataSource) (new InitialContext()).lookup("java:comp/env/jdbc/test");

「java:comp/env/」の部分はお決まりの接頭辞のようなもので、その後ろにリソース名を書きます。

これで普通にURLにリクエストを飛ばすと、コンソールに

名前:takashi
年齢:20
名前:satoshi
年齢:30

と吐かれます。
なお、私はビルドにAntを使いました。
build.xmlも参考までに載せておきます。

<?xml version="1.0" encoding="UTF-8" ?>
<project basedir="." default="build">
	<property name="name" value="sample-web"/>
	<property name="base.dir" value="."/>
	<property name="appserver.dir" value="C:\\eclipse\pleiades_XXXX\tomcat\6"/>
	<property name="deploy.dir" value="${appserver.dir}/webapps"/>
	<property name="src.dir" value="src"/>

	<property name="build.dir" value="${base.dir}/WEB-INF/classes"/>

	<path id="master-classpath">
		<fileset dir="${base.dir}/WEB-INF/lib">
			<include name="*.jar"/>
		</fileset>
		<fileset dir="${appserver.dir}/lib">
			<include name="*.jar"/>
		</fileset>
		<pathelement path="${build.dir}"/>
	</path>

	<target name="build" description="Complie main source tree java files">
		<mkdir dir="${build.dir}"/>
		<javac destdir="${build.dir}" debug="true" failonerror="true">
			<src path="${src.dir}"/>
			<classpath refid="master-classpath"/>
		</javac>
	</target>

	<target name="deploy" depends="build" description="Deploy Application">
		<copy todir="${deploy.dir}/${name}" preservelastmodified="true">
			<fileset dir="${base.dir}">
				<include name="**/*.*"/>
			</fileset>
		</copy>
	</target>

	<target name="clean">
		<delete failonerror="false">
			<fileset dir="${build.dir}">
				<include name="**.*.class"/>
				<include name="**.*.properties"/>
			</fileset>
		</delete>
	</target>

</project>

ant deployを実行すると、自動でTomcatにデプロイすることができます。

なお、Eclipseで開発していて、context.xmlを修正しても

Cannot create JDBC driver of class '' for connect URL 'null'

のようなエラーが出る場合は、

$CATALINA_BASE/conf/CATALINA/localhost/

以下にある、「コンテキスト名.xml」に修正が反映されていない可能性があります。

Eclipseで開発するなら、
C:\eclipse\pleiades_XXX\tomcat\6\conf\Catalina\localhost
みたいなディレクトリです。
Eclipseのインストールディレクトリを見てください。

http://gae-fan.blogspot.jp/2012/03/tomcat6oracle.html

スッキリわかるサーブレット&JSP入門

スッキリわかるサーブレット&JSP入門