Struts1.3.8+Spring2+iBATIS

目次

インストール

環境

  • Java 5.0
  • Tomcat 6.0
  • Oracle10g XE
  • Eclipse 3.4(日本語化済)

Struts1.3.8

  1. http://struts.apache.org/download.cgiからStruts 1.3.8をダウンロード。
  2. 解凍して、webapps配下のstruts-blank-1.3.8.warを$CATALINA_HOME\webapps配下に設置。
  3. Tomcatを起動し、ブラウザでhttp://localhost:8081/struts-blank-1.3.8/を開く。
  4. 成功すると、$CATALINA_HOME\webapps配下にstruts-blank-1.3.8フォルダが出現。
    これを元にEclipseでTomcatプロジェクトを作成する。
    

iBATIS + ABATOR

  1. http://ibatis.apache.org/からiBATIS Java 2.3.4をダウンロード。
  2. 解凍して、lib配下のibatis-2.3.4.726.jarを上のStrutsで作ったプロジェクトのlib配下にコピー。
  3. Eclipseを起動し、ヘルプ→ソフトウェア更新→更新可能なソフトウェア→サイトの追加。
  4. ロケーションにhttp://ibatis.apache.org/tools/abator/を入力。
  5. Abator Code Generator for iBATISを選択しインストール。

Spring2 + Spring IDE

  1. http://sourceforge.net/project/showfiles.php?group_id=73357からspringframework-2をダウンロード。
  2. 解凍して、dist配下のspring.jarを上のStrutsで作ったプロジェクトのlib配下にコピー。
  3. Eclipseを起動し、ヘルプ→ソフトウェア更新→更新可能なソフトウェア→サイトの追加。
  4. ロケーションにhttp://dist.springframework.org/release/IDEを入力。
  5. Spring IDE Update Siteを選択しインストール。
    • この際GEF(Graphical Editing Framework)とWTS(Web Standard Tools)が一緒にインストールされるはず。
    • Eclipse3.3以下だと先にGEFとWTSをインストールする必要がある。面倒くさい。

プロジェクト準備

jarファイルの準備

  • struts-blank-1.3.8を元に作成したプロジェクトに、以下のjarファイルを用意。
    • struts-blankに最初から入ってたjar
      • antlr-2.7.2.jar
      • commons-beanutils-1.7.0.jar
      • commons-chain-1.1.jar
      • commons-digester-1.8.jar
      • commons-logging-1.0.4.jar
      • commons-validator-1.3.1.jar
      • oro-2.0.8.jar
      • struts-core-1.3.8.jar
      • struts-taglib-1.3.8.jar
      • struts-tiles-1.3.8.jar
    • iBATISから
      • ibatis-2.3.4.726.jar
    • Springから(場所がバラバラなのでフォルダ内検索で。)
      • spring.jar
      • spring-webmvc-struts.jar
      • commons-dbcp.jar
      • commons-logging.jar
      • log4j-1.2.15.jar
    • Oracleドライバ(各自用意)
      • ojdbc14.jar
        全部使うかは謎。
        common-loggingが2個あるのは多分どちらかが不要なのか?
        

フォルダ構成

Exam(プロジェクト名)
 ├src(ソースフォルダ)
 │ └example
 │  ├action
 │  ├bean
 │  ├biz
 │  ├dao
 │  └sqlMap(iBATIS用)
 ├pages(JSP置き場)
 └WEB-INF(各種定義ファイル)

使用テーブル

  1. EMP
    • EMPNO(CHAR)
    • EMPNAME(VARCHAR2)
    • DEPTNO(CHAR)
  2. DEPT
    • DEPTNO(CHAR)
    • DEPTNAME(VARCHAR2)
      従業員番号を入力すると、従業員名と部署名が返ってくる簡単なものを作ってみる。
      

手順

ABATORによるDAO自動生成

  1. Eclipseのパッケージエクスプローラ上でプロジェクト名を右クリック→新規→その他。
  2. Abator for iBATIS Wisardsの中のAbator for iBATIS Configuration Fileを選択し次へ。
  3. ロケーションを/WEB-INF/配下にして終了すると、abatorConfig.xmlが作成される。???の部分を以下のように書き加える。
    <?xml version="1.0" encoding="UTF-8" ?>
     <!DOCTYPE abatorConfiguration PUBLIC "-//Apache Software Foundation//DTD Abator for iBATIS Configuration 1.0//EN"
       "http://ibatis.apache.org/dtd/abator-config_1_0.dtd" >
    
     <abatorConfiguration >
      <abatorContext >
       <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost:1521:xe" userId="userID"
      password="pass" >
         <classPathEntry location="ojdbc14.jarのフルパス" />
       </jdbcConnection>
    
       <javaModelGenerator targetPackage="example.bean" targetProject="Exam" />
       <sqlMapGenerator targetPackage="example.sqlMap" targetProject="Exam" />
       <daoGenerator targetPackage="example.dao" targetProject="Exam" type="GENERIC-CI" />
    
       <table tableName="EMP" >
         <columnOverride column="EMPNO" property="empNo" javaType="String" jdbcType="CHAR" />
         <columnOverride column="EMPNAME" property="empName" javaType="String" jdbcType="VARCHAR2" />
         <columnOverride column="DEPTNO" property="deptNo" javaType="String" jdbcType="CHAR" />
       </table>
       <table tableName="DEPT" >
         <columnOverride column="DEPTNO" property="deptNo" javaType="String" jdbcType="CHAR" />
         <columnOverride column="DEPTNAME" property="deptName" javaType="String" jdbcType="VARCHAR2" />
       </table>
    
      </abatorContext>
     </abatorConfiguration>
    
  4. 保存したら、abatorConfig.xmlを右クリック→Generate iBATIS Artifactsを選択。src/example配下にファイルが自動生成される。
    example
     ├bean
     │ ├Dept.java
     │ ├DeptExcample.java
     │ ├Emp.java
     │ └EmpExample.java
     ├dao
     │ ├DeptDAO.java
     │ ├DeptDAOImpl.java
     │ ├EmpDAO.java
     │ └EmpDAOImpl.java
     └sqlMap
      ├Dept_SqlMap.xml
      └Emp_SqlMap.xml
    

beanのカスタマイズとテーブル内部結合用のsql作成

  1. Emp.javaでDEPTNAMEも扱えるようにする。
    • Emp.javaにprivate String deptNameを作成し、getter/setterを作る。
      他にもやり方はあるがこれが一番単純なので。
      
  2. EMPとDEPTを内部結合した結果を取得できるようにする。
    • Emp_SqlMap.xmlを開き、resultMapにDEPTNAMEを追加、新規sql文を作成する。
       <resultMap id="abatorgenerated_EmpResult" class="example.bean.Emp" >
         <result column="EMPNO" property="empNo" jdbcType="CHAR" />
         <result column="EMPNAME" property="empName" jdbcType="VARCHAR2" />
         <result column="DEPTNO" property="deptNo" jdbcType="CHAR" />
         <result column="DEPTNAME" property="deptName" jdbcType="VARCHAR2"/>  //追加するカラム
       </resultMap>
       <sql id="abatorgenerated_Example_Where_Clause" >
       :
       </sql>
       <select id="getEmp" resultClass="example.bean.Emp">  //新しく追加するsql文
       	SELECT EMP.EMPNO, EMP.EMPNAME, DEPT.DEPTNAME AS DEPTNAME
       	FROM EMP, DEPT
       	WHERE EMP.DEPTNO = DEPT.DEPTNO
       	AND EMP.EMPNO = #VALUES#   //#VALUES#は後で引数を受け取る部分
       </select>
       :
      
  3. sqlMapConfig.xml(sqlMap定義ファイル)をsrc/example/sqlMap配下に作成
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
    <sqlMapConfig>
       <settings useStatementNamespaces="true" />
       <transactionManager type="JDBC">
           <dataSource type="SIMPLE">
               <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" />
               <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:1521:xe" />
               <property name="JDBC.Username" value="userID" />
               <property name="JDBC.Password" value="pass" />
           </dataSource>
       </transactionManager>
       <sqlMap resource="example/sqlMap/EMP_SqlMap.xml" />
       <sqlMap resource="example/sqlMap/DEPT_SqlMap.xml" />
    </sqlMapConfig>
    
  1. dao.xml(DAO定義ファイル)をsrc/sqlMap配下に作成
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE daoConfig PUBLIC "-//iBATIS.com//DTD DAO Configuration 2.0//EN"
    "http://www.ibatis.com/dtd/dao-2.dtd">
    <daoConfig>
      <context>
          <transactionManager type="SQLMAP">
              <property name="SqlMapConfigResource" 
              value="sqlMapConfig.xml" />
          </transactionManager>
          <dao interface="example.dao.EmpDAO" implementation="example.dao.EmpDAOImpl" />
          <dao interface="example.dao.DeptDAO" implementation="example.dao.DeptDAOImpl" />
       </context>
    </daoConfig>
    
  2. AppSqlConfig.java(SqlMapClientを一度だけ作成し取得するためのクラス)をexample/sqlMap配下に作成。
    import java.io.Reader;
    import com.ibatis.common.resources.Resources;
    import com.ibatis.sqlmap.client.SqlMapClient;
    import com.ibatis.sqlmap.client.SqlMapClientBuilder;
    
    public class AppSqlConfig {
    	private static SqlMapClient sqlMap;
    	static {
    		try {
    			String resource = "jp/co/los/Sample001/sqlMap/sqlMapConfig.xml";
    			Reader reader = Resources.getResourceAsReader(resource);
    			sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	public static SqlMapClient getSqlMapInstance() {
    		return sqlMap;
    	}
    }
    

IDEで定義ファイル作成

  1. パッケージエクスプローラ上でプロジェクト名を右クリック→Spring ToolsAdd Spring Project Natureを選択。
    • パッケージエクスプローラのプロジェクトのアイコンの文字がJからSに変わる。
  2. パッケージエクスプローラ上でプロジェクト名を右クリック→新規→その他→Spring→Spring Bean Definitionを選択し次へ。
  3. 親フォルダをWEB-INFにし、名前(ここではapplicationContextとする)を入力し次へ。
  4. beansのすぐ下のcontextにもチェックを入れて終了。
  5. WEB-INF配下にxmlファイルが作成されるので、以下のように書き加える。
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    	<context:component-scan base-package="example"/>  //書き加える部分。base-packageはsrc配下のexampleを入力。
    
    </beans>
    

画面と各種定義ファイルの作成。

  1. ログイン画面(login.jsp)の作成
    <%@page pageEncoding="Windows-31J" contentType="text/html; charset=Windows-31J" %>
    <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-31J"/>
    <title>ログイン画面</title>
    </head>
    <body>
    <html:form action="/login">
    <div>
    	ログインID:<input type="text" name="empNo">
    	<html:submit value="送信"/>
    </div>
    </html:form>
    </body>
    </html>
    
  2. ログイン成功時画面(success.jsp)の作成
    <%@page pageEncoding="Windows-31J" contentType="text/html; charset=Windows-31J" %>
    <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
    <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-31J"/>
    <title>テスト</title>
    </head>
    <body>
    <div>
    	<h1>Hello, <bean:write name="empNo" scope="session"/>:<bean:write name="empName" scope="session"/>さん
    	(<bean:write name="deptName" scope="session"/>)</h1>  //従業員No:従業員名さん(部署名)という風に表示させる。
    </div>
    </body>
    </html>
    
  3. web.xmlの修正
    <?xml version="1.0" encoding="ISO-8859-1"?>
     <!DOCTYPE web-app PUBLIC
    	"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    	"http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
     <display-name>Sample Application</display-name>
     <session-config>
    	<session-timeout>30</session-timeout>
     </session-config>
    
     <servlet>
      <servlet-name>example</servlet-name>
       <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
       <init-param>
         <param-name>spring.autowire</param-name>  //今回はSpringのAutowire機能を使う。
         <param-value>byName</param-value>
       </init-param>
       <load-on-startup>2</load-on-startup>
     </servlet>
    
     <servlet-mapping>
       <servlet-name>example</servlet-name>
       <url-pattern>*.do</url-pattern>
     </servlet-mapping>
    
    </web-app>
    
  4. struts-config.xmlの修正
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts-config PUBLIC
             "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
             "http://struts.apache.org/dtds/struts-config_1_3.dtd">
    
    <struts-config>
       <form-beans>
          <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">
          	<form-property name="empNo" type="java.lang.String" />
          	<form-property name="empName" type="java.lang.String" />
          	<form-property name="deptName" type="java.lang.String" />
          </form-bean>
       </form-beans>
    
       <action-mappings>
       	<action path="/home" forward="/pages/login.jsp" />
       	<action path="/login" type="example.action.LoginAction" name="loginForm">
       		<forward name="success" path="/pages/success.jsp" />
       		<forward name="failure" path="/pages/login.jsp" />  //ログインに失敗したときはログイン画面に戻る。
       	</action>
       </action-mappings>
    
       <controller processorClass="org.springframework.web.struts.AutowiringRequestProcessor"/>
       <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
    		<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
       </plug-in>    
    </struts-config>
    

ログイン処理インターフェイスとログイン処理実装クラスの作成

  1. LoginService.java(インターフェイス)をsrc/example/biz配下に作成。
    package example.biz;
    
    import example.bean.Emp;
    
    public interface LoginService {
    	public Emp execute(String empNo);
    }
    
  2. LoginServiceImpl.java(実装クラス)をsrc/example/biz配下に作成。
    package example.biz;
    
    import org.springframework.stereotype.Service;
    import example.sqlMap.AppSqlConfig;
    import com.ibatis.sqlmap.client.SqlMapClient;
    import example.bean.Emp;
    
    @Service("loginService")  //アノテーションを利用したBean定義
    
    public class LoginServiceImpl implements LoginService {
    	public Emp execute(String empNo) {
    		SqlMapClient sqlMap = AppSqlConfig.getSqlMapInstance();
    		Emp emp = new Emp();
    		try {
    			emp = (Emp)sqlMap.queryForObject("EMP.getEmp",empNo);  //(1)
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return emp;
    	}
    }
    
    • (1)…EMP_sqlMap.xmlで設定したSQL文を呼び出す。2つ目の引数は#VALUES#に入る。

Actionクラスを作成

package example.action;

import org.apache.struts.action.Action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.springframework.beans.factory.annotation.Autowired;
import example.bean.Emp;
import example.biz.LoginService;

public class LoginAction extends Action {

	@Autowired  //……(1)
	private LoginService loginService = null;

	@Override
	public ActionForward execute(
			ActionMapping mapping,
			ActionForm form,
			HttpServletRequest req,
			HttpServletResponse res
			) throws Exception {

		HttpSession session = req.getSession();
		DynaActionForm dynaForm = (DynaActionForm)form;

		String empNo = dynaForm.getString("empNo");
 		Emp emp = loginService.execute(empNo);

		// 該当する従業員番号があればログイン成功とする。
		if (emp != null) {
			session.setAttribute("empNo", emp.getEmpNo());
			session.setAttribute("empName", emp.getEmpName());
			session.setAttribute("deptName", emp.getDeptName());

			return mapping.findForward("success");
		}
		return mapping.findForward("failure");
	}
}
  • (1)byNameでのオートワイヤリングなので,LoginServiceImplで指定している@Serviceの引数とLoginActionクラスの@Autowiredが指定してあるフィールドloginService の名称をあわせることでDIされる。

参考URL

最終更新:2008年11月18日 11:58
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。