8月29日

エンティティを作成する

ひとりひとりの得点に対応するエンティティを作成する。試験成績なので Result とする。
プロジェクトエクスプローラでJavaリソース以下の src/main/java にある、jp.abc パッケージを右クリック。[新規]-[クラス]を選択。
名前に Result を入力して完了。

Result.java

package jp.abc;

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 = "result")
public class Result {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	private long id;

	@Column(nullable = false)
	private String number;

	@Column(nullable = false)
	private int score;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}
}

edit.jspの変更

エンティティを作ったので、edit.jsp もエンティティ経由でデータをやりとりするように変更する。

edit.jsp

<!DOCTYPE html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>

<h1>${title}</h1>

<p>受験番号と得点を入力してください</p>
<form:form modelAttribute="result">
  <form:label path="number">受験番号</form:label>
  <form:input path="number" />
  <form:label path="score">得点</form:label>
  <form:input path="score" />
  <br/>
  <input type="submit" value="登録" />
</form:form>

</body>
</html>

コントローラからJSPにデータを渡す

edit.jspでエンティティを参照するようにしたので、JSPにエンティティを渡すように修正する。

EditController.java

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class EditController {

	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public String home(Model model) {
		model.addAttribute("title", "成績の入力");
		Result r = new Result();
		model.addAttribute("result", r);
		return "edit";
	}

}

動作確認

エンティティを使うように変更したので、動作するか確認する。

入力チェックを追加する

まずは登録ボタンを押したときにエラーにならないようにする。
POSTメソッドのリクエストを受け取るようにする。

EditController.java

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class EditController {

	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public String home(Model model) {
		model.addAttribute("title", "成績の入力");
		Result r = new Result();
		model.addAttribute("result", r);
		return "edit";
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public String add(Model model) {
		model.addAttribute("title", "成績の入力");
		Result r = new Result();
		model.addAttribute("result", r);
		return "edit";
	}
}

入力チェックの追加

入力チェックは、テキストp.230~240を参考にする。

バリデーション用ライブラリの追加

pom.xmlに以下のコードを追加する。

pom.xml

		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.0.1.Final</version>
		</dependency>

エンティティにバリデーションのアノテーションを追加する

Result.java

	@NotEmpty
	@Length(min=3, max=10)
	@Column(nullable = false)
	private String number;

	@Range(min=0, max=100)
	@Column(nullable = false)
	private int score;

コントローラにバリデーションのコードを追加する

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public String add(@Valid @ModelAttribute Result result,
			BindingResult errors, Model model) {
		model.addAttribute("title", "成績の入力");
		Result r = new Result();
		model.addAttribute("result", r);
		return "edit";
	}

JSPにエラー表示用のコードを追加する

エラー表示用のタグ <form:errors /> を追加する。

edit.jsp

<p>受験番号と得点を入力してください</p>
<form:form modelAttribute="result">
  <form:errors path="*" element="div"/><br/>
  <form:label path="number">受験番号</form:label>

HSQLDBの用意

exam プロジェクトにデータベースアクセスのためのライブラリを追加する。

pom.xml の最後の </dependencies>の直前に以下の内容を追加する。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.1</version>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.2.9</version>
</dependency>
<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>jta</artifactId>
    <version>1.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>3.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>3.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring-framework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>1.3.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.7.4</version>
</dependency>
 
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
        <exclusion>
            <groupId>xml-apis</groupId>
            <artifactId>xml-apis</artifactId>
        </exclusion>
    </exclusions>
</dependency>

database.propertiesの作成

以下の spring フォルダを右クリックし、[新規]-[ファイル]を選択
exam
+ src
  + main
  + resources
   + spring

ファイル名に database.properties を入力して完了。
テキストp.270 のリスト5-4 の内容を入力する。

database.driverClassName=org.hsqldb.jdbc.JDBCDriver
database.url=jdbc:hsqldb:hsql://localhost/exam
database.username=sa
database.password=

persistence.xmlの作成

以下の resources フォルダを右クリックし、[新規]-[フォルダー]を選択
exam
+ src
  + main
  + resources

フォルダ名に META-INF を入力して完了。
作成した META-INF フォルダを右クリックし、[新規]-[ファイル]を選択
ファイル名に persistence.xml を入力して完了。
作成した persistence.xml に以下の内容を記述する。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.0"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbc.JDBCDriver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:hsql://localhost/exam" />
    </properties>
  </persistence-unit>
</persistence>

application-config.xmlの変更

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		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
		http://www.springframework.org/schema/jee
		http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa
		http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

	<context:property-placeholder location="classpath:spring/database.properties"/>

	<bean class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close" id="dataSource">
		<property name="driverClassName" value="$database.driverClassName}" />
		<property name="url" value="${database.url}" />
		<property name="username" value="${database.username}" />
		<property name="password" value="${database.password}" />
		<property name="testOnBorrow" value="true" />
		<property name="testOnReturn" value="true" />
		<property name="testWhileIdle" value="true" />
		<property name="timeBetweenEvictionRunsMillis" value="1800000" />
		<property name="numTestsPerEvictionRun" value="3" />
		<property name="minEvictableIdleTimeMillis" value="1800000" />
	</bean>
</beans>

DAOのインタフェースと実装

DAOインタフェースの用意

プロジェクトエクスプローラでJavaリソース以下の src/main/java にある、jp.abc パッケージを右クリック。[新規]-[インタフェース]を選択。
名前に ResultDao を入力して完了。

ResultDao.java

package jp.abc;
 
import java.io.Serializable;
import java.util.List;
 
public interface ResultDao extends Serializable {
    public List<Result> getAll();
    public void add(Result result);
}

DAOの実装を追加する

DAOの実装を追加する。

ResultDaoImpl.java

package jp.abc;
 
import java.util.List;
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;
 
public class ResultDaoImpl implements ResultDao {
    private static EntityManagerFactory factory =
        Persistence.createEntityManagerFactory("persistenceUnit");
 
    public List<Result> getAll() {
        EntityManager manager = factory.createEntityManager();
        Query query = manager.createQuery("from Result");
        List<Result> list = query.getResultList();
        manager.close();
        return list;
    }
 
    public void add(Result result) {
        EntityManager manager = factory.createEntityManager();
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(result);
        transaction.commit();
        manager.close();
    }
}

コントローラからJSPに登録済みのリストをわたす

EditController.java

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public String add(@Valid @ModelAttribute Result result,
			BindingResult errors, Model model) {
		ResultDao dao = new ResultDaoImpl();
		if (errors.hasErrors()) {
			model.addAttribute("title", "成績の入力");
		} else {
			model.addAttribute("title", "成績の入力");
			model.addAttribute("result", result);
			dao.add(result);
		}
		List<Result> list = dao.getAll();
		model.addAttribute("list", list);
		return "edit";
	}

ControllerとJSP

データ登録画面に登録済みのリストを表示する

edit.jsp

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>

<h1>${title}</h1>

<p>受験番号と得点を入力してください</p>
<form:form modelAttribute="result">
  <form:errors path="*" element="div" cssStyle="color:red" /><br/>
  <form:label path="number">受験番号</form:label>
  <form:input path="number" />
  <form:label path="score">得点</form:label>
  <form:input path="score" />
  <br/>
  <input type="submit" value="登録" />
</form:form>
<hr/>
<c:if test="${list != null}">
  <table>
  <tr><th>ID</th><th>受験番号</th><th>得点</th></tr>
  <c:forEach var="r" items="${list}">
    <tr>
      <td>${r.id}</td>
      <td>${r.number}</td>
      <td>${r.score}</td>
    </tr>
  </c:forEach>
  </table>
</c:if>

</body>
</html>

8月28日

今までの復習をかねて、最初からWebアプリをつくってみる。

プロジェクト:exam

ID、受験番号、成績を格納するDBを作成する。
受験番号と成績を入力したら、DBに登録する。
受験番号を入力し、成績を検索する。

Springプロジェクトを作成する

テキストp.40~p.44と6月2日のページを参考にする。
プロジェクトを作成し、http://locahost:8080/exam/ にアクセスすると、Click to enter を表示する。

プロジェクトの更新

exam プロジェクトを右クリックし、[Maven]-[プロジェクトの更新]を選択。

Mavenインストール

exam プロジェクトを右クリックし、[実行]-[Maven install]を選択。

Webアプリの実行

サーバータブでTomcatサーバーを起動。
サーバータブで起動したTomcatサーバーにexamアプリを追加。
http://localhost:8080/exam/ にアクセスする。

検索画面を作る

HomeControllerを作成する。(p.163)
home.jspを作成する。(テキストではshowMessage.jspを表示している)
mvc-config.xmlを修正する。(p.167)

HomeController.java

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {

	@RequestMapping(value = "/home", method = RequestMethod.GET)
	public String home(Model model) {
		model.addAttribute("title", "成績の検索");
		return "home";
	}
}

home.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>${title}</title>
</head>
<body>

<h1>${title}</h1>

</body>
</html>

文字化け対策をする

テキストp.187を参照し、CharacterEncodingFilterを追加する。

入力フォームを作成する

home.jsp に受験番号を入力するフォームを追加する。

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>

<h1>${title}</h1>

<p>受験番号を入力してください</p>
<form action="/exam/home" method="post">
    <input type="text" name="number" />
    <input type="submit" />
</form>

</body>
</html>

exam-1

コントローラで検索リクエストを受け取る

HomeController.java に query() メソッドを追加する。
検索結果は result.jsp で表示する。
リクエストパラメータは @RequestParam で受け取る。
得点は適当な値を設定しておく。

検索結果を表示する

result.jsp で検索結果を表示する。まだデータベースがないので、HomeControllerで適当な値を設定しておく。

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>

<h1>${title}</h1>
<p>
受験番号 ${number} の得点は ${score} です。
</p>

<a href="/exam/home">戻る</a>
</body>
</html>

exam-2

データ登録画面を作成する

edit.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>

<h1>${title}</h1>

<p>受験番号と得点を入力してください</p>
<form action="/exam/edit">
受験番号<input type="text" name="number"/>
得点<input type="number" name="score" />
<br/>
<input type="submit" value="登録"/>
</form>
</body>
</html>

データ登録画面を表示するためのコントローラを作成する

EditController.java では、http://localhost:8080/exam/edit をリクエストされたら、edit.jsp を表示する。

package jp.abc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class EditController {

	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public String home(Model model) {
		model.addAttribute("title", "成績の入力");
		return "edit";
	}
}

データ登録画面を表示する

http://localhost:8080/exam/edit にアクセスすると、データ登録画面を表示する。

exam-4