ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Servlet とは
Servlet (サーブレット) はサーバ上で動作する Java のクラスで、HTTP リクエストを受け取り動的なレスポンスを返します。1997 年に Sun (現 Oracle) が発表した、Java サーバサイドの基礎仕様です。
Tomcat / Jetty / WildFly / GlassFish などのサーブレットコンテナ上で動作します。
最小サンプル
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html; charset=UTF-8");
try (PrintWriter out = resp.getWriter()) {
out.println("<h1>Hello, Servlet!</h1>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String name = req.getParameter("name");
resp.setContentType("text/plain; charset=UTF-8");
resp.getWriter().println("Hello, " + name);
}
}
Servlet のライフサイクル
| フェーズ | メソッド | 呼ばれるタイミング |
|---|---|---|
| 初期化 | init() | ★ サーブレット生成直後 (1 度だけ) |
| サービス | service() | リクエストごと → doGet/doPost にディスパッチ |
| 処理 | doGet / doPost / doPut / doDelete | HTTP メソッドに応じて |
| 破棄 | destroy() | ★ サーブレットコンテナ停止時 / リロード時 |
重要: Servlet インスタンスはシングルトンで、複数スレッドが同時に service() を呼びます。インスタンスフィールドは thread-unsafe なので使わないか同期します。
@WebServlet("/lifecycle")
public class LifecycleServlet extends HttpServlet {
private DataSource ds;
// ⚠️ インスタンスフィールドはスレッド共有
@Override
public void init() {
// 1 度だけ呼ばれる → 初期化に最適
ds = lookupDataSource();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
// ★ ローカル変数のみ使う → スレッドセーフ
try (Connection conn = ds.getConnection()) { ... }
}
@Override
public void destroy() {
// クリーンアップ (コネクションプール close 等)
}
}
HttpServletRequest と HttpServletResponse
@WebServlet("/users")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
// クエリパラメータ
String name = req.getParameter("name");
String[] tags = req.getParameterValues("tag");
// ヘッダ
String userAgent = req.getHeader("User-Agent");
// パス情報
String uri = req.getRequestURI(); // /app/users
String path = req.getServletPath(); // /users
String method = req.getMethod(); // GET
// セッション
HttpSession session = req.getSession();
session.setAttribute("user", name);
Object u = session.getAttribute("user");
// Cookie
Cookie[] cookies = req.getCookies();
// Body (POST)
BufferedReader reader = req.getReader();
// === レスポンス ===
resp.setStatus(200); // HttpServletResponse.SC_OK
resp.setContentType("application/json; charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
// ヘッダ
resp.setHeader("Cache-Control", "no-cache");
resp.addCookie(new Cookie("session_id", "abc"));
// ボディ
resp.getWriter().println("{\"name\": \"" + name + "\"}");
// リダイレクト
resp.sendRedirect("/login");
// エラー
resp.sendError(404, "Not Found");
// フォワード (内部転送)
req.getRequestDispatcher("/WEB-INF/views/index.jsp").forward(req, resp);
}
}
マッピング: web.xml vs アノテーション
web.xml (古典的)
<!-- WEB-INF/web.xml -->
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" version="5.0">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.example.HelloServlet</servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Hello</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
@WebServlet アノテーション (Servlet 3.0+)
@WebServlet(
name = "HelloServlet",
urlPatterns = {"/hello", "/greet"},
initParams = {
@WebInitParam(name = "greeting", value = "Hello")
},
loadOnStartup = 1
)
public class HelloServlet extends HttpServlet { ... }
セッション管理
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String user = req.getParameter("username");
String pass = req.getParameter("password");
if (authenticate(user, pass)) {
HttpSession session = req.getSession(true); // 無ければ作成
session.setAttribute("user", user);
session.setMaxInactiveInterval(30 * 60); // 30 分
resp.sendRedirect("/dashboard");
} else {
resp.sendRedirect("/login?error=1");
}
}
}
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
HttpSession session = req.getSession(false);
if (session != null) {
session.invalidate();
}
resp.sendRedirect("/");
}
}
Filter とListener
// Filter: リクエスト前後の共通処理
@WebFilter("/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
try {
chain.doFilter(req, res); // 次のフィルタ or サーブレットへ
} finally {
System.out.println("elapsed: " + (System.currentTimeMillis() - start));
}
}
}
// Listener: 各種イベント (起動 / セッション生成 / 属性変更)
@WebListener
public class AppListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// アプリ起動時 (DB プール構築など)
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// アプリ停止時
}
}
JSP との関係
JSP (JavaServer Pages) はHTML 中に Java コードを埋め込めるテンプレート技術で、内部的にはServlet にコンパイルされる関係です。
<%-- WEB-INF/views/users.jsp --%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
<html>
<body>
<h1>Users</h1>
<ul>
<c:forEach var="user" items="${users}">
<li>${user.name}</li>
</c:forEach>
</ul>
</body>
</html>
典型的な MVC では Servlet がコントローラ役、JSP が View 役を担います。
javax.servlet → jakarta.servlet 移行 (Jakarta EE 9+)
Oracle から Eclipse Foundation への Java EE 移管 (Jakarta EE) に伴い、Java EE 8 / Servlet 4.0 までは javax.servlet、Jakarta EE 9+ / Servlet 5.0+ は jakarta.servlet に変わりました。
| EE バージョン | Servlet | パッケージ | サーバ例 |
|---|---|---|---|
| Java EE 7 | 3.1 | javax.servlet | Tomcat 8 / WildFly 8 |
| Java EE 8 | 4.0 | javax.servlet | Tomcat 9 / WildFly 18 |
| ★ Jakarta EE 9 | 5.0 | jakarta.servlet | Tomcat 10 / WildFly 27 |
| Jakarta EE 10 | 6.0 | jakarta.servlet | Tomcat 10.1 |
| Jakarta EE 11 | 6.1 | jakarta.servlet | Tomcat 11 |
現代の選択肢: Spring MVC / Spring Boot
Spring Framework は内部に DispatcherServlet (フロントコントローラ) を持ち、Servlet 仕様の上に MVC を構築しています。現代の Java Web 開発は素の Servlet を書くことは稀で、Spring Boot / Quarkus / Micronaut / Vert.x が主流です。
// Spring Boot Controller (Servlet を直接書かない)
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
public User create(@RequestBody UserCreateRequest req) {
return userService.create(req);
}
}
// → Spring が内部で DispatcherServlet → HandlerMapping → このメソッドへルーティング
FAQ
Q: いまから Servlet を学ぶ価値はある?
A: 直接書く機会は減ったが、Spring / Tomcat の動作理解の基礎なので仕様の理解は有益。新規プロジェクトでは Spring Boot を直接学んだ方が実用的。
Q: javax.servlet ライブラリが見つからない
A: Jakarta EE 移行で jakarta.servlet-api に変わりました。spring-boot-starter-web 3.x も Jakarta 系。
Q: Servlet のスレッド数は?
A: コンテナ (Tomcat) のスレッドプール (デフォルト 200) で同時処理されます。server.tomcat.threads.max で調整。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?