はじめに
Servlet、JSP、JDBCを学んだ皆さんは、次にこれらの技術をどのように組み合わせて効果的なWebアプリケーションを構築するかについて考える時期に来ています。この記事では、MVCアーキテクチャという重要な設計パターンを解説し、学んだ技術をどのように統合すれば良いかを具体的に説明します。
MVCアーキテクチャとは
MVC(Model-View-Controller)は、アプリケーションを3つの主要なコンポーネントに分離する設計パターンです。
- Model(モデル): データとビジネスロジックを担当
- View(ビュー): ユーザーインターフェース(表示)を担当
- Controller(コントローラ): ユーザーからの入力を受け取り、モデルとビューを制御
この分離により、コードの保守性、拡張性、テスト容易性が向上します。

JSP/Servlet環境でのMVC実装
Java Webアプリケーションでは、以下のように各コンポーネントを割り当てます。
| MVCコンポーネント | Java Web技術 |
|---|---|
| Model | JavaBeans, JDBC, DAOクラス |
| View | JSPページ |
| Controller | Servlet |
具体的なデータフロー
- ユーザーがブラウザからリクエストを送信
- Servlet(Controller)がリクエストを受信
- ServletがJavaBeans/DAO(Model)を呼び出してデータ処理
- Modelがデータベース(JDBC)とやり取り
- Servletが処理結果をJSP(View)に転送
- JSPがHTMLを生成してユーザーに返却
実践例:ユーザー管理システム
具体的なコード例でMVCを理解しましょう。ユーザー一覧を表示する機能を作成します。
1. Modelの実装 (User.java)
public class User {
private int id;
private String name;
private String email;
// コンストラクタ、ゲッター、セッター
public User(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// getterとsetterメソッド
public int getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
// その他のsetterメソッド...
}
2. DAOクラス (UserDAO.java) – Modelの一部
public class UserDAO {
private Connection connection;
public UserDAO() {
// データベース接続初期化
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "user", "password");
} catch (Exception e) {
e.printStackTrace();
}
}
public List getAllUsers() {
List users = new ArrayList<>();
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
while (rs.next()) {
users.add(new User(
rs.getInt("id"),
rs.getString("name"),
rs.getString("email")
));
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
}
3. Controllerの実装 (UserServlet.java)
@WebServlet("/users")
public class UserServlet extends HttpServlet {
private UserDAO userDao;
@Override
public void init() {
userDao = new UserDAO();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Modelからデータ取得
List users = userDao.getAllUsers();
// Viewにデータを渡す
request.setAttribute("userList", users);
// Viewに転送
RequestDispatcher dispatcher = request.getRequestDispatcher("/userList.jsp");
dispatcher.forward(request, response);
}
}
4. Viewの実装 (userList.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>ユーザー一覧</title>
</head>
<body>
<h1>ユーザー一覧</h1>
<table border="1">
<tr>
<th>ID</th>
<th>名前</th>
<th>メール</th>
</tr>
<c:forEach var="user" items="${userList}">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
MVCのメリット
この構造には多くの利点があります。
- 関心の分離: 各コンポーネントが単一の責任を持つ
- 保守性の向上: 変更が局所的になる
- デザイン変更 → Viewのみ修正
- ビジネスロジック変更 → Modelのみ修正
- ナビゲーション変更 → Controllerのみ修正
- 再利用性: 同じModelを異なるViewで利用可能
- テスト容易性: 各コンポーネントを個別にテスト可能
よくある間違いとベストプラクティス
避けるべきアンチパターン
- JSPにビジネスロジックを書く
<%-- 悪い例 --%>
<%
Connection conn = DriverManager.getConnection(...);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
while (rs.next()) {
%>
<%= rs.getString("name") %>
<%
}
conn.close();
%>
- Servletに表示ロジックを書く
// 悪い例
PrintWriter out = response.getWriter();
out.println("");
out.println("ユーザー一覧
");
// ...
推奨されるプラクティス
- JSTLとEL式の使用: JSPでのスクリプトレットを避ける
- 適切なスコープの選択:
- リクエストスコープ: 1回のリクエストで使用
- セッションスコープ: ユーザーセッション中に保持
- アプリケーションスコープ: 全ユーザーで共有
- フロントコントローラーパターン: 全リクエストを1つのServletで受けて適切なハンドラに振り分ける
発展的なトピック
フレームワークの利用
MVCをより簡単に実装できるフレームワークがあります。
- Spring MVC: アノテーションベースの設定
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public String listUsers(Model model) {
model.addAttribute("users", userService.getAllUsers());
return "userList";
}
}
- Jakarta EE (旧Java EE)のMVC: JAX-RSベースの実装
RESTful APIとの統合
現代のWebアプリケーションでは、フロントエンド(React/Vueなど)とバックエンドを分離し、JSONでデータをやり取りする構成が一般的です。
@WebServlet("/api/users")
public class UserApiServlet extends HttpServlet {
private UserDAO userDao = new UserDAO();
private Gson gson = new Gson();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
List users = userDao.getAllUsers();
response.getWriter().print(gson.toJson(users));
}
}
まとめ
MVCアーキテクチャは、Servlet、JSP、JDBCで学んだ技術を効果的に組み合わせるための設計パターンです。各コンポーネントの役割を明確に分離することで、以下のようなメリットが得られます。
- コードの見通しが良くなり、開発効率が向上
- 変更に強く、保守性が高いアプリケーションを構築可能
- チーム開発での役割分担が明確になる
- 将来的な拡張やフレームワーク導入が容易
最初は少し複雑に感じるかもしれませんが、実際に小さなプロジェクトで実践してみると、その価値が実感できるでしょう。まずはユーザー管理や商品管理などの簡単なCRUDアプリケーションから始めて、MVCの理解を深めてください。