
JSP MVCモデルを使った模擬アプリ課題
以下に、Servlet、JSP、JDBC、フロントコントローラーパターンを活用した3つの課題を提案します。 課題1: 簡易タスク管理アプリケーション 要件 模範 […]
前回の記事でMVCアーキテクチャについて学んだ皆さんは、Java Web開発における「モデル1」と「モデル2」という用語を耳にしたことがあるでしょう。この記事では、この2つのアプローチを詳細に比較し、それぞれの特徴、利点、欠点、そして適切な使用場面について解説します。
モデル1は、JSPを中心としたシンプルなアーキテクチャです。主な特徴は:
モデル2は、MVCパターンに基づいたより構造化されたアーキテクチャです。主な特徴は:
<%@ page import="java.sql.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// ビジネスロジックがJSP内に直接記述(アンチパターン)
if ("POST".equals(request.getMethod())) {
String name = request.getParameter("name");
String email = request.getParameter("email");
String password = request.getParameter("password");
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "user", "password");
String sql = "INSERT INTO users (name, email, password) VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, email);
pstmt.setString(3, password);
int result = pstmt.executeUpdate();
if (result > 0) {
out.println("登録成功しました
");
} else {
out.println("登録に失敗しました
");
}
} catch (Exception e) {
e.printStackTrace();
out.println("エラーが発生しました: " + e.getMessage() + "
");
} finally {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
}
}
%>
<!DOCTYPE html>
<html>
<head>
<title>ユーザー登録</title>
</head>
<body>
<h1>ユーザー登録</h1>
<form method="post">
名前: <input type="text" name="name"><br>
メール: <input type="email" name="email"><br>
パスワード: <input type="password" name="password"><br>
<button type="submit">登録</button>
</form>
</body>
</html>
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
private UserService userService = new UserService();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/register.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
String email = request.getParameter("email");
String password = request.getParameter("password");
try {
boolean success = userService.registerUser(name, email, password);
if (success) {
request.setAttribute("message", "登録成功しました");
} else {
request.setAttribute("error", "登録に失敗しました");
}
} catch (Exception e) {
request.setAttribute("error", "エラーが発生しました: " + e.getMessage());
}
request.getRequestDispatcher("/register.jsp").forward(request, response);
}
}
public class UserService {
private UserDAO userDao = new UserDAO();
public boolean registerUser(String name, String email, String password)
throws SQLException {
// バリデーションなどのビジネスロジック
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("名前は必須です");
}
// パスワードの複雑性チェックなど...
return userDao.insertUser(new User(name, email, password));
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>ユーザー登録</title>
</head>
<body>
<h1>ユーザー登録</h1>
<%-- メッセージ表示 --%>
<c:if test="${not empty message}">
<p style="color:green">${message}</p>
</c:if>
<c:if test="${not empty error}">
<p style="color:red">${error}</p>
</c:if>
<form method="post">
名前: <input type="text" name="name"><br>
メール: <input type="email" name="email"><br>
パスワード: <input type="password" name="password"><br>
<button type="submit">登録</button>
</form>
</body>
</html>
項目 | モデル1 | モデル2 |
---|---|---|
構造 | JSP中心 | MVCパターン |
役割分担 | 不明確(JSPがすべて処理) | 明確(Model-View-Controller) |
開発速度 | 速い(初期段階) | やや遅い(設計が必要) |
保守性 | 低い(コードが散らばる) | 高い(責務が分離) |
拡張性 | 低い(大規模化に不向き) | 高い(大規模対応可) |
テスト容易性 | 困難(ロジックがJSP内) | 容易(各層を個別にテスト可能) |
適応規模 | 小規模・プロトタイプ | 中~大規模・本番システム |
チーム開発 | 不向き(競合が発生) | 適している(役割分担可能) |
技術的負債 | 蓄積しやすい | 蓄積しにくい |
既存のモデル1アプリケーションをモデル2にリファクタリングする場合の手順:
Before (モデル1):
<%-- JSP内に直接データベース操作 --%>
<%
String id = request.getParameter("id");
Connection conn = ...;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM products WHERE id=" + id);
// ...
%>
After (モデル2):
// Controller
@WebServlet("/product")
public class ProductServlet extends HttpServlet {
private ProductService productService = new ProductService();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
Product product = productService.getProductById(id);
request.setAttribute("product", product);
request.getRequestDispatcher("/productDetail.jsp").forward(request, response);
}
}
<%-- JSPは表示のみ --%>
<p>商品名: ${product.name}</p>
<p>価格: ${product.price}円</p>
モデル2が主流となった現在でも、モデル1には以下のような用途があります:
しかし、以下の点に注意が必要です:
プロジェクトの要件に基づいて適切なアーキテクチャを選択してください。
モデル1が適している場合:
モデル2が必須な場合:
Java Web開発のベストプラクティスとしては、モデル2(MVC)アーキテクチャを採用することが強く推奨されます。特に、Spring Frameworkなどの現代的なフレームワークはすべてMVCパターンに基づいて設計されているため、モデル2を理解することはプロフェッショナルなJava開発者になるための重要なステップです。
モデル2の理解を深めたら、以下のトピックに進むことをお勧めします:
MVCアーキテクチャの完全な理解は、現代のJava Web開発における成功への鍵です。小さなプロジェクトから始めて、徐々に複雑なアプリケーションへとスキルを拡張していきましょう。