スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Spring MVC Tilesを使って画面をレイアウトする

前回までで、Spring MVCを使ったController周りやSpring Securityによるログイン画面が用意できたので、今回はApacheのTilesを使って、ヘッダー/フッターのついた画面をレイアウトしてみた。

◎動作検証にあたっての各バージョンは以下の通り
  • SpringFramework 3.2.8.RELEASE
  • Java 1.7
  • Tomcat 7.0

1.Mavenのpom.xml




org.apache.tiles
tiles-core
3.0.5


org.apache.tiles
tiles-jsp
3.0.5


バージョンは、2015年2月3日時点で最新の3.0.5にした。最初2.2.2で試していたのだが、tilesが依存しているslf4jのバージョン(1.5.8)が古いせいか、Tomcatサーバー起動時にエラーになったため、最新版に変更した。(ちなみにデフォルトで設定されているslf4jのバージョンは1.7.5)

2.Controller


@Controller
@RequestMapping("book")
public class BookController {

private static Logger logger = LoggerFactory.getLogger(BookController.class);

@Autowired
protected BookService bookService;

@RequestMapping(method = RequestMethod.GET)
public String index(BookForm form) {
logger.info("index start");
return "newBook";
}

@RequestMapping(value = "create", method = RequestMethod.POST)
public String create(@Valid BookForm form, BindingResult result, Model model) {
logger.info("create start");
if (result.hasErrors()) {
return "newBook";
}
//TODO bookServiceより返却されたBookオブジェクトをmodelに追加する
return "result";
}
}

ここでのポイントは初期画面を返すindexメソッドの返却値が「newBook」となっている点で、後で改めて説明する。

3.mcv-config.xml(関連箇所のみ)


<mvc:resources mapping="/css/**" location="/WEB-INF/css/" />
<mvc:resources mapping="/js/**" location="/WEB-INF/js/" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>

<!-- layouts -->
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
<property name="order" value="0"/>
</bean>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<value>/WEB-INF/view/views.xml</value>
</list>
</property>
</bean>

まず「ResourceViewResolver」「UrlBasedViewResolver」クラスに、「order」属性があるが、これは適用するViewResolverの優先順位となり、数字の小さい方が優先される。試しに「UrlBasedViewResolver」を「ResourceViewResolver」より先に記述した場合、「order」属性を設定しなくも優先されたので、記載しない場合は記載順のように思われる。
次に「TilesView」クラスのパッケージについてであるが、「spring-webmvc-3.2.8.RELELSE.jar」を確認すると、「tiles2」と「tiles3」が存在してそれぞれに「TilesView」クラスがあり、バージョンに合ったものを適用する。
「layouts.xml」と「views.xm」についてはこの後説明する。

4.layouts.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Cnfiguration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>
<definition name="default" template="/WEB-INF/layouts/default.jsp">
<put-attribute name="header" value="/WEB-INF/view/header.jsp"/>
<put-attribute name="footer" value="/WEB-INF/view/footer.jsp"/>
</definition>
</tiles-definitions>

「name」属性に論理名称、「template」属性にレイアウトを定義したJSPファイルを設定する。
ここでは、「header」と「footer」のみを定義して、メインとなる「body」を定義していない点がポイントとなる。

5.views.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Cnfiguration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>
<definition extends="default" name="newBook">
<put-attribute name="body" value="/WEB-INF/view/newBook.jsp"/>
</definition>
</tiles-definitions>

「extends」属性で分かるように、defaultを拡張している。ここで、メインとなる「body」を定義することで、中身だけを入れ替えた柔軟な定義ができるようになる。
また、「2.Controller」にて後で説明するとした「newBook」が「definition」タグの「name」属性にも定義している。「index」メソッドの返却値である「newBook」と紐づいて、header/footerをレイアウトした画面を表示する。試しにこの「name」属性を「Book」に変更した場合、header/footerをレイアウトした画面ではなく、ただの「newBook.jsp」が表示される。「mvc-config.xml」にてViewResolverの優先順位が「UrlBasedViewResolver」→「ResourceViewResolver」で機能していることが分かる。(勿論、「name」属性を「Book」に変更して、「index」メソッドの返却値を「Book」に返れば、レイアウトされた画面が表示される。)

6.default.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>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<title>template</title>
</head>
<body>
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>
</body>
</html>

このdefault.jspがテンプレートとなる。

7.header.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>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<link href="<c:url value="/css/bootstrap-theme.min.css" />" rel="stylesheet">
<script src="<c:url value="/js/bootstrap.min.js" />"></script>

<title>header</title>
</head>
<body>
<div class="container-fluid">
<h3>Book</h3>
<a href="#">Login</a>
</div>
</body>
</html>

ログインのリンクは仮実装。

8.footer.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>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<link href="<c:url value="/css/bootstrap-theme.min.css" />" rel="stylesheet">
<script src="<c:url value="/js/bootstrap.min.js" />"></script>

<title>footer</title>
</head>
<body>
<div class="container-fluid">
<div align="center">@Copyright bookmount8</div>
</div>
</body>
</html>


9.newBook.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>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<link href="<c:url value="/css/bootstrap-theme.min.css" />" rel="stylesheet">
<script src="<c:url value="/js/bootstrap.min.js" />"></script>

<title>newBook</title>
</head>
<body>
<div class="container-fluid">
<form:form
action="${pageContext.request.contextPath}/book/create"
method="post" modelAttribute="bookForm" class="well">
<div class="form-group error">
<form:label path="bookId" class="control-label">bookId</form:label>
<form:input path="bookId" class="form-control"/>
<p class="help-block"><font color="red"><form:errors path="bookId" /></font></p>
</div>
<div class="form-group">
<form:label path="bookName" class="control-label">bookName</form:label>
<form:input path="bookName" class="form-control"/>
<p class="help-block"><font color="red"><form:errors path="bookName" /></font></p>
</div>
<div class="form-group">
<form:label path="price" class="control-label">price</form:label>
<form:input path="price" class="form-control"/>
<p class="help-block"><font color="red"><form:errors path="price" /></font></p>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary"/>
</div>
</form:form>
</div>
</body>
</html>

本JSPがメイン(body)となる。

10.動作確認




header/footerが表示されることが確認できた。

まとめ
Spring MVCでTilesを使う場合のポイントをまとめてみた。
①ViewResolverの優先順位を正しく設定すること
②Controllerクラスで返却するView名を意識すること

■過去のSpring関連記事
Spring関連記事 Index

スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

bookmount8

Author:bookmount8
システムエンジニア。サーバーサイドでjavaを扱うことが多い。最近は、ミドルやフロント周りも関心あり。

最新記事
カテゴリ
検索フォーム
最新コメント
月別アーカイブ
これまでの訪問者数
ブロとも申請フォーム

この人とブロともになる

RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。