SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

WTPではじめるサーバサイドJava入門

サーバサイドJava入門 フォームデータの取り扱いとページ遷移の基本

第3回 フォーム送信とデータのやり取り


ページ間の移動

 ここまでは1つのJSPファイルですべて処理してきましたが、今度は複数のページの間でやりとりをしてみることにします。ある程度複雑なWebになると、処理をフロントエンドとバックヤードに分けて作成するようになります。ユーザーが操作する部分と、送られてきたデータを処理する部分を分けることで、システムの設計もしやすくなりますし、メンテナンスもやりやすくなります。

 このような「複数のページ間でのやり取り」を考えた場合、必要となる機能にはどのようなものがあるでしょうか。1つは、「ページの移動」があるでしょう。そしてもう1つ、「ページ間でのデータの受け渡し」が考えられるでしょう。

 では、まず「ページの移動」について行ってみましょう。サンプルとして、既に作成してある「index.jsp」と、新たに「back.jsp」というファイルを用意することにします。Eclipseのメニューから[ファイル]-[新規]-[JSP]を選択し、作成しておきましょう。ファイルを用意したら、それぞれ次のように記述します。

index.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="windows-31j"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" 
          content="text/html; charset=Shift_JIS">
    <title>JSP SAMPLE</title>
  </head>
  <body>
    ※送信元ページ<br><br>
    <form method="post" action="./back.jsp">
      <input name="submit" type="submit" value="送信">
    </form>
  </body>
</html>
back.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%
  request.setCharacterEncoding("Shift_JIS");

  if (request.getParameter("submit") != null)
    pageContext.forward("./index.jsp");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" 
          content="text/html; charset=Shift_JIS">
    <title>Insert title here</title>
  </head>
  <body>
    ※このページは、直接開いても動きません。
  </body>
</html>
ボタンを押すと、back.jspに移動しすぐにindex.jspに戻る。直接back.jspにアクセスすると、下図のように表示される
ボタンを押すと、back.jspに移動しすぐにindex.jspに戻る。直接back.jspにアクセスすると、下図のように表示される

 「index.jsp」にアクセスし、ボタンを押すと、再び「index.jsp」に戻ります。ブラウザのアドレスバーには「back.jsp」と表示されていますが、表示は「index.jsp」になるのです。それを確認したら、今度はアドレスを記述して直接「back.jsp」にアクセスしてみましょう。すると、「※このページは、直接開いても動きません」と表示されるはずです。

 この「back.jsp」は、直接アクセスするとこのようにメッセージを表示し、「index.jsp」から送信すると「index.jspに戻る」という働きをします。どうアクセスするかによって挙動が違うのです。

 「back.jsp」で行っているのは、submitの値が送られているかどうかをチェックし、nullでなければ「index.jsp」にジャンプする、という処理です。以下の部分です。

if (request.getParameter("submit") != null)
    pageContext.forward("./index.jsp");

 ここで使っているpageContextというのは、requestoutと同じ「暗黙オブジェクト」です。これは、PageContextというクラスのインスタンスで、JSPのさまざまな暗黙オブジェクトや属性などを利用するための機能がまとめられたものです。ここで利用しているforwardは、引数に指定したページにリダイレクトする(ページを移動する)働きをします。ページの移動は、とりあえずこのメソッドだけ覚えておけば十分でしょう。

ページ間のデータの受け渡し

 続いて、ページ間でのデータの受け渡しについて考えてみましょう。ページ間でさまざまな値を受け渡す場合には、「アトリビュート」(属性)と呼ばれるものを利用します。データを送る側でアトリビュートに値を設定し、受け取る側でそのアトリビュートの値を取り出す、といった形で値のやり取りを行うわけです。

 問題は、このアトリビュートの保管先が複数ある、という点でしょう。アトリビュートを保管するメソッドは、以下の暗黙オブジェクトにそれぞれ用意されています。

  • request
  • 現在のリクエスト情報に関する暗黙オブジェクトです。ここに保管すると、そのリクエストが完了するまでの間、値が保持されます。つまり、複数のページに移動しても、リクエスト完了まではその値をどのページからも利用できるわけです。
  • session
  • これは、サーバとクライアントとの連続した接続を示す「セッション」に関する暗黙オブジェクトです。セッションは、一度接続されると、一定時間そのサイトにアクセスしなかったり、ブラウザを終了するまで常に保ち続けられます。ここに値を保管すると、現在のセッションが切断されるまで常に値が保持され続けます。

 requestは、複数ページ間で値をやり取りする際に最もよく使われるオブジェクトです。クライアントからサーバにリクエストが送られると、その後の一連の処理が完了するまで値は保持され続けますから、複数のページ間で値を受け渡すにはもってこいでしょう。リクエストが完了すると値は消えてしまいますが、逆にいえば「使い終わったらきれいに消えて後に残らない」という方が便利かも知れません。

 sessionは、サーバとのセッションがつながっている間、常に値が保持され続けます。これは、複数のページ間で値を受け渡すためよりも、「接続中、常に保ち続ける必要がある値」の保管場所として利用されることが多いでしょう。単純な値の受け渡しではなく、そのWebアプリケーションで常に必要とされる値を置く場所、と考えるべきでしょう。

requestとsesionによる値の受け渡し

 では、実際にrequestとsesionを使った値の受け渡しのサンプルをあげておきましょう。これも「index.jsp」と「back.jsp」の間でやり取りする形にしてあります。

index.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="windows-31j"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" 
          content="text/html; charset=Shift_JIS">
    <title>JSP SAMPLE</title>
  </head>
  <body>
<%
  request.setCharacterEncoding("Shift_JIS");
        
  String msg1 = (String)request.getAttribute("message");
  if (msg1 == null)
    msg1 = "(REQUEST:未送信)";
    out.println("REQUEST:" + msg1);
    out.println("<br>");
        
    String msg2 = (String)session.getAttribute("defaultMsg");
    if (msg2 == null)
        msg2 = "(SESSION:未送信)";
    out.println("SESSION:" + msg2);
%>
        
    <form method="post" action="./back.jsp">
      <input type="text" name="text1">
      <input type="submit">
    </form>
  </body>
</html>
back.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%
  request.setCharacterEncoding("Shift_JIS");

  String msg = request.getParameter("text1");
  String result = "Hello, " + msg + "!";

  request.setAttribute("message",result);
  if (session.getAttribute("defaultMsg") == null)
      session.setAttribute("defaultMsg",result);

  if (msg != null)
      pageContext.forward("./index.jsp");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" 
          content="text/html; charset=Shift_JIS">
    <title>Insert title here</title>
  </head>
  <body>
    ※このページは、直接開いても動きません。
  </body>
</html>
フォームから値を送信すると、セッションとリクエストに値を保管し表示する
フォームから値を送信すると、セッションとリクエストに値を保管し表示する

 最初に適当なテキストを書いて送信すると、それを元に「Hello,○○!」といったテキストを作成し、sessionとrequestにそれぞれ値を保管します。2回目以降は、requestのみ値を設定し、sessionには値を設定しません。

 実際に送信をしてみると、requestの値は毎回送信する度に送られた値が表示されますが、sessionの値は最初に送信したメッセージがその後もずっと保ち続けられていることが分かります。

 値のアトリビュートへの設定と、アトリビュートからの値の取り出しを行うために用意されているのは、次のようなメソッドです。これは、request、sessionそれぞれにまったく同じものが用意されています。

値の設定
[request/session].setAttribute(String name, Object object);
値の取り出し
Object 変数 = [request/session].getAttribute(String name);

 引数のString nameは属性名を、Object objectは設定する値をそれぞれ示します。このように、アトリビュートは、setAttributeで指定した名前を使って値を管理します。

 注意が必要なのは、設定される値はStringではなくObjectである、という点です。従って、Stringの値を設定したような場合には、取り出した値を再びStringにキャストして利用しなければいけません。

 実際にアトリビュートを操作している部分を見てみましょう。「back.jsp」では、getParameterで送信されたテキストを取り出し、それを元にmsgを作成してから、requestとsessionにそれぞれ値を設定しています。sessionについては、値がnullである場合(すなわち、まだ値が設定されていない)にのみ設定をしています。

request.setAttribute("message",result);
if (session.getAttribute("defaultMsg") == null)
    session.setAttribute("defaultMsg",result);

 「index.jsp」側では、requestとsessionからそれぞれアトリビュートの値を取り出し、それを表示しています。request部分を見ると、このように値を取り出しているのが分かりますね。

String msg1 = (String)request.getAttribute("message");

 保存される値はObjectインスタンスになっていますから、取り出す際にはStringにキャストします。sessionのgetAttributeも扱いは同じです。

次のページ
アトリビュートを管理する

この記事は参考になりましたか?

WTPではじめるサーバサイドJava入門連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1369 2008/08/19 19:12

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー