質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.79%

filterでユーザー振り分けがしたいです。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,318

score 13

イベント管理システムを作成しています。

フィルターファイルで、DBに登録しているテーブルのtype_idごとにページの飛ばし先を変更したいです。
1=一般ユーザーページ
2=管理ユーザーページ

イメージ説明

-- users テーブル作成
CREATE TABLE users (
    id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    login_id VARCHAR(50) NOT NULL unique,
    login_pass VARCHAR(255) NOT NULL,
    name VARCHAR(50) NOT NULL,
    type_id INT NOT NULL,
    group_id INT NOT NULL,
    created  DATETIME NOT NULL
);
-- users テーブルサンプル追加 1
INSERT INTO mydb.users(login_id, login_pass, name, type_id, group_id, created)
VALUES('tarou','taroupass','山田太郎',1,1,'2019-05-02 11:12:00');

-- users テーブルサンプル追加 2
INSERT INTO mydb.users(login_id, login_pass, name, type_id, group_id, created)
VALUES('takasi','takasipass','田中隆',2,2,'2019-02-18 05:08:00');

-- users テーブルサンプル追加 3
INSERT INTO mydb.users(login_id, login_pass, name, type_id, group_id, created)
VALUES('yuuki','yuukipass','小鳥遊ゆうき',1,3,'2019-01-20 04:30:00');```  
package filter;  

import java.io.IOException;  

import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
import javax.servlet.annotation.WebFilter;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;  

/**  
* Servlet Filter implementation class AuthFilter  
*/  
@WebFilter("/AuthFilter")  
public class AuthFilter implements Filter {  

/**  
* Default constructor.  
*/  
public AuthFilter() {  
// TODO Auto-generated constructor stub  
}  

/**  
* @see Filter#destroy()  
*/  
public void destroy() {  
// TODO Auto-generated method stub  
}  

/**  
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)  
*/  
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
throws IOException, ServletException {  
// TODO Auto-generated method stub  
// place your code here  

HttpServletRequest req = (HttpServletRequest) request;  
HttpServletResponse res = (HttpServletResponse) response;  
HttpSession session = req.getSession();  
String uri = req.getRequestURI();  
if (!uri.endsWith("/login")) {  
if (session.getAttribute("loginId") == null) {  
res.sendRedirect("login");  
return;  
}  
}  

// pass the request along the filter chain  
chain.doFilter(request, response);  
}  

/**  
* @see Filter#init(FilterConfig)  
*/  
public void init(FilterConfig fConfig) throws ServletException {  
// TODO Auto-generated method stub  
}  

}  

どのようなコードを書いたらわからないので、教えていただけますと幸いです。 ほかに必要な情報がありましたら教えてください。

>追記 現在、データベースのテーブル作成しました。 type_idカラムの値を条件にフィルターファイルでページの振り分けするところで止まっています。

>4.絞込検索のときにプリペアドステートメントを利用する:prepareStatementの使用 ⇒手順4でつまづいてます。 PreparedStatement st = con.PreparedStatement(sql);の一行がエラーになります。

package test04;  

import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Statement;  

/**  
* localhost上のデータベースと接続し、取得したデータをコンソール出力する。  
*/  
public class UseJdbc {  

public static void main(String args[]) throws Exception {  

/*接続先サーバー名を"localhost"で与えることを示している*/  
String servername = "localhost";  

/*接続するデータベース名をsenngokuとしている*/  
String databasename = "mydb";  

/*データベースの接続に用いるユーザ名をrootユーザとしている*/  
String user = "root";  

/*データベースの接続に用いるユーザのパスワードを指定している*/  
String password = "pass";  

/*取り扱う文字コードをUTF-8文字としている*/  
String serverencoding = "UTF-8";  

/*データベースをあらわすURLを設定している*/  
String url = "jdbc:mysql://localhost/" + databasename;  

/*MySQLの場合、URLの形式は次のようになります。  
jdbc:mysql://(サーバ名)/(データベース名)*/  

/*↑データベースをあらわすURL(データベースURL)は、データベースに接続する場合に  
必要となる情報をセットした文字列である。  
この文字列の構造は、"jdbc"、サブプロトコル、サブネームの3つの部分から構成される。*/  

/*接続を表すConnectionオブジェクトを初期化*/  
Connection con = null;  

try {  

/*クラスローダによりJDBCドライバを読み込んでいることを示している。  
引数は、データベースにアクセスするためのJDBCドライバのクラス名である。*/  
Class.forName("com.mysql.jdbc.Driver").newInstance();  

/*DriverManagerクラスのgetConnectionメソッドを使ってデータベースに接続する。*/  
con = DriverManager.getConnection(url, user, password);  

System.out.println("Connected....");  

/*データベースの接続後に、sql文をデータベースに直接渡すのではなく、  
sqlコンテナの役割を果たすオブジェクトに渡すためのStatementオブジェクトを作成する。*/  
//            Statement st = con.createStatement(sql);  
PreparedStatement st = con.PreparedStatement();  

/*SQL文を作成する*/  
String sqlStr = "SELECT * FROM mydb.users where name = ?,?;";  
st.setString(1, "山田太郎");  

/*SQL文を実行した結果セットをResultSetオブジェクトに格納している*/  
ResultSet result = st.executeQuery(sqlStr);  

/*クエリ結果を1レコードずつ出力していく*/  
while (result.next()) {  
/*getString()メソッドは、引数に指定されたフィールド名(列)の値をStringとして取得する*/  
//                String str1 = result.getString("id");  
String str2 = result.getString("login_id");  
String str3 = result.getString("login_pass");  
//                String str4 = result.getString("name");  
//                String str5 = result.getString("type_id");  
//                String str6 = result.getString("grouo_id");  
//                String str7 = result.getString("created");  
//                System.out.println(str1 + ", " + str2 + ", " + str3 + "," + str4);  
System.out.println(str2 + ", " + str3);  
}  

/*ResultSetオブジェクトを閉じる*/  
result.close();  

/*Statementオブジェクトを閉じる*/  
st.close();  

/*Connectionオブジェクトを閉じる*/  
con.close();  
} catch (SQLException e) {  

/*エラーメッセージ出力*/  
System.out.println("Connection Failed. : " + e.toString());  

/*例外を投げちゃうぞ*/  
throw new Exception();  

} catch (ClassNotFoundException e) {  

/*エラーメッセージ出力*/  
System.out.println("ドライバを読み込めませんでした " + e);  
} finally {  
try {  
if (con != null) {  
con.close();  
}  
} catch (Exception e) {  

/*エラーメッセージ出力*/  
System.out.println("Exception2! :" + e.toString());  

/*例外を投げちゃうぞ*/  
throw new Exception();  
}  
}  
}  
}  
コード  
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Yuri0402

    2019/05/24 13:15

    DBは、mysqlを使用しています。

    キャンセル

  • m.ts10806

    2019/05/24 13:20

    あ、ごめんなさい。
    >【java初心者】
    タグに「Java」はありますし「初心者アイコン」もあるのでタイトルにつける必要はないので削ってもらえればと。「要件のみ」が原則です。
    >type_idカラムの値を条件にフィルターファイルでページの振り分けするところ
    DBからデータを取得する処理(ここはフィルタ・検索あってもなくても良いですが)はできますか?
    参考にできそうな記事は(サーブレット、JSP)結構あると思います。

    キャンセル

  • Yuri0402

    2019/05/24 13:28

    >DBからデータを取得する処理(ここはフィルタ・検索あってもなくても良いですが)はできますか?
    参考にできそうな記事は(サーブレット、JSP)結構あると思います。
    ⇒ネットの記事を参考にDAOを使ってためしてみたりしたのですが、自力ではうまくいかなかったため、今回質問させていただきました。。。もう一度調べて再度返信させていただきます。

    キャンセル

回答 1

0

ネットの記事を参考にDAOを使ってためしてみたりしたのですが

DAOにしようと思うとワンクッション置くことになるのでまずは「直にSQLを実行してDBからデータを取得する」ことを次の段階とすると良いでしょう。

流れとしては下記。

  1. 全て取得する:データを取得する(SELECT文)
  2. 絞り込む:データを取得する条件を設定する(WHERE句)
  3. JavaからMySQLに接続する/結果を取得する:データの取得(SELECT)
    jdbcドライバー部分が古いかもしれません。最新確認してください
  4. 絞込検索のときにプリペアドステートメントを利用する:prepareStatementの使用

という感じです。
あとは任意のデータが取得出来たらそれをもとに実現したい処理を入れていきます。

コード追記を受けて

流れを提示したところでちょっと説明不足があったかもしれませんが、
1,2についてはDBに対して直接SQLを実行してください。
SQLはプログラムからすると外部のサービスです。
外部のサービスを利用する際は、いきなりプログラムを経由するのではなく、直接実行してみて実行できるかどうか確かめて、想定通りの結果が得られるパラメータをそのまま利用します。

下記ですが、直接DBに対して実行してみましたか?
SELECT * FROM mydb.users where name = ?,?

2.で提示したリンクに name = ?,? のような書き方はなかったはずです(コンマで区切っているところ)
提示リンクより引用しますが、複数条件を指定したい場合はANDやORなどでつなぎます

SELECT * FROM personal WHERE address='Osaka' AND old>=20;

マニュアルも確認してください→ SELECT構文

今回はnameで検索したいようですから,?は不要です。
SELECT * FROM mydb.users where name = ?

ただDBに対して実行する場合は?ではいけないので適当な値をおいて実行します。
SELECT * FROM mydb.users where name = '山田太郎'

これが通るか確認してください。

※今後SELECT以外も使うようになると思いますが、必ず直接DBに実行して想定通りの結果が得られるSQLを使うようにしてください。いきなりプログラムから実行してしまっては問題の切り分けが難しくなります。

次。

String sqlStr = "SELECT * FROM mydb.users where name = ?,?;";  
st.setString(1, "山田太郎");  


プリペアドステートメントはまずSQLでバインド待ち(?)の値をバインドしてからDBに届けます。
このSQL上ではバインド待ちが2つあるのでsetも同じ数必要です。

おそらくでエラーになっているのでは(つまり、セット予定と実際にセットされた値の数が合わない)

私が提示した4番目の記事にも書いてありますね。

この例では実際に挿入する値を記述箇所に「?」を使っています。2箇所使っていますので、後からパラメータを2つ指定する必要があります。
パラメータはSQL文中に記述された「?」を先頭から順番に1,2,3、・・・と順番に番号が割り当てられています。1番目のメソッドにはパラメータの番号を指定し、2番目の引数にパラメータに設定したい値を記述します。

あとは型を適切に設定してください。

元々のSQLの間違いをなおせばsetは1つで良くなります。

*蛇足確認
これは仕様部分なのですが、nameで検索しようとしていますが、これはあくまで検証のためですよね?
通常ログインといったらユーザIDとPASSを半角英数で入力するので・・。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/24 14:47

    >4.絞込検索のときにプリペアドステートメントを利用する:prepareStatementの使用
    ⇒手順4でつまづいてます。 PreparedStatement st = con.PreparedStatement(sql);の一行がエラーになります。コードは上に追加しました。

    キャンセル

  • 2019/05/24 14:49

    インデントが全くないのでちょっと見づらいです。手元のコードを調整して再度ご提示いただけますか?

    キャンセル

  • 2019/05/24 14:49

    またエラーとなるのでしたら原則エラーメッセージをそのままご提示ください。

    キャンセル

  • 2019/05/24 14:50

    そういえばコード内ではPreparedStatementにsqlを引数に指定しているところがないような。引数なしになってますね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る