アプリケーション開発
Servlet、JSP/JSTL、非同期処理、WebSocketを利用する際の配置とAPIを説明します。
javax.*を使う
対象はJava EE 8世代です。Maven座標に jakarta が含まれていても、APIパッケージは javax.servlet、javax.websocket などです。Servlet 5以降の jakarta.servlet.* アプリはそのままでは対象になりません。仕様APIはprovidedとして扱い、WARに重複同梱しない構成にします。
| API | 配布API座標・版 |
|---|---|
| Servlet 4.0 | jakarta.servlet:jakarta.servlet-api:4.0.3 |
| EL 3.0 | jakarta.el:jakarta.el-api:3.0.3 |
| JSP 2.3 | jakarta.servlet.jsp:jakarta.servlet.jsp-api:2.3.6 |
| JSTL 1.2 | jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:1.2.7 |
| JTA中核 | jakarta.transaction:jakarta.transaction-api:1.3.3 |
| Concurrency Utilities | jakarta.enterprise.concurrent:jakarta.enterprise.concurrent-api:1.1.2 |
| WebSocket 1.1 | jakarta.websocket:jakarta.websocket-api:1.1.2 |
最小のServlet
Javaクラスを WEB-INF/classes またはWAR内のjarへ配置します。アノテーションの走査は web.xml の metadata-complete と記述子の規則に従います。
package example;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().println("Hello, Kohaku");
}
}sample.war として配備した場合は /sample/hello で確認します。依存APIの指定例:
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>4.0.3</version>
<scope>provided</scope>
</dependency>JSP・EL・JSTL
JSPは要求時に翻訳・Javaコンパイルされます。JDK 21で実行し、webappの作業領域を実行ユーザーが書けるようにします。JSTL実装とAPIは配布物の shared/ からwebappクラスローダの末尾へ追加されます。WARが同じタグライブラリを持つ場合はWAR側が優先されます。
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html lang="ja">
<head><meta charset="UTF-8"><title>Hello</title></head>
<body><h1><c:out value="${param.name}" default="Kohaku" /></h1></body>
</html>/sample/index.jsp?name=Hello で出力を確認します。出力に外部入力を使う場合は、この例のように c:out 等でエスケープします。
JSTLの資源制限
以下は 各WARのWEB-INF/web.xmlのcontext-param です。server.yamlからは読みません。負数や非整数の数値はタグ使用時に JspTagException になります。
| param-name | 既定 | 意味 |
|---|---|---|
| kohaku.jstl.import.connectTimeoutMillis | 10000 | 接続期限。0はこの層で設定しない |
| kohaku.jstl.import.readTimeoutMillis | 30000 | read期限。0はこの層で設定しない |
| kohaku.jstl.import.maxBytes | 10485760 | 10 MiB。0は本文無制限 |
| kohaku.jstl.import.allowedSchemes | http,https | カンマ区切り。*は全スキーム |
| kohaku.jstl.import.allowedHosts | 未設定 | ホスト/IP/CIDRの許可リスト |
| kohaku.jstl.import.deniedHosts | 未設定 | 拒否リスト。許可より優先 |
| kohaku.jstl.import.maxRedirects | 20 | 手動追従の上限。明示設定かホストポリシー設定時に手動追従 |
| kohaku.jstl.sql.queryTimeoutSeconds | 0 | SQL実行期限。0はsetQueryTimeoutを呼ばない |
| kohaku.jstl.sql.maxRows | 0 | query結果の行数上限。0は無効。指定時はページの上限より小さい値で縛る |
<context-param>
<param-name>kohaku.jstl.import.allowedHosts</param-name>
<param-value>content.example.invalid:443</param-value>
</context-param>
<context-param>
<param-name>kohaku.jstl.sql.queryTimeoutSeconds</param-name>
<param-value>30</param-value>
</context-param>
<context-param>
<param-name>kohaku.jstl.sql.maxRows</param-name>
<param-value>1000</param-value>
</context-param>Servlet非同期と管理タスク
非同期Servlet/Filterは asyncSupported=true を宣言します。AsyncContext.start() の枠は async.maxTasks と async.maxTasksPerWebapp です。Concurrency UtilitiesのManagedExecutorは別の枠を持ち、実装定数で同時実行1,024・待機4,096です。async.* を増やしてもManagedExecutorの枠は変わりません。
管理サービスは JNDIの既定名 で取得します。アプリからコンテナ管理Executorの shutdown() を呼ぶ運用にしないでください。トランザクションはタスクへそのまま持ち越されず、タスク内の開始・完了はタスク側で処理します。
WebSocket
package example;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/echo")
public class EchoEndpoint {
@OnMessage
public String echo(String message) {
return message;
}
}sample.war なら接続先は ws://127.0.0.1:8080/sample/echo、TLSでは wss:// です。クライアントAPIは ContainerProvider.getWebSocketContainer() から取得します。最新の実装ではwebapp所有のクライアント接続も撤去・停止で回収し、サーバの websocket.* 設定がContainerProvider経由にも反映されます。
接続上限はHTTP枠とWebSocket枠の両方を考慮します。超過はハンドシェイク503、サイズ超過はclose 1009、レート違反等は1008です。WebSocket Sessionのidle期限は http.upgradeIdleTimeoutMillis と独立です。