- PR -

JSPページング処理にて

1
投稿者投稿内容
会議室デビュー日: 2007/09/21
投稿数: 4
投稿日時: 2007-09-21 19:08
[環境]
OS WINDOWS 2000
DB MS ACCESS 2000
JAVA j2sdk1.4.2_06
TOMCAT 4.1.24

[現象]
条件画面と一覧画面からなる検索システムをJSP,サーブレット,beanで作りました。

機能として、条件画面で指定した条件でDBより抽出し一覧画面に表示する。

一覧画面では前ページ、次ページボタンにてページング処理います。

IEを1つ立ち上げて参照するのには問題ないのですが、

複数のIEを立ち上げて参照した場合に以下のような問題が発生します。

・1つ目のIEを起動する->以下IE1
IE1)条件画面から一覧画面に遷移。1ページ目が表示されるので
次ページボタンを2回押して3ページ目に遷移する。

・2つ目のIEを起動する->以下IE2
IE2)条件画面から一覧画面に遷移。1ページ目が表示される(IE1同様)

IE1)次ページボタンを1回押すと2ページ目に遷移する。
(4ページ目に遷移して欲しい)

IE2)次ページボタンを1回押すと3ページ目に遷移する。
(2ページ目にして欲しい)

IE毎にページ情報を保持したいのですが、

何が問題なのか検討がつきません。
以下はソースの抜粋です、よろしくお願いします。

[サーブレット 抜粋]
import beans.FileLstManager;

public class G100 extends HttpServlet
{

FileLstManager FilLstMan = new FileLstManager();

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{

request.setCharacterEncoding("JISAutoDetect");

ServletContext sc = getServletContext();

try {
// 実行ボタン
if(request.getParameter("bt1") != null) {

FilLstMan.setDspCnt(30);
FilLstMan.executeQuery(request.getParameter("txTitle"),request.getParameter("rdSerch"),request.getParameter("rdSort1"),request.getParameter("rdSort2"));
request.setAttribute("FilLst", FilLstMan);
sc.getRequestDispatcher("/G110.jsp").forward(request, response);
}
// 前頁ボタン
if(request.getParameter("btPrev") != null) {
FilLstMan.setDspCnt(30);
FilLstMan.pPrev();
request.setAttribute("FilLst", FilLstMan);
System.out.println("----- (/G110.jsp).forward -----");
sc.getRequestDispatcher("/G110.jsp").forward(request, response);
}
// 次頁ボタン
if(request.getParameter("btNext") != null) {
FilLstMan.setDspCnt(30);
FilLstMan.pNext();
request.setAttribute("FilLst", FilLstMan);
System.out.println("----- (/G110.jsp).forward -----");
sc.getRequestDispatcher("/G110.jsp").forward(request, response);
}
}
}
}

[bean 抜粋]
package beans;
import beans.FileLst;

public class FileLstManager implements Serializable {

final int DefaultDspCnt = 10; // 画面表示行数(デフォルト)
Vector filLsts;
FileLst current = null;
private int KeyBuff[]; // キーバッファ
private int index = 0;
private int dspCnt=0; // 画面表示行数
private int recCnt=0; // レコードカウント
private int pageCnt=0; // ページカウント
private int curPage=0; // カレントページ

public boolean next() {
if (index < filLsts.size()) {
current = (FileLst) filLsts.elementAt(index);
index ++;
return true;
}
else {
return false;
}
}
public void pPrev() throws SQLException{
int iFrom = 0; // キーバッファインデックス(開始)
int iTo =0; // キーバッファインデックス(終了)
if (curPage > 1){
curPage--;
}
iFrom = (curPage - 1) == 0 ? 0 : (curPage - 1) * dspCnt;
iTo = (iFrom + dspCnt) > KeyBuff.length ? KeyBuff.length : iFrom + dspCnt;
pageNext(iFrom,iTo);
}
public void pNext() throws SQLException{
int iFrom = 0; // キーバッファインデックス(開始)
int iTo =0; // キーバッファインデックス(終了)

if (curPage < pageCnt){
curPage++;
}
iFrom = (curPage - 1) == 0 ? 0 : (curPage - 1) * dspCnt;
iTo = (iFrom + dspCnt) > KeyBuff.length ? KeyBuff.length : iFrom + dspCnt;
pageNext(iFrom,iTo);
}
private void pageNext(int iFrom, int iTo) throws SQLException {
int i;
init();
Statement stmt = cn.createStatement();
for (i = iFrom; i < iTo; i++){
String sSql = "SELECT * FROM FILELST WHERE FILELST.[NO] = " + KeyBuff[i];
ResultSet rs = stmt.executeQuery(sSql);
rs.next();
FileLst filLst = new FileLst();
filLst.setFolder(rs.getString("FOLDER"));
filLst.setFdate(rs.getString("FDATE"));
filLst.setFname(rs.getString("FNAME"));
filLst.setFsize(rs.getInt("FSIZE"));
filLst.setAppear(rs.getString("APPEAR"));
filLst.setRemarks(rs.getString("REMARKS"));
filLsts.addElement(filLst);
rs.close();
}
stmt.close();
cn.close();
}
}

mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-09-21 19:27
>FileLstManager FilLstMan = new FileLstManager();
思い切りこれが原因でしょう。
クライアントごとに異なる情報を、シングルインスタンスであるサーブレットのフィールドに持ってはいけません。
会議室デビュー日: 2007/09/21
投稿数: 4
投稿日時: 2007-09-21 20:54
mioさん、ご回答ありがとうございます。

質問ですが、
FileLstManager FilLstMan = new FileLstManager();
はどこで行うべきなのでしょう?
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2007-09-22 00:51
ページング情報はクエリ・パラメータでよいとも思えますが。
引用:

Jさんの書き込み (2007-09-21 20:54) より:
FileLstManager FilLstMan = new FileLstManager();
はどこで行うべきなのでしょう?


保持する場所が問題なだけで、生成はどこでもかまわないでしょう。
セッションに持たせるなりすればそれだけで解決するのではないでしょうか。
会議室デビュー日: 2007/09/21
投稿数: 4
投稿日時: 2007-09-22 17:26
暁さん、ご回答ありがとうございました。

今回の問題点を整理していたのですが、
まず、構成はこのようになります。

「MVCモデルを意識した検索システムの構成」

・サーブレット・・・C
G100.JAVA
条件画面、一覧画面の振分け
beanインスタンスを生成

・JSP・・・V
条件画面(G100.JSP)
抽出条件を指定する

一覧画面(G110.JSP)
抽出条件に一致するデータを表示
一覧は30行表示とし、前・次ボタンでページ切替を行う
表示データはbeanより取得

・bean・・・M
FileLstManager.java
・与えられた抽出条件でDBを検索しキー情報を保持する
・ページ切替制御を行い、保持したキー情報より表示対象となるデータを検索する

MVCを意識した構成のつもりなのですが、
ダメならご指摘お願いします。

また、beanのインスタンスをie毎に生成できれば
問題は解決すると思われるのですが可能なのでしょうか?
可能であれば、どのタイミングで生成すべきなのでしょう?
そもそもこのような検索システムを実現するには
どのような構成にすべきなのでしょうか?
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2007-09-23 00:26
引用:

Jさんの書き込み (2007-09-22 17:26) より:
MVCを意識した構成のつもりなのですが、
ダメならご指摘お願いします。


だめじゃないです。
検索結果が、検索時点でのスナップショットになるんですね。
だとすれば、このつくりで妥当だと思います。

私がページングを作る際は、毎回検索しなおして表示させることがほとんどですので
検索結果を保持するbeanを作ることがまずないのです。
それ故に、パラメータだけでよいのではないかと思ったのです。

引用:

また、beanのインスタンスをie毎に生成できれば
問題は解決すると思われるのですが可能なのでしょうか?


beanのインスタンスを、doPostメソッド内で生成すれば解決です。
そうして、ユーザセッションごとのHttpSessionで保持してやると。
(あるいはシリアライズ機構を組みこむか)

上記引用コメントの意図が、リクエストごとにServletクラスの
インスタンスを生成させたいということであれば無理です。
会議室デビュー日: 2007/09/21
投稿数: 4
投稿日時: 2007-09-24 08:57
暁さん、ご回答ありあごうございました。

このつくりで問題ないとの事でほっとしています。
実はjava入門者で、ノウハウがなく、あちこちのサイトから
情報収集して継ぎはぎした結果、このつくりとなってました。

>beanのインスタンスを、doPostメソッド内で生成すれば解決です。
>そうして、ユーザセッションごとのHttpSessionで保持してやると。

なるほど、抽出実行時にbeanに設定されたキー情報などの内容を
セッションに保持し、前・次ページ実行時にはセッションから
beanを復元するという事ですね。

色々とありがとうございました。




1

スキルアップ/キャリアアップ(JOB@IT)