以下の4パターンのアプリケーション実装方法の例を示します。
基本的なWebMVCアプリケーションの作成
データベースにアクセスするアプリケーションの作成
他フレームワークと連携するアプリケーションの作成
他アプリケーションと連携するアプリケーションの作成
基本的なWebMVCアプリケーションの開発の手順を説明します。
AP層の作成
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属性を使用する必要があります。
ポイント
MyBatisを使用したデータベースにアクセスするアプリケーションの作成については、“3.4.4.2 MyBatisを使用するSpring Frameworkのアプリケーションの作成”を参照してください。
JPAを使用して、ブラウザ経由でEnterprise Postgresのテーブルに値を追加するアプリケーションを作成します。
データベースにアクセスするアプリケーションの作成として、JPAを使用したO/Rマッピングアプリケーションの開発手順を説明します。
以下の手順は、Spring FrameworkでJPAを使用したO/Rマッピングを実現するために必要な手順です。手順4以降はSpring MVC Webアプリケーションとして必要な手順です。
エンティティクラスの作成
設定ファイルの作成
データベースアクセスクラスの作成
サービスクラスの作成
コントローラクラスの作成
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がJPAに接続するには、下記のファイル設定が必要です。
Bean定義ファイル
deployment descriptor(persistence.xml)
Bean定義ファイルの設定例を以下に示します。
Bean定義ファイル:
<?xml version="1.0" encoding="UTF-8"?>
…
<!--- LocalContainerEntityManagerFactoryBeanを使用-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--- deployment descriptorのファイル名と場所を指定 -->
<property name="persistenceXmlLocation" value="classpath*:META-INF/my-persistence.xml" />
<!--- データソースを指定 -->
<property name="jtaDataSource" ref="dataSource" />
<!--- エンティティマネージャの動作設定を指定 -->
<property name="jpaPropertyMap">
<map>
<entry key="eclipselink.weaving" value="false"/>
…
</map>
</property>
<!--- JpaVendorAdapterを指定する -->
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
</bean>
<!--- JPAプロバイダアダプタを指定する -->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<!--- 接続先データベースに対応する値を指定 -->
<property name="database" value="ORACLE"/>
</bean>
<!--- 接続先のJDBCリソースを指定 -->
<jee:jndi-lookup id="dataSource" jndi-name="Test_DataSource"/>
<!--- トランザクションマネージャの設定 -->
<tx:jta-transaction-manager />
… |
deployment descriptor(persistence.xml)の設定については、“Interstage Application Server GlassFish設計・構築・運用ガイド”の“JPAの提供機能”を参照してください。
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">
<exclude-unlisted-classes>false</exclude-unlisted-classes/>
<properties>
<!--- テーブルの自動生成 -->
<property name="eclipselink.ddl-generation" value="create-tables" />
…
</properties>
</persistence-unit>
</persistence> |
(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) コントローラクラスの作成
コントローラクラスを作成します。
コントローラクラス:
package com.example.controller;
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> |
WebSocketを利用したメッセージ送信アプリケーションを作成します。
他フレームワークと連携するアプリケーションの作成として、WebSocketと連携したアプリケーションの開発手順を説明します。
以下の手順は、Spring FrameworkでWebSocketと連携するために必要な手順です。手順3はWebSocketとして必要な手順です。
ハンドラークラスの作成
設定クラスの作成
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> |
現在時刻を取得するEJB 3.xアプリケーションと連携するアプリケーションを作成します。
他アプリケーションと連携するアプリケーションの作成として、EJBと連携したアプリケーションの開発手順を説明します。
以下の手順は、Spring FrameworkでEJBアプリケーションと連携するために必要な手順です。手順3以降はSpring MVC Webアプリケーションとして必要な手順です。
EJBアプリケーションの作成
Bean定義ファイルの作成
コントローラクラスの作成
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> |