
JSP MVCモデルを使った模擬アプリ課題
以下に、Servlet、JSP、JDBC、フロントコントローラーパターンを活用した3つの課題を提案します。 課題1: 簡易タスク管理アプリケーション 要件 模範 […]
カスタムタグは、JSPの機能を拡張するために開発者が独自に作成できるタグです。JSP標準タグライブラリ(JSTL)で提供されるタグと同じように使用できますが、自分でロジックや表示をカプセル化できる点が特徴です。
カスタムタグの主な特徴:
カスタムタグは以下の主要コンポーネントで構成されます:
スクリプトレットでの日付フォーマット表示:
<%
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy年MM月dd日");
String formattedDate = sdf.format(new java.util.Date());
%>
<%= formattedDate %>
カスタムタグを使用した場合:
<my:formatDate pattern="yyyy年MM月dd日" />
javax.servlet.jsp.tagext.SimpleTagSupport
を継承したクラスを作成します。
package com.example.tags;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FormatDateTag extends SimpleTagSupport {
private String pattern;
public void setPattern(String pattern) {
this.pattern = pattern;
}
@Override
public void doTag() throws JspException, IOException {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String formattedDate = sdf.format(new Date());
getJspContext().getOut().write(formattedDate);
}
}
WEB-INF/tags/my.tld
ファイルを作成:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>my</short-name>
<uri>/WEB-INF/tags/my.tld</uri>
<tag>
<name>formatDate</name>
<tag-class>com.example.tags.FormatDateTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>pattern</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
<%@ taglib prefix="my" uri="/WEB-INF/tags/my.tld" %>
<html>
<head>
<title>カスタムタグデモ</title>
</head>
<body>
<h1>現在の日付: <my:formatDate pattern="yyyy年MM月dd日" /></h1>
<p>別の形式: <my:formatDate pattern="MM/dd/yyyy HH:mm:ss" /></p>
</body>
</html>
<my:currentTime />
<my:repeatText text="Hello" count="5" //>
<my:toUpperCase>
This text will be converted to uppercase
</my:toUpperCase>
<my:table>
<my:row>
<my:cell>Data 1</my:cell>
<my:cell>Data 2</my:cell>
</my:row>
</my:table>
public class ToUpperCaseTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
StringWriter sw = new StringWriter();
getJspBody().invoke(sw); // ボディ内容をStringWriterに出力
String upperCased = sw.toString().toUpperCase();
getJspContext().getOut().write(upperCased);
}
}
<tag>
<name>toUpperCase</name>
<tag-class>com.example.tags.ToUpperCaseTag</tag-class>
<body-content>scriptless</body-content>
</tag>
<my:toUpperCase>
このテキストは大文字に変換されます
</my:toUpperCase>
<attribute>
<name>pattern</name>
<required>true</required>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
</attribute>
<attribute>
<name>count</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
JSPでの動的属性値の使用:
<my:repeatText count="${requestScope.repeatCount}" text="Sample" />
public class PaginationTag extends SimpleTagSupport {
private int currentPage;
private int totalPages;
private String url;
// セッターメソッド省略
@Override
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.print("");
if (currentPage > 1) {
out.print(String.format("前へ", url, currentPage-1));
}
for (int i = 1; i <= totalPages; i++) {
if (i == currentPage) {
out.print(String.format("%d", i));
} else {
out.print(String.format("%d", url, i, i));
}
}
if (currentPage < totalPages) {
out.print(String.format("次へ", url, currentPage+1));
}
out.print("");
}
}
<my:pagination currentPage="${param.page}"
totalPages="${totalPages}"
url="products.jsp" />
<tag>
<description>Formats a date according to specified pattern</description>
<!-- その他の設定 -->
</tag>
public void doTag() throws JspException, IOException {
System.out.println("Debug: pattern = " + pattern);
// タグ処理
}
if (pattern == null) {
throw new JspTagException("pattern attribute must be specified");
}
<c:out value="Debug: ${requestScope.someValue}" />
@Test
public void testFormatDateTag() throws Exception {
FormatDateTag tag = new FormatDateTag();
tag.setPattern("yyyy-MM-dd");
StringWriter sw = new StringWriter();
JspWriter jspWriter = new MockJspWriter(sw);
MockJspContext jspContext = new MockJspContext();
jspContext.setJspWriter(jspWriter);
tag.setJspContext(jspContext);
tag.doTag();
assertEquals("2023-11-15", sw.toString());
}
JSP-likeな構文でカスタムタグを定義:
WEB-INF/tags/formatDate.tag
:
<%@ attribute name="pattern" required="true" rtexprvalue="true" %>
<%@ tag body-content="empty" %>
<%
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
String formattedDate = sdf.format(new java.util.Date());
%>
<%= formattedDate %>
public class DynamicAttributeTag extends SimpleTagSupport
implements DynamicAttributes {
private Map attrs = new HashMap<>();
@Override
public void setDynamicAttribute(String uri, String name, Object value) {
attrs.put(name, value);
}
@Override
public void doTag() throws JspException, IOException {
// 動的属性を使用した処理
}
}
子タグから親タグへのアクセス:
ParentTag parent = (ParentTag)findAncestorWithClass(this, ParentTag.class);
if (parent != null) {
parent.addItem(item);
}
<my:hasPermission role="admin">
<!-- 管理者のみ表示されるコンテンツ -->
</my:hasPermission>
<my:formatCurrency amount="${product.price}" locale="ja_JP" />
<my:cache key="product_${product.id}" duration="3600">
<!-- キャッシュされるコンテンツ -->
</my:cache>
<my:i18n key="welcome.message" />
カスタムタグはJSPの強力な拡張機能であり、以下のような利点があります:
カスタムタグを適切に設計・実装するためには、以下のポイントを押さえることが重要です:
カスタムタグをマスターすることで、JSPベースのWebアプリケーション開発の効率と品質を大幅に向上させることができます。最初はシンプルなタグから始め、徐々に複雑な機能を持つタグを作成していくことをおすすめします。