10月31日

小さな粒度の課題を実施する

今日の2現目はテストなので、作業できるのは70分程度。その短い時間で達成できそうな課題を考えて、その課題を完了させることを目標にすること。

Gitの活用

ソースコードを変更しているときに、変更方法が不適切だと気づいたときは、そのソースコードのファイルを右クリックし、[チーム]-[リセット]を選択するとよい。修正を加える前の状態に戻せる。

Gitの問題?

プッシュして、BacklogのGit上では更新されているのに、プルしても最新のファイルを取得できない問題あり?

10月17日

認証なしでアクセス可能なページの設定


JavaScriptやCSS、画像など認証不要でアクセス可能なURLを指定する方法について。

cssや画像を取得できるようにする

mvc-config.xmlに以下の設定を追加する。

	<mvc:resources mapping="/css/**" location="/css/" />

Spring Security でアクセス制限する場合、誰でもアクセス可能なページは、security-config.xml で設定する。
たとえば、アプリケーションコンテキストルートに対応するページは誰でもアクセス可能にするべきなので、以下のように設定する。

    <sec:http pattern="/" security="none"/>

以下は security-config.xml の全体。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:sec="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.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">

	<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<beans:property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver" />
		<beans:property name="url" value="jdbc:hsqldb:hsql://localhost/exam" />
		<beans:property name="username" value="sa" />
		<beans:property name="password" value="" />
	</beans:bean>

	<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />

	<sec:http pattern="/" security="none"/>
	<sec:http pattern="/index.jsp" security="none"/>
	<sec:http auto-config="true">
		<intercept-url pattern="/**" access="ROLE_USER" />
	</sec:http>

	<authentication-manager>
	    <authentication-provider>
                <user-service>
                    <user name="taro" password="abcd" authorities="ROLE_USER" />
                </user-service>
	    </authentication-provider>
	</authentication-manager>

</beans:beans>

Tomcatサーバーにアプリケーションコンテキストを追加できない場合

Tomcatサーバーを右クリックして「追加および除去」を選択し、ダイアログの中に動作させたいアプリケーションコンテキスト名が表示されていない場合は、以下の設定を確認する。

  1. プロジェクトを右クリックし、プロパティを開く。
  2. ダイアログの左で「プロジェクト・ファセット」を選択する。
  3. 「動的Webモジュール」の「バージョン」を「2.5」に変更する。
  4. 「動的Webモジュール」のチェックボックスをチェックする。
  5. ダイアログで「OK」する。

データベースを使った認証

現状では spring-security.xml に書いたユーザー名とパスワードで認証しているが、これをデータベースを使った認証に変更する。

USERSテーブルの準備

HSQLDBのデータベースマネージャを起動し、以下のSQLでテーブルを作成する。

CREATE TABLE users(
 user_id bigint NOT NULL identity,
 user_name varchar(50) NOT NULL,
 password varchar(50) NOT NULL,
 enabled tinyint NOT NULL,
 role varchar(100) NOT NULL
);

テスト用のユーザーをUSERSテーブルに追加する

以下のSQLでユーザーを追加する。

INSERT INTO users ( user_name , password , enabled, role)
   VALUES ( 'taro', 'abcd' , 1, 'ROLE_USER' );

spring-security.xmlの変更

spring-securoty.xml の以下の箇所でユーザー名とパスワードを指定している。

	<authentication-manager>
	    <authentication-provider>
                <user-service>
                    <user name="taro" password="abcd" authorities="ROLE_USER" />
                </user-service>
	    </authentication-provider>
	</authentication-manager>

この部分をデータベースのUSERSテーブルから取得するようにするために、以下のように修正する。

	<authentication-manager>
	    <authentication-provider>
                <jdbc-user-service data-source-ref="dataSource"
	             users-by-username-query="SELECT user_name, password, enabled FROM users WHERE user_name = ?"
	             authorities-by-username-query="SELECT user_name, role FROM users WHERE user_name = ?"
	        />
	    </authentication-provider>
	</authentication-manager>

10月3日

GITを使ってチーム内でソースコードを共有する

BacklogのプロジェクトでGitリポジトリを作成する

こちらを参考に、BacklogにGitリポジトリを作成する。

プロジェクトをローカルリポジトリにコミットする

プロジェクトをBacklogのリモートリポジトリにプッシュする

こちらを参考に、プロジェクトをリモートリポジトリにプッシュする。

リモートリポジトリをローカルにクローンする

代表者以外の人は、代表者がリモートリポジトリにプッシュしたプロジェクトを、ローカルにクローンする。

  1. Eclipseで[ファイル]-[インポート]を選択。
  2. ダイアログで[Git]-[Gitからプロジェクト]を選択して「次へ」をクリック。
  3. [Clone URI]を選択して「次へ」をクリック
  4. URI に、BacklogのプロジェクトのGitタブにあるURLを貼り付ける。
  5. backlog-1

  6. Backlogプロジェクトのユーザー名とパスワードを入力して「次へ」をクリック
  7. masterがチェックされた状態で「次へ」をクリック
  8. git-1

  9. ローカルの保管場所はそのままで「次へ」をクリック
  10. git-2

  11. プロジェクトのインポートもそのままの設定で「完了」をクリック
  12. git-4

  13. Eclipseにプロジェクトが追加された!
  14. git-5

ユーザー認証

ユーザー認証はSpring Securityを使用する。

こちらのサイトを参考に。

その他、「srping security hibernate ユーザー認証」などのキーワードで検索するとよい。

9月26日

Rooによる超高速開発

コントローラを作る

Roo Shell で以下のコマンドを実行。

> web mvc controller --class ~.HelloController --preferredMapping /helo

昨日の動作するプロジェクトのバックアップを以下の場所に置いたので、エラーが出る人がこちらからコピーしてみてください。

\\kgakusei1\share\澤田\SE3Java2014\20140925

FormDataクラスを作成する。

package jp.abc;

public class FormData {
	private String input;

	public String getInput() {
		return input;
	}

	public void setInput(String input) {
		this.input = input;
	}
}

index.jspxを編集する。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page" 
     xmlns:spring="http://www.springframework.org/tags" 
     xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" 
     xmlns:form="http://www.springframework.org/tags/form"
     version="2.0">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <jsp:output omit-xml-declaration="yes"/>
  <spring:message code="label_helo_index" htmlEscape="false" var="title"/>
  <util:panel id="title" title="${title}">
    <spring:message code="application_name" htmlEscape="false" var="app_name"/>
    <h3>
      <spring:message arguments="${app_name}" code="welcome_titlepane"/>
    </h3>
    <p>${message}</p>
    <form:form modelAttribute="formData" action="form">
        <form:input path="input" />
        <input type="submit" />
    </form:form>
  </util:panel>
</div>

HelloController.java を編集する。

package jp.abc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("/helo/**")
@Controller
public class HelloController {

    @RequestMapping(method = RequestMethod.POST, value = "{id}")
    public void post(@PathVariable Long id, ModelMap modelMap,
    		HttpServletRequest request,
    		HttpServletResponse response) {
    }

    @RequestMapping
    public String index(Model model) {
    	model.addAttribute("formData", new FormData());
        return "helo/index";
    }

    @RequestMapping(method = RequestMethod.POST, value = "/form")
    public String post(@ModelAttribute FormData form, Errors result, Model model) {
    	model.addAttribute("message", "You typed: " + form.getInput());
    	return "helo/index";
    }
}

Rooは問題が多いのであきらめましょう!

examプロジェクトに戻ります

JUnitを使ったテスト

以下のサイトを参考に。
http://d.hatena.ne.jp/nakaearth/20131204

src/test/java に新規で jp.abc パッケージを作成。
[新規]-[JUnitテストケース]でテストクラスを作成。

package jp.abc;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class HomeControllerTest {

	@Autowired
	private WebApplicationContext wac;

	private MockMvc mockMvc;

	@Before
	public void setUp() throws Exception {
		mockMvc = webAppContextSetup(wac).build();
	}

	@Test
	public void testHome() {
		fail("まだ実装されていません");
	}

	@Test
	public void testQuery() {
		fail("まだ実装されていません");
	}

}

9月25日

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

  1. 新規でSpring Rooプロジェクトを作成
  2. Roo Shell が表示されたら、web mvc setup を実行
  3. サーバーに作成したプロジェクトを追加
  4. ブラウザからアクセス
  5. Roo Shell で以下のコマンドを入力
    persistence setup –provider HIBERNATE –database HYPERSONIC_PERSISTENT

コントローラを作る

Roo Shell で以下のコマンドを実行。

> web mvc controller --class ~.HelloController --preferredMapping /helo

9月19日

STSでRooプロジェクトを作る

Maven install を実行する

[実行]-[maven]-[install]でエラーが出る人は、サーバーに置いた pom.xml をコピーして試してみること。

MyRooApp-0

Maven install に成功したときは、コンソールに以下のように表示される。

MyRooApp-3

wev mbc setup を実行する

Roo Shell でコマンド「web mvc setup」を実行する。

TomcatにMyRooAppを追加する

「サーバー」タブでTomcatにMyRooAppを追加し、Tomcatを開始する。
http://localhost:8080/MyRooAppにアクセスすると、Rooの画面が表示される。

MyRooApp-4

データベースのセットアップ

Roo Shell で以下のコマンドを実行する。

> persistence setup --provider HIBERNATE --database HYPERSONIC_PERSISTENT 

MyRooApp-5

コマンドプロンプトでmavenを使えるようにする

maven をコピーする。
サーバー上のファイル apache-maven-3.2.3-bin.zip をローカルにコピーする。

mvn-1

se3 の下に java フォルダを作成し、そこにZIPファイルを解凍する。

スタートメニューのコンピュータを右クリックし、プロパティを選択する。
システムの詳細設定をクリックする。
環境変数をクリックする。

JAVA_HOMEとPATHの2つの環境変数を追加する。

mvn-2

スタートメニューからコマンドプロンプトを開き、cd コマンドでMyRooAppのフォルダに移動し、mvn install コマンドを実行する。

mvn-3

BUILD FAILED でエラーになった場合は、-Xオプションを指定してmavenを実行する。

> mvn -X install

エラーになった原因が表示されるので、その原因を解決する。

9月18日

Spring Rooを使ってみる

Spring Rooのインストール

以下のサイトを参考に、Spring Roo をインストールする。
Spring Roo チュートリアルをやってみた 1

Springダッシュボードの右下にある 「IDE EXTENSIONS」 をクリック。
「Spring Roo」をチェックしてインストールを実行。

Roo のインストールが終わったら Eclipse を再起動する。

プロジェクトを作成する

メニューから[ファイル]-[新規]-[プロジェクト]を選択する。
Spring内にある「Spring Roo Project」を選択し、「次へ」をクリック。
以下の内容を入力して「次へ」をクリック。
 プロジェクト名: MyRooApp
 Top level package name: jp.abc
「完了」をクリックしてプロジェクトを作成する。

「Roo shell」が表示されるまでしばらく待機する。

プロジェクトが生成さけれど、pom.xml で「プラグイン実行がライフサイクル構成でカバーされていません」のエラーが出ている。
これを解消するには、Eclipseマーケットプレイスで「m2e-apt」をインストールする。

それでもエラーが消えないので、pom.xml のエラー上にマウスカーソルを移動してクイックフィックスを表示し、「新規m2eコネクタの…」をクリックする。

AspectJ のコネクタが表示されるので、それをインストールする。

Eclipseを再起動し、ビルドが実行されると、エラーが消える。

再起動後にビルドが終わらない等が発生した場合は、Eclipseを再起動してみる。

エラーが消えてビルドが完了していれば、MyRooAppプロジェクトを右クリックし、[実行]-[Maven install]を選択する。
コンソールに「BUILD SUCCESS」が表示されることを確認する。

Roo Shell で「web mvc setup」コマンドを入力しENTERで実行する。

9月12日

エンティティの連携

SpringMVCでは関連付けされたエンティティの永続化も簡単にできる。

Profileクラスの追加

Resultは試験番号と得点だけを保持するので、受験者の名前を保持する Profile クラスを追加して関連付け、受験者の名前も永続化できるようにする。

Profile.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.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name = "profile")
public class Profile {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	@OneToOne
	private Result result;

	public long getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Result getResult() {
		return result;
	}

	public void setResult(Result result) {
		this.result = result;
	}
}

ResultクラスにもProfileへの参照を追加する。

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.OneToOne;
import javax.persistence.Table;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

@Entity
@Table(name = "result")
public class Result {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	private long id;

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

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

	@OneToOne
	private Profile profile;

	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;
	}

	public Profile getProfile() {
		return profile;
	}

	public void setProfile(Profile profile) {
		this.profile = profile;
	}
}

インタフェースProfileDaoを作成する。

ProfileDao.java

package jp.abc;

import java.io.Serializable;
import java.util.List;

public interface ProfileDao<T> extends Serializable {
	public List<T> getAll();
	public T findById(long id);
	public void add(T data);
	public void update(T data);
	public void delete(T data);
	public void delete(long id);
}

ProfileDaoの実装クラスProfileDaoImpleを作成する。

ProfileDaoImple.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 ProfileDaoImpl implements ProfileDao<Profile> {
	private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnit");

	public List<Profile> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<Profile> list = null;
		Query query = manager.createQuery("from Profile");
		list = query.getResultList();
		manager.close();
		return list;
	}

	public Profile findById(long id) {
		EntityManager manager = factory.createEntityManager();
		return (Profile)manager.createQuery("from Profile where id = " + id).getSingleResult();
	}

	public void add(Profile data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.persist(data);
		tx.commit();
		manager.close();
	}

	public void update(Profile data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		manager.merge(data);
		tx.commit();
		manager.close();
	}

	public void delete(Profile data) {
		EntityManager manager = factory.createEntityManager();
		EntityTransaction tx = manager.getTransaction();
		tx.begin();
		Profile p = manager.merge(data);
		manager.remove(p);
		tx.commit();
		manager.close();
	}

	public void delete(long id) {
		delete(findById(id));
	}

}

ビューテンプレートを作成する。

profile.jsp

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

<h1>${title}</h1>
<p>${message}</p>

<table>
  <form:form modelAttribute="profile">
    <tr>
      <td></td>
      <td><form:errors path="*" /></td>
    </tr>
    <tr>
      <td><form:label path="name">名前</form:label></td>
      <td><form:input path="name" size="20" /></td>
    </tr>
    <tr>
      <td><form:label path="result">受験番号</form:label></td>
      <td><form:input path="result" size="20" /></td>
    </tr>
    <tr>
      <td></td>
      <td><input type="submit"></td>
    </tr>
  </form:form>
</table>

<hr>
<c:if test="${list != null}">
<table>
  <tr><th>ID</th><th>受験番号</th><th>名前</th></tr>
  <c:forEach var="obj" items="${list}">
    <tr>
      <td>${obj.id}</td>
      <td>${obj.result.number}</td>
      <td>${obj.name}</td>
    </tr>
  </c:forEach>
</table>
</c:if>

</body>
</html>

コントローラを作成する。

ProfileController.java

package jp.abc;

import java.util.List;

import javax.validation.Valid;

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

@Controller
public class ProfileController {

	@RequestMapping(value = "/profile", method = RequestMethod.GET)
	public String profile(Model model) {
		model.addAttribute("title", "Sample");
		model.addAttribute("message", "Profileのサンプルです");
		Profile p = new Profile();
		model.addAttribute("profile", p);
		ProfileDao<Profile> dao = new ProfileDaoImpl();
		List<Profile> list = dao.getAll();
		model.addAttribute("list", list);
		return "profile";
	}

	@RequestMapping(value = "/profile", method = RequestMethod.POST)
	public String profileForm(@Valid @ModelAttribute Profile p, Errors result, Model model) {
		if (result.hasErrors()) {
			model.addAttribute("title", "Sample ERROR");
			model.addAttribute("message", "値をチェックしてください");
		} else {
			model.addAttribute("title", "Sample");
			model.addAttribute("message", "Profileのサンプルです");
			ProfileDaoImpl dao = new ProfileDaoImpl();
			dao.add(p);
			List<Profile> list = dao.getAll();
			model.addAttribute("list", list);
		}
		return "/profile";
	}
}

プロパティエディタを作成する。

ResultPropertyEditor.java

package jp.abc;

import java.beans.PropertyEditorSupport;

public class ResultPropertyEditor extends PropertyEditorSupport {
	public String getAsText() {
		Result r = (Result)getValue();
		if (r == null) {
			return "";
		} else {
			return r.getNumber();
		}
	}

	public void setAsText(String value) {
		ResultDao dao = new ResultDaoImpl();
		Result r = dao.find(value);
		setValue(r);
	}
}

コントローラにInitBinderを追加する。

ProfileController.java

	@InitBinder
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(Result.class, new ResultPropertyEditor());
	}

exam-6

受験番号と名前に続いて得点も表示するようにビューテンプレートを変更する。

profile.jsp

<table>
  <tr><th>ID</th><th>受験番号</th><th>名前</th><th>得点</th></tr>
  <c:forEach var="obj" items="${list}">
    <tr>
      <td>${obj.id}</td>
      <td>${obj.result.number}</td>
      <td>${obj.name}</td>
      <td>${obj.result.score}</td>
    </tr>
  </c:forEach>
</table>

exam-7

9月11日

サービスとリポジトリ

DIでサービスを使えるようにするとさらに簡単になる。

application-config.xml

	<bean
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		id="entityManagerFactory">
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="showSql" value="true" />
			</bean>
		</property>
		<property name="persistenceUnitName" value="persistenceUnit" />
		<property name="dataSource" ref="dataSource" />
		<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
	</bean>
	<bean
		class="org.springframework.orm.jpa.JpaTransactionManager"
		id="transactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	<tx:annotation-driven/>
	<bean
		class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
	<jpa:repositories base-package="jp.abc.exam.repositories" />

Serviceを作る

テキストではMyDataServiceになっているが、これはMyDataを扱っているアプリだから。
成績検索アプリではResultを扱うのでResultServiceを作成する。

ResultService.java

package jp.abc;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ResultService {
	@PersistenceContext
	private EntityManager manager;

	@Transactional
	public List<Result> getAll() {
		return (List<Result>)manager.createQuery("from Result").getResultList();
	}
}

コントローラでサービスを使う。
テキストでは既存のコントローラを書き換えているが、ここでは新しいコントローラを作成する。

ListController.java

package jp.abc;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;

@Controller
public class ListController {
	@Autowired
	private ResultService service;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String list(Model model) {
		model.addAttribute("title", "Sample");
		model.addAttribute("message", "Selectのサンプルです");
		List<Result> list = service.getAll();
		model.addAttribute("list", list);
		return "list";
	}
}

JSPを用意する。

list.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ 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>${message}</p>

<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>

</body>
</html>