Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

JavaScriptの中でJava(Session)

いつも参考にさせていただいています。

プルダウンメニューの数値変更時に
変更された数値分のInputBoxを作りたい。
という目的の作業をしており、以下のような
プログラミングをしてみました。

しかし、なぜかSessionにデータが登録されません。
JavaScript内ではSystemログが出せないようだったので
アラートで、現在のsession設定値を表示してみたところ
switch文内部のsession設定直後は、選択された値に
設定されているのに、switch文を抜けたあとに表示
するアラートでは 設定値が1になってしまうのです。

分かる方教えてもらえないでしょうか?
すみませんがおねがいします。


<%@page contentType="text/html; charset=SJIS" %>
<html>
<head>

<script language="JavaScript">
<!--
function reload(n){

    if (n != null){
        alert(n);

        switch(n){
            case "1":
                <% application.setAttribute("boxnum",new Integer(1)); %>
                alert("ここでは" + <%=(Integer)(application.getAttribute("boxnum"))%>);
                break;
            case "2":
                <% application.setAttribute("boxnum",new Integer(2)); %>
                alert("ここでは" + <%=(Integer)(application.getAttribute("boxnum"))%>);
                break;
            case "3":
                <% application.setAttribute("boxnum",new Integer(3)); %>
                alert("ここでは" + <%=(Integer)(application.getAttribute("boxnum"))%>);
                break;
            case "4":
                <% application.setAttribute("boxnum",new Integer(4)); %>
                alert("ここでは" + <%=(Integer)(application.getAttribute("boxnum"))%>);
                break;
            default:
                <% application.setAttribute("boxnum",new Integer(1)); %>
                alert("default");                
        }

        alert("switch分抜けたら" + <%=(Integer)(application.getAttribute("boxnum"))%>);
        
        location.href = "javascript:location.reload(true);"
    }
}

// -->
</script>
</head>

<body>
<% 
    // セッション設定値取得
    int iboxnum = 1;    // セッション未登録時はboxを1個記述
    Integer num =(Integer)(application.getAttribute("boxnum"));

    if(num != null){
        iboxnum  = num.intValue();
    }
%>

<br><br>増えるBOX<br>
<form name="form" action="/project/Servlet" method="post">
<table border="0" cellpadding="6" width="100%">

    <tr>
        <td bgcolor="#6666FF">
            <font color="#FFFFFF" SIZE=1>ID</font><BR>
            <font color="#FFFFFF" SIZE=1>個数</font>
            <font action="location.href" method="post">
                <select name="num" onChange="reload(this.options[this.selectedIndex].value)"> 
                    <option value="1">1</option>     <!-- 以下件数 -->
                    <option value="2">2</option> 
                    <option value="3">3</option> 
                    <option value="4">4</option> 
                </select> 
        </td>
        <td bgcolor="#CCCCFF">        
<%        
            int i = 0;
            while(i < iboxnum){
%>            
                <input type="TEXT" name="MEISAI_ID" size="15" maxlength="7" balue=""><br>
<%        
                i++;
            }
%>            
                <input type="hidden" name="MEISAI_NUM" value=<%= iboxnum %>>
        </td>
    </tr>
    <tr>
        <td bgcolor="#FFFFFF" colspan=2><div align="RIGHT">
            <INPUT TYPE="reset" VALUE = "リセット"> 
            <INPUT TYPE="submit" VALUE = " 登 録 "> 
        </DIV></td>
    </tr>
</table>
</form></body></html>

12

回答

25833

閲覧

12件の回答

評価

0

JSPの処理と、JavaScriptの処理をごっちゃにしてはいけません。
処理が走る順番から、理解してください。

評価

0

JSPのスクリプトレットとJavaScriptの実行タイミングについて理解しておられないのでは?

JSPスクリプトレットはサーバ側で、JavaScriptはクライアントブラウザで実行されます。

つまり、JSPでJavaScriptを動的に生成できても、JavaScriptでJSPスクリプトレットを動的に生成することは不可能です。

ようは、<% application.setAttribute("boxnum",new Integer(1)); %>をJavaScriptでSwitch処理している点がアウトです。
根本的な仕組みを再考した方が良いでしょう。


余談ですが、applicationはHttpSessionではなくServletContextなので、request、session、applicationについても学んでおいた方が良いです。

評価

0

回答ありがとうございます。
根本的にJavaScriptの中でJavaを使うということ自体が
おかしかったのですね。

この処理を実現させるために、
1、PostでRequestに数値を設定してサーバに送る
2、サーバで受けてどのリクエストか判定してBeanに設定
3、その後Jspをリロードさせる
4、Beanからデータを取得するメソッドを作っておく
5、Jspでは4を使ってBeanから数値取ってきて値分のテキストボックスの作成。

という処理をしなくてもいい方法がないかな?と考えていて
ひねりだしたJavaScriptでした。
JavaScriptではSessionが扱えないし、URLに組み込んだところで
このJSPを呼び出しているのがServletなのでURL組み込みもダメ。

やはり上記1〜5の手順を踏むべきなのでしょうか?

となると テキストボックスに記入されたデータを登録するための
Form文の中に Form文を入れ子で書くことになってしまうんですね。

画面の表記から考え直すべきかもしれませんね・・・

評価

0

>Form文の中に Form文を入れ子で書く
できません。

要するに、画面をリロードさせずにサーバ側で判定を行い、画面の一部を変更したいということなんですね?
いくつか、案はあります。

1. 変更する部分と元の部分を、frameで分ける
画面デザインを変える必要がありますが、処理的にはそれほど考えることなく、実現できると思います。

2. 隠しframeを利用する
隠れたframe(もしくはiframe)でサーブレットを呼び出し、onloadイベントでbodyのinnerHTMLを拾います。

3. AJAXを利用する
知識が必要ですが、JavaScriptだけでサーバと通信ができます。最近はこれが流行りです。

評価

0

回答ありがとうございます。

Formの入れ子は出来ないのですか・・・・

>画面をリロードさせずにサーバ側で判定を行い、画面の一部を変更したいということなんですね?

画面はリロードしてもいいんですが、
じつはURLに埋め込む方式で実験してみたところ、
実際に表示させているのはinsert.jspだけど
サーブレットから表示させているので、アドレスは

http://localhost:8080/project/jsp/Servlet

って表記されており、ここが

http://localhost:8080/project/jsp/insert.jsp?boxnum=5

とかいう表示に一度なると、もう一度プルダウンメニューを
変更したら

jsp/jsp/insert.jsp がみつかりません。

なんていうエラーになってしまうので、この方法は
ダメなんだろうと思ってました。

実際画面のリロードは現在あげているコードの36行目で
location.href = "javascript:location.reload(true);"
と行っています。

mioさんの掲示してくださった 1,2 の方法は
埋め込みフレームを使うということですよね?

今、やろうとしているのですが、HTMLのOnChangeには
JavaScriptのコードを呼び出すのが常套手段のようで、
ここからServletにRequestを投げるにはやはり
Submitボタンを配置してあげないといけないという
ことになってしまうんでしょうか?

質問ばかりですみません。

評価

0

質問の答えになっていない部分があったので追記します。

ただ、boxの数を増やして再描画できるように
したいだけなので、クライアント側だけの処理でなんとか
できないものかとJavaScriptとSession(ここではapprication)
等を使って何とかできないものかと考えておりました。

評価

0

なぜJavaScriptでsessionが使えないのかというと、sessionというのは、そもそもサーバが同じ箇所からのリクエストを便宜的にそう呼んでいるだけで、
クライアントから見てそういうものは存在しないからです。
クライアントから見ると、それぞれのリクエストはすべて別のもの、レスポンスとして得られる画面も、すべて別のものです。

submitボタンでは、画面がリロードされることになります。
onchangeでJavaScriptのコードを呼ぶのは良いとして、そこで隠しフレームのlocation.hrefを書き換えることで、
表示中の画面とは独立してサーブレット/jspを呼び出し、その処理結果を得ることができます。
それを今風に書くとすると、3番目のAJAXになります。

評価

0

>jsp/jsp/insert.jsp がみつかりません。
>なんていうエラーになってしまうので、この方法は
>ダメなんだろうと思ってました。
これは単純に、リクエストするURLがおかしいからです。
相対パスでリクエストする際は、常にリクエストをあげる画面がどの階層にいるかを、意識しておく必要があります。
それができないのであれば、リクエストはルートからの相対パスで記述すべきです。

評価

0

回答ありがとうございます。
返答が遅くなってしまってすみません。

frameを使った方式で実験しておりました。
プルダウンメニューだけを記述したjspを作成し、
もとの insert.jsp部分には <iframe> で作成した
jspを表示させるようにしたところ、うまくいきました。

いまのところ、新しいjsp(insert_idnum.jsp)を
<%@page contentType="text/html; charset=SJIS" %>
<html>
<body bgcolor = #6666FF>
<form name="boxnum" action="/project/Servlet" method="post">
    <select name="boxnum" onChange="submit();">
        <option value="1">1</option>     <!-- 以下明細件数 -->
        <option value="2">2</option> 
        <option value="3">3</option> 
        <option value="4">4</option> 
        <option value="5">5</option> 
    </select> 
    <input type="hidden" name="pageName" value="insert_idnum">    
</FORM>
</body>
</html>

上記のように記述してサーブレットに飛ばしており
サーブレットのほうも特に遷移対象を記述したコードに
なっていないので、プルダウンメニューの小さなフレームの中に
insert.jspを表示しようとしているおかしなことになっていますが
もう少し勉強して、子フレーム?から上がったリクエストで
親フレーム?を更新できるように直していくつもりです。



>これは単純に、リクエストするURLがおかしいからです。
>相対パスでリクエストする際は、常にリクエストをあげる画面がどの階層にいるかを、意識しておく必要があります。
>それができないのであれば、リクエストはルートからの相対パスで記述すべきです。 

この部分なのですが、遷移先としてルートからのパス
/project/jsp/insert.jsp?boxnum=5
のように指定しておりました。

結果、一回プルダウンメニュー変更をしただけなら
うまく画面遷移できたのですが、その画面でもう一度
プルダウンメニューを変更すると前述のような

jsp/jsp/insert.jsp がみつかりません。

というエラー表記になっておりました。
これは、自分が考えているルートからの相対パスの記述が
おかしいということなのでしょうか?

評価

0

>というエラー表記になっておりました。
きちんと設定していないからこそ、こういうエラーが出るとしか言えません。
遷移する前に、ソース表示やアラートなどでパスを確認してください。
「なっているはず」なんていうのは、実際に問題が起きている以上意味がありません。

評価

0

遷移先は相対パスより絶対パスで。

理由:サーブレットからの場合とJSPからの場合で遷移先が動く。

たとえば jsp/forward.jsp の場合
http://localhost:8080/context/servlet

http://localhost:8080/context/servlet/jsp/forward.jsp

http://localhost:8080/context/servlet/jsp/jsp/forward.jsp
となってしまう。

JSPフォルダに遷移したあとに更にしたのJSPふぉルダに見に行くから発生します。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。