初級問題 (9問)
- Servletとは何か、簡単に説明してください。
- Servletのライフサイクルについて説明してください。
- web.xmlファイルでのServlet設定方法を説明してください。
- @WebServletアノテーションを使用したServlet設定方法を説明してください。
- doGet()メソッドとdoPost()メソッドの違いは何ですか?
- HttpServletRequestオブジェクトからクエリパラメータを取得する方法を説明してください。
- HttpServletResponseオブジェクトを使ってクライアントにテキストを送信する方法を説明してください。
- ServletでHTMLを動的に生成してレスポンスとして返す簡単な例を示してください。
- Servletコンテナとは何か、その役割を説明してください。
中級問題 (15問)
- フォームから送信されたデータをServletで処理する流れを説明してください。
- doGet()メソッドでフォームを表示し、doPost()メソッドでそのフォームデータを処理するServletの例を作成してください。
- リクエストヘッダーを取得して表示するServletを作成してください。
- レスポンスヘッダーを設定する方法を説明し、キャッシュを無効化する設定例を示してください。
- リクエストディスパッチを使用して別のServletやJSPに転送する方法を説明してください。
- レスポンスのコンテンツタイプを動的に変更する方法を説明してください(例: XML、JSON、プレーンテキスト)。
- マルチパートフォームデータ(ファイルアップロード)を処理するServletの基本構造を説明してください。
- ServletContextオブジェクトの用途を3つ挙げ、それぞれの使用例を説明してください。
- リクエストパラメータが存在するかどうかをチェックする方法を説明してください。
- リクエストパラメータの値を安全に取得する方法(nullチェックなど)を示してください。
- レスポンスのエンコーディングをUTF-8に設定する方法を説明してください。
- リダイレクトを行う方法を説明し、フォワードとの違いを述べてください。
- Servletでエラーページを表示させる方法を2通り説明してください。
- 初期化パラメータ(init-param)を取得して使用する方法を説明してください。
- 同一Servlet内でdoGet()とdoPost()を相互に呼び出す方法を示してください。
上級問題 (6問)
- 非同期Servletの基本的な実装方法を説明してください。
- ServletでJSONデータを生成して返す方法を示してください(ライブラリ使用可)。
- リクエストの内容に基づいて動的にレスポンスのコンテンツタイプを決定するServletを作成してください。
- Servletフィルタを使用せずに、Servlet内でリクエストとレスポンスをラップして処理する方法を示してください。
- 複数のパラメータを処理し、バリデーションを行うServletの例を作成してください。
- RESTfulなAPIを模したServlet設計の例を示し、GET/POST/PUT/DELETEの各メソッドを処理する方法を説明してください。
解答例
初級問題解答
- Servletとは
Servletは、JavaでWebアプリケーションを開発するためのコンポーネントです。クライアントからのリクエストを受け取り、動的なコンテンツを生成してレスポンスとして返します。サーバーサイドで動作し、HTTPプロトコルを扱うためのHttpServletクラスが一般的に使用されます。
- Servletのライフサイクル
1. init(): Servletが初期化されるときに1回だけ呼ばれる
2. service(): クライアントリクエストごとに呼ばれる(通常は直接扱わず、doGet/doPostを使用)
3. destroy(): Servletが破棄されるときに呼ばれる
- web.xmlでの設定
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
- @WebServletアノテーション
@WebServlet("/myservlet")
public class MyServlet extends HttpServlet {
// Servlet実装
}
- doGet()とdoPost()の違い
doGet(): HTTP GETリクエストを処理。URLにパラメータが表示され、キャッシュ可能
doPost(): HTTP POSTリクエストを処理。リクエストボディにパラメータを含み、キャッシュ不可
- クエリパラメータ取得
String value = request.getParameter("paramName");
- テキスト送信
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
out.print("Hello World");
- HTML生成例
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("Hello Servlet
");
out.println("");
- Servletコンテナ
Servletコンテナ(Webコンテナ)はServletを管理・実行する環境です。リクエストの受け付け、Servletのライフサイクル管理、スレッド管理などを行います。TomcatやJettyが代表的な実装です。
中級問題解答
- フォーム処理の流れ
-
クライアントがフォームを表示(通常はGETリクエスト)
ユーザーがフォーム入力して送信(POSTリクエスト)
ServletがdoPost()でフォームデータを処理 4. 処理結果をレスポンスとして返す
- doGet/doPost連携例
@WebServlet("/form")
public class FormServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<form method='post'>");
out.println("Name: <input type='text' name='name'><br>");
out.println("<input type='submit'>");
out.println("</form>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Hello, " + name);
}
}
- リクエストヘッダー表示
@WebServlet("/headers")
public class HeaderServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
out.println(name + ": " + request.getHeader(name) + "<br>");
}
}
}
- レスポンスヘッダー設定
// キャッシュ無効化
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// カスタムヘッダー
response.setHeader("X-Custom-Header", "MyValue");
- リクエストディスパッチ
// Servletに転送
RequestDispatcher dispatcher = request.getRequestDispatcher("/otherServlet");
dispatcher.forward(request, response);
// JSPに転送
RequestDispatcher dispatcher = request.getRequestDispatcher("/page.jsp");
dispatcher.forward(request, response);
- 動的コンテンツタイプ
String type = request.getParameter("type");
if ("xml".equals(type)) {
response.setContentType("application/xml");
// XML生成
} else if ("json".equals(type)) {
response.setContentType("application/json");
// JSON生成
} else {
response.setContentType("text/plain");
// テキスト生成
}
- ファイルアップロード基本構造
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part filePart = request.getPart("file");
InputStream fileContent = filePart.getInputStream();
// ファイル処理...
}
}
- ServletContextの用途
アプリケーション全体で共有するデータの格納: getServletContext().setAttribute("key", object);
初期化パラメータの取得: getServletContext().getInitParameter("paramName");
リソースへのアクセス: getServletContext().getResourceAsStream("/WEB-INF/config.xml");
- リクエストパラメータ存在チェック
if (request.getParameter("paramName") != null) { // パラメータが存在する場合の処理 }
- 安全なパラメータ取得
String value = request.getParameter("paramName");
if (value == null || value.trim().isEmpty()) {
// デフォルト値設定またはエラー処理 value = "default";
}
- UTF-8エンコーディング設定
// リクエストのエンコーディング設定
request.setCharacterEncoding("UTF-8");
// レスポンスのエンコーディング設定
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
- リダイレクトとフォワードの違い
// リダイレクト (クライアント側で新しいリクエスト)
response.sendRedirect("/newLocation");
// フォワード (サーバー側で処理を転送)
request.getRequestDispatcher("/newLocation").forward(request, response);
// 違い:
// - リダイレクトはURLが変わり、新しいリクエストが発生
// - フォワードはURLが変わらず、サーバー内部で処理
- エラーページ表示
// 方法1: sendErrorを使用
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Page not found");
// 方法2: 例外をスロー
throw new ServletException("Error message");
// web.xmlでエラーページを設定可能
- 初期化パラメータ取得
<!-- web.xml -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>value</param-value>
</init-param>
</servlet>
// Servlet内で初期化パラメータを取得
String configValue = getServletConfig().getInitParameter("config");
- doGet/doPost相互呼び出し
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response); // doPostに処理を委譲
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 共通処理
}
上級問題解答
- 非同期Servlet
@WebServlet(urlPatterns = "/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.start(() -> {
try {
// 長時間実行処理
Thread.sleep(3000);
ServletResponse res = asyncContext.getResponse();
res.getWriter().write("Async response");
} catch (Exception e) {
e.printStackTrace();
} finally {
asyncContext.complete();
}
});
}
}
- JSONデータ生成
@WebServlet("/data")
public class JsonServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, String> data = new HashMap<>();
data.put("name", "John");
data.put("age", "30");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
// Jacksonライブラリ使用例
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getWriter(), data);
}
}
- 動的コンテンツタイプ決定
@WebServlet("/dynamic")
public class DynamicContentServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String acceptHeader = request.getHeader("Accept");
if (acceptHeader.contains("application/json")) {
response.setContentType("application/json"); // JSON生成
} else if (acceptHeader.contains("application/xml")) {
response.setContentType("application/xml"); // XML生成
} else {
response.setContentType("text/plain"); // テキスト生成
}
}
}
- リクエスト/レスポンスラップ
public class CustomRequestWrapper extends HttpServletRequestWrapper {
public CustomRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return value != null ? value.toUpperCase() : null;
}
}
@WebServlet("/wrapped")
public class WrappingServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
CustomRequestWrapper wrappedRequest = new CustomRequestWrapper(request);
String param = wrappedRequest.getParameter("test"); // 大文字変換される
response.getWriter().write(param);
}
}
- バリデーション付きServlet
@WebServlet("/validate")
public class ValidationServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
List errors = new ArrayList<>();
if (name == null || name.trim().isEmpty()) {
errors.add("Name is required");
}
int age = 0;
try {
age = Integer.parseInt(ageStr);
if (age < 18 || age > 120) {
errors.add("Age must be between 18 and 120");
}
} catch (NumberFormatException e) {
errors.add("Age must be a number");
}
if (errors.isEmpty()) {
// 正常処理
response.getWriter().write("Valid data: " + name + ", " + age);
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write(String.join(", ", errors));
}
}
}
- RESTfulなServlet設計
@WebServlet("/api/users/*")
public class UserApiServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// GET /api/users - ユーザー一覧取得
// GET /api/users/123 - ID123のユーザー取得
response.setContentType("application/json");
// 実装...
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// POST /api/users - 新規ユーザー作成
response.setContentType("application/json");
// 実装...
}
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// PUT /api/users/123 - ID123のユーザー更新
response.setContentType("application/json");
// 実装...
}
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// DELETE /api/users/123 - ID123のユーザー削除
response.setContentType("application/json");
// 実装...
}
}