ページの先頭行へ戻る
Interstage Business Application Server 12.0.0 オープンJavaフレームワークユーザーズガイド Java EE 7編
FUJITSU Software

3.5.4 アプリケーションの実装

以下の4パターンのアプリケーション実装方法の例を示します。

  1. 基本的なアプリケーションの作成

  2. データベースにアクセスするアプリケーションの作成

  3. 他フレームワークと連携するアプリケーションの作成

  4. 他アプリケーションと連携するアプリケーションの作成

3.5.4.1 基本的なアプリケーションの作成

ポイント

Interstage Studio上におけるSpring Frameworkアプリケーション開発用プロジェクトの作成方法については、“3.5.6 Spring IDEによるSpring Frameworkアプリケーションの作成”を参照してください。

基本的なSpring Frameworkアプリケーションの開発の手順を説明します。

  1. AP層の作成

  2. Web層の作成

  3. 定義ファイルの作成

アプリケーションの作成は、基本的に「Springプロジェクト・ネーチャーの追加を行ったWebアプリケーションプロジェクト」でします。AP層とWEB層の資材および定義ファイルをWARファイルにまとめます。

(1) AP層の作成

Web層からの要求に応じて呼び出される業務アプリケーションを作成します。業務アプリケーションでは、データベースとのやり取りなどの処理を行い、処理結果をWeb層に返します。

■EmployeeDao.java(DAOのインターフェース)

package test;
public interface EmployeeDao {
    public void init();
    public void destroy();
    public String[] execDaoSelect();
    public boolean execDaoInsert(String Employee);
    public boolean execDaoDelete(String Employee);
}

■EmployeeDaoImpl.java(DAOの実装クラス)

package test;
@Repository 
public class EmployeeDaoImpl implements EmployeeDao{
    public void init() {
        // 初期処理
    }
    public void destroy() {
        // 終了処理
    }
    // AOPが差し込まれる対象となるメソッド
    public String[] execDaoSelect(){
        String[] data = null;
        // データベースから社員全員の名前を取得します
        //data[] = ...
        return data;
    }
    // AOPが差し込まれる対象となるメソッド
    public boolean execDaoInsert(String Employee){
        boolean ret = true;
        // データベースに指定した社員名を登録します
        //ret = ...
        return ret;
    }
    // AOPが差し込まれる対象となるメソッド
    public boolean execDaoDelete(String Employee){
        boolean ret = true;
        // データベースから指定した社員を削除します
        //ret = ...
        return ret;
    }
}

■ListService.java(業務アプリケーションのインターフェース)

package test;
public interface ListService {
    public String[] getEmployeeList();
}

■ListServiceImpl.java(業務アプリケーションの実装クラス)

package test;
@Service
public class ListServiceImpl implements ListService {
    // DIによって生成されたインスタンスが格納されます
    @Autowired
    private EmployeeDao employeeDao;
    public String[] getEmployeeList() {
        // 社員の名前一覧を返却します
        String[] employeeList = employeeDao.execDaoSelect();
        return employeeList;
    }
}

■AopDatabaseCheck.java(AOPで差し込む処理)

package test;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Component
@Aspect
public class AopDatabaseCheck{
    // データベースに関するチェック処理を指定されたメソッドの前後で処理をします
    @Around("execution(* execDao*())")
    public Object aroundMessage( ProceedingJoinPoint pjp ) throws Throwable {
        try{
            // DBチェック処理
        }catch(Exception e){
            throw e;
        }
        // AOPによって処理を差し込んだため、もとの処理を呼び出します
        Object retval = pjp.proceed() ;
        // メッセージ
        System.out.println("...");
        return retval ;
    }
}

(2) Web層の作成

クライアントからの要求をAP層に引き渡すコントローラを作成します。また、業務アプリケーションの処理結果などをビューとして表示するためのJSPを作成します。

業務アプリケーションを呼び出すコントローラの作成例を以下に示します。

■ViewEmployeeListController.java(社員一覧を表示するコントローラ)

package test;
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewEmployeeListController extends AbstractController{
    @Autowired
    private ListService businessService;
    @RequestMapping("/ViewEmployeeList")
    public Map viewEmployeeList() {
        Map<String,Object> model = new HashMap<String,Object>();
        // 業務アプリケーションから社員の名前一覧を取得します
        String[] employeeList = businessService.getEmployeeList();
        // 処理結果をビューに伝播するためmodelに設定します
        model.put("employeeList", employeeList);
        return model;
    }
}

■ViewEmployeeList.jsp(社員一覧を表示するビュー)

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>社員名簿</title>
    </head>
    <body>
        <table border="1" cellspacing="2" cellpadding="3">
            <tr>
                <td><b>No.</b></td>
                <td><b>名前</b></td>
            </tr>
            <!-- (a) -->
            <c:forEach var="employee" items="${employeeList}" varStatus="no">
            <tr>
                <td><b></b><c:out value="${no.index + 1}"/></td>
                <td><c:out value="${employee}"/></td>
            </tr>
            </c:forEach>
        </table>
    </body>
</html>

(a) ModelAndViewに設定された社員全員の名前のリスト“employeeList”の情報を表示します。

(3) 定義ファイルの作成

Spring Frameworkランタイムは作成したBean定義ファイルに従って動作します。

運用形態に応じて用意するBean定義ファイル数は異なり、基本型の場合は、最低1つのBean定義ファイルを作成します。Web-AP分離型の場合は、最低2つのBean定義ファイルを作成します。

Bean定義ファイルにはSpring Frameworkアプリケーションで利用するクラスをBeanとして定義します。必要に応じてAOPやDB、トランザクションなどの定義を記述します。

この例では、基本型の定義ファイルの例を記述します。

■applicationContext.xmlまたはサーブレット名-servlet.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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- (a) AOP定義 -->
    <aop:aspectj-autoproxy/>
    <!-- AOP定義から参照されるクラスをbeanとして定義します -->
    <bean id="sampleAdvice" class="test.aopDatabaseCheck" />
    <!-- (b) ビューの定義 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- (c) コントローラの定義 -->
    <mvc:annotation-driven/>
    <context:component-scan base-package="test"/>
    <!-- (d) ハンドラーマッピング-->
    <mvc:default-servlet-handler/>
    <!-- (e) 業務アプリケーションで使用するBeanの定義-->
    <bean id="businessService" class="test.ListServiceImpl">
        <property name="employeeDao" ref="employeeDao00"/>
    </bean>
    <bean id="employeeDao00" class="test.EmployeeDaoImpl" />
</beans>

(a) AOP定義

指定したクラス/メソッドに、指定したタイミングで、Beanとして定義したクラスの指定したメソッドを実行します。

処理を実行するクラス/メソッドには、前方/後方/完全一致などの条件を指定でき、処理を実行するタイミングは、指定したメソッドの直前/直後/前後や例外発生時などを指定できます。

(b) ビューの定義

業務アプリケーションの処理結果をビューで表示するためにビューリゾルバを指定します。

(c) コントローラの定義

業務アプリケーションおよび業務アプリケーションの処理結果を格納するコントローラを指定します。

(d) ハンドラーマッピング

リクエストURLとコントローラを関連付けるための条件をハンドラーマッピングに定義します。

(e) 業務アプリケーションで使用するBeanの定義

Beanとして定義したクラスは、DIによって実行時に自動的にインスタンスが生成されます。

ポイント

beanタグのid属性に使用可能な文字はXML名前空間のNCName型です。NCName型に準拠しない文字を使用したい場合はid属性の代わりにname属性を使用する必要があります。

3.5.4.2 データベースにアクセスするアプリケーションの作成

ポイント

MyBatisを使用したデータベースにアクセスするアプリケーションの作成については、“4.4.5.2 MyBatisを使用するSpring Frameworkのアプリケーションの作成”を参照してください。

JPAを使用して、ブラウザ経由でEnterprise Postgresのテーブルに値を追加するアプリケーションを作成します。

データベースにアクセスするアプリケーションの作成として、JPAを使用したO/Rマッピングアプリケーションの開発手順を説明します。

以下の手順は、Spring Framework 4.3でJPAを使用したO/Rマッピングを実現するために必要な手順です。手順4以降はSpring MVC Webアプリケーションとして必要な手順です。

  1. エンティティクラスの作成

  2. 設定ファイルの作成

  3. データベースアクセスクラスの作成

  4. サービスクラスの作成

  5. コントローラクラスの作成

  6. JSP画面の作成

(1) エンティティクラス作成

エンティティクラスを作成します。エンティティクラスにはEntityアノテーションを指定してください。

エンティティクラス:

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="test")
public class UserModel {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column(name="name")
    private String name;
    public void setName(String name) {
        this.name = name;
    }
}

(2) 設定ファイルの作成

Spring Framework 4.3がJPAに接続するには、下記のファイル設定が必要です。

Bean定義ファイルの設定例を以下に示します。

Bean定義ファイル:

<?xml version="1.0" encoding="UTF-8"?>
    <!--- JNDIからデータソースを取得 -->
    <jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/em"/> 
    <!--- トランザクションマネージャの設定 -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
        <property name="allowCustomIsolationLevels" value="true"/> 
    </bean>
</beans>

persistence.xmlの設定については、“Interstage Application Server Java EE 7設計・構築・運用ガイド”の“JPAの提供機能”、web.xmlの設定については、“Interstage Application Server Java EE 7設計・構築・運用ガイド”の“JNDI”を参照してください。

deployment descriptor(persistence.xml):

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--- ユニット名とトランザクション種別の指定 -->
    <persistence-unit name="testUnit" transaction-type="JTA">
        <!--- 接続先のJDBCリソースを指定 -->
        <jta-data-source>Test_DataSource</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes/>
        <properties>
            <!--- 接続先データベースに応じたプラットフォームクラスを指定 -->
            <property name="eclipselink.target-database" 
                value="org.eclipse.persistence.platform.database.OraclePlatform"/>
            <!--- テーブルの自動生成 -->
            <property name="eclipselink.ddl-generation" value="create-tables" />
        </properties>
    </persistence-unit>
</persistence>

Web application deployment descriptor(web.xml):

    <javaee:persistence-unit-ref>
        <!--- Bean定義で定義した値を指定  -->
        <javaee:persistence-unit-ref-name>persistence/em</javaee:persistence-unit-ref-name>
        <!--- deployment descriptorで定義した値を指定  -->
        <javaee:persistence-unit-name>testUnit</javaee:persistence-unit-name>
    </javaee:persistence-unit-ref>

(3) データベースアクセスクラスの作成

データベースにアクセスするためのクラスを作成します。データベースアクセスクラスを作成する前に、DAOインターフェースを作成します。

DAOインターフェース:

package com.example.service;
import com.example.model.UserModel;
public interface UserDao { 
    public void add(UserModel userModel,String name); 
}

DAOインターフェースを実装して、データベースアクセスクラスを作成します。データベースにアクセスするために、セションファクトリを使用します。

データベースアクセスクラス:

package com.example.service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import com.example.model.UserModel;
@Repository
public class UserDaoImpl implements UserDao {
    @PersistenceContext
    private EntityManager em;
    @Override
    public void add(UserModel userModel,String name) {
        em.merge(userModel).setName(name);
    }
}

(4) サービスクラスの作成

コントローラクラスとデータベースアクセスクラスの橋渡しをするサービスクラスを作成します。サービスクラスを作成する前に、実装するサービスDaoインターフェースを作成します。

サービスDAOインターフェース:

package com.example.service;
import com.example.model.UserModel;
public interface JpaService { 
    public void add(UserModel userModel,String name);
}

サービスDAOインターフェースを実装して、サービスクラスを作成します。

サービスクラス:

package com.example.service;
import javax.persistence.PersistenceUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.model.UserModel;
@Service
public class JpaServiceImp implements JpaService {
    @Autowired
    private UserDao userDao;
    @Override
    @Transactional
    public void add(UserModel userModel,String name){
        this.userDao.add(userModel,name);
    }
}

(5) コントローラクラスの作成

コントローラクラスを作成します。

コントローラクラス:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.context.annotation.Scope;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.model.UserModel;
import com.example.service.JpaService;
@Controller
@Scope(value = WebApplicationContext.SCOPE_REQUEST)
public class UserController {
    @Autowired
    private JpaService userService;
    UserModel userModel = new UserModel();
    @RequestMapping(value="/add", method=RequestMethod.POST)
    public String add(@RequestParam("name") String name,Model model) {
    	userService.add(userModel,name);
    	return "index";
    }
}

(6) JSP画面の作成

JSP画面を作成します。

JSP画面:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>index</title>
    </head>
    <body>
        <form action="add" method="POST">
          Name:<input type="text" name="name"/><br/>
            <input value="add" type="submit"/>
        </form>
    </body>
</html>

3.5.4.3 他フレームワークと連携するアプリケーションの作成

WebSocketを利用したメッセージ送信アプリケーションを作成します。

他フレームワークと連携するアプリケーションの作成として、WebSocketと連携したアプリケーションの開発手順を説明します。

以下の手順は、Spring Framework 4.3でWebSocketと連携するために必要な手順です。手順3はWebSocketとして必要な手順です。

  1. ハンドラークラスの作成

  2. 設定クラスの作成

  3. JSP画面の作成

(1) ハンドラクラスの作成

テキストデータを扱うため、TextWebSocketHandlerを継承してハンドラークラスを作成します。

ハンドラクラスの作成:

package websocket.handler;
import static java.util.Map.Entry;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.logging.Logger;
public class ChatHandler extends TextWebSocketHandler {
    private Map<String, WebSocketSession> map = new ConcurrentHashMap<>();
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        this.map.put(session.getId(),webSocketSession);
    }
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession,
            CloseStatus status) throws Exception {
        this.map.remove(webSocketSession.getId());
    }
    @Override
    public void handleTextMessage(WebSocketSession webSocketSession, TextMessage message) throws Exception {
        entry.getValue().sendMessage(message);
    }
}

(2) 設定クラスの作成

WebSocketConfigurerインターフェースを実装して、設定クラスを作成します。

設定クラス:

package websocket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import websocket.handler.ChatHandler;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry)
    {
        //エンドポイントchatを指定
        registry.addHandler(new EchoHandler(), "/chat");
    }
}

(3) JSP画面の作成

JSP画面:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Test</title>
    <style type="text/css">
        #display {
            font-size: small;
            border: 1px solid #000000;
            overflow-y: scroll;
            height: 200px;
            width: 500px;
        }
        #display p {
            padding: 0;
            margin: 0;
        }
    </style>
<script type="text/javascript" src="./jquery.js"></script>
    <script type="text/javascript">
        var ws = null;
        
        function Status(connected){
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('send').disabled = !connected;
        }
        function connect(){
            ws = new WebSocket('ws://websocket/websocket_test/echo');
            ws.onopen = function(){
                Status(true);
                log('Connect!');
            };
            ws.onmessage = function(event){
                log(event.data);
            };
            ws.onclose = function(event){
                Status(false);
                log('Disconnect!');
            };
        }
        function disconnect(){
            if(ws != null){
                ws.close();
                ws = null;
            }
            Status(false);
        }
        function send(){
            var message = document.getElementById('message').value;
            if(message.length != 0){
                ws.send(message);
            }else{
                <!-- messageが空の場合は送信しない -->
            }
        }
        function log(message){
            var display = document.getElementById('display');
            var p = document.createElement('p');
            p.appendChild(document.createTextNode(message));
            display.appendChild(p);
            display.scrollTop = display.scrollHeight;
        }
    </script>
</head>
<body>
    <div>
        <button id="connect" onclick="connect();">Connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
    <div>
        <input type="text" id="message" size="50" maxlength="30" placeholder="Message" />
        <button id="send" onclick="send();" disabled="disabled">Send</button>
    </div>
    <div id="display"/>
</body>
</html>

3.5.4.4 他アプリケーションと連携するアプリケーションの作成

現在時刻を取得するEJB 3.xアプリケーションと連携するアプリケーションを作成します。

他アプリケーションと連携するアプリケーションの作成として、EJBと連携したアプリケーションの開発手順を説明します。

以下の手順は、Spring Framework 4.3でEJBアプリケーションと連携するために必要な手順です。手順3以降はSpring MVC Webアプリケーションとして必要な手順です。

  1. EJBアプリケーションの作成

  2. Bean定義ファイルの作成

  3. コントローラクラスの作成

  4. JSP画面の作成

(1) EJBアプリケーションの作成

連携するEJBアプリケーションを作成します。

連携するEJBアプリケーションには、StatelessアノテーションにBeanマッピング名を定義してください。

ローカルインターフェース:

package com.example.ejb;
import javax.ejb.Local;
@Local
public interface TestEJBLocal {
    public String sendTime();
}

リモートインターフェース:

package com.example.ejb;
import javax.ejb.Remote;
@Remote
public interface TestEJBRemote {
    public String sendTime();
}

EJBアプリケーション:

package com.example.ejb;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import java.util.Date;
// Beanマッピング名を指定
@Stateless(mappedName = "ejb/TimeSender")
@LocalBean
public class TestEJB implements TestEJBRemote, TestEJBLocal {
@Override
    public String sendTime() {
        Date date = new Date();
        return date.toString();
    }
}

(2) Bean定義ファイルの作成

EJBアプリケーションにを呼び出すための定義を設定します。

Bean定義ファイル:

    <bean id ="testEJBLocal" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
        <!-- Beanマッピング名を指定 -->
        <property name="jndiName" value="ejb/TimeSender" />
        <!-- 連携するEJBアプリケーションのパスを指定 -->
        <property name="businessInterface" value="com.example.ejb.TestEJBLocal" />
    </bean>

(3) コントローラクラス作成

コントローラクラスを作成します。

コントローラクラス:

package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.ejb.TestEJBLocal;
@Controller
public class GetMessageController {
    @Autowired
    private TestEJBLocal testEJBLocal;
    @RequestMapping(value="/get", method=RequestMethod.POST)
    public ModelAndView getTime() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message",  testEJBLocal.sendTime());
        modelAndView.setViewName("index");
        return modelAndView;
    }
}

(4) JSP画面の作成

JSP画面を作成します。

JSP画面:

<html>
    <head>
        <title>index</title>
    </head>
    <body>
        <form action="get" method="POST">
            <input value="Gst Message" type="submit"/>
        </form>
        <h3>${message}</h3>
    </body>
</html>