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

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

ただいまの
回答率

89.99%

(Java)セッション取得ができない HttpSession

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 6,612

kyasubaru

score 19

いつもお世話になっております。
今回も皆様のお力を借りたくご質問させて頂きます。

以下動作環境
Java
エクリプス4.5Mars
動的WEBプロジェクト

WEBアプリを構築中ですが問題が不明な為投稿させて頂きます。
以下ソース

package util;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import model.SQL_RS_form;

public class QueryExcute {

    HttpServletRequest request;

    public void queryEX(ResultSet rs) {

        SQL_RS_form rsform = new SQL_RS_form();
        List<Object> list = new ArrayList<Object>();

        try {
            while (rs.next()) {
                rsform.setUser_mail(rs.getString("user_mail"));
                list.add(rsform.getUser_mail());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        /* 問題発生個所 */
        HttpSession session = request.getSession();
        session.setAttribute("user_mail", list);
    }
}

/*MYSQL接続*/
package util;

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

public class JdbcDriver {

    final static String DRIVER = "com.mysql.jdbc.Driver";
final static String URL = "-------";
    final static String NAME = "-----";
    final static String PASS = "------";

    Connection con = null;
    public void Conect(String sql) throws SQLException {

        try {
            Class.forName(DRIVER).newInstance();
        } catch (InstantiationException e) {

            e.printStackTrace();
        } catch (IllegalAccessException e) {

            e.printStackTrace();
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }

            con = DriverManager.getConnection(URL, NAME, PASS);
            Statement smt = con.createStatement();
            ResultSet rs = smt.executeQuery(sql);

            QueryExcute qe = new QueryExcute();
            qe.queryEX(rs);

            con.close();
    }

}

/* メールアドレスを全件検索 */
package dao;

import java.io.IOException;
import java.sql.SQLException;
import util.JdbcDriver;
import util.QueryLoader;

public class R001 {
    public void select() throws IOException, SQLException {

        String sql = QueryLoader.getQuery("R001", "SQL01");
        JdbcDriver jdbc = new JdbcDriver();
        jdbc.Conect(sql);

    }
}
package validate;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
import javax.servlet.ServletRequest;
import common.MessageStream;
import dao.R001;

/*メールアドレス重複チェッククラス*/
public class S002 {
    ServletRequest session;
    public String validate(String mail) {

        MessageStream me = new MessageStream();
        Properties inMessage = null;
        try {
            inMessage = me.loadUtf8Properties("/Message.properties");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            R001 r001 = new R001();
            r001.select();

@SuppressWarnings("unchecked")
            List<String> list = (List<String>) session.getAttribute("user_mail");

            for (String str : list) {
                if (mail.equals(str)) {
                    return inMessage.getProperty("M01");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return "";
    }
}

デバッグにて動作確認をしていた所、上記指摘個所「HttpSession session = request.getSession();」にて問題がエラーが発生しています。それまでの動作には問題は御座いません。
以下エラー文
java.lang.NullPointerException
    util.QueryExcute.queryEX(QueryExcute.java:36)
    util.JdbcDriver.Query(JdbcDriver.java:42)
    dao.R001.select(R001.java:19)
    validate.S002.validate(S002.java:32)
    servlet.MMPC002.doPost(MMPC002.java:46)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

問題が発生しなければ、ここでDBから取得してきた値がlistへ格納されているので、それをセッションへ保持して他ロジックで取得可能にさせるといった流れで考えています。
みなさまのお力添えの程宜しくお願い致します。

追記
一連の処理(下から進行)を掲載いたしました。S002クラスがサーブレットから呼ばれます。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

requestのインスタンスを生成していないからですね。

request = //インスタンス生成文。

requestに何も代入していないので、requestは初期値であるnullのままです。

※参照型の変数では起こりうるnull pointer exceptionについて、まず理解された方がいいと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/26 00:09 編集

    ご返信遅れまして申し訳ございません。
    はい実装は当クラスのみです。少々低いレベルのご質問かもしれませんが、

    「他にHttpServletの実装などはありませんか? 」

    とご指摘頂きました個所が解釈できかねております。
    他クラスで実装しているとするとどういった使い方があるのでしょうか?
    またHttpServletRequest request = new HttpServletRequest();としたところインスタンスを作成できませんと表示されましたがなぜなのでしょうか?
    お手すきの際にでもご回答お待ちしております。

    補足追加致しました。

    キャンセル

  • 2016/03/26 01:23

    HttpServletRequestは、クラスではなくインタフェースなので、インスタンスを生成できません。

    今の状態はどんな感じかというと、
    あなたはタクシーというサービスを受けようと思っている人とします。

    タクシーというサービスを受けるためには、「車」と「運転手」と「あなた」が必要です。

    今のあなたのソースコードは「車や車のハンドル、ブレーキ、アクセル(DBとDBへのアクセスの実装)」を作りこんでいるだけで、肝心の運転手(HttpServlet)が存在していません。

    あなたはブラウザなどを介して、運転手に「サービスを受けたい」とリクエスト(HttpServletRequest)をしようとしているわけですが、運転手が居ないタクシーにいくら語りかけても、タクシーはウンともスンとも言いません(;・∀・)

    したがって、HttpServletクラスを継承して、あなたのリクエストに答えてくれる運転手を作ってください。そうすれば、運転手はあなたが望むサービスをしてくれることでしょう。

    下記など参考になりませんか?
    http://www.wakhok.ac.jp/~tomoharu/web2004/text/index_c10.html

    キャンセル

  • 2016/03/27 19:09

    ご回答有難うございます。
    HttpServletRequestがインターフェースという認識がありませんでした。お恥ずかしい話です。ご親切に比喩表現ありがとうございます。

    キャンセル

checkベストアンサー

0

事象の原因としては「Odacchi」さまの回答の通りです。

質問のソースを確認したところ、サーブレットから呼び出すUtilクラスではないでしょうか?
それであれば、以下のように処理を変更することで改善できませんか?

  • QueryExcute#queryEX()メソッドの戻り値をvoidからList<Object>に変更
  • QueryExcute#queryEX()メソッドでは、listを返却
  • 呼び出し側サーブレットでQueryExcute#queryEX()メソッドの戻り値をsessionへセット

また、できればQueryExcute#queryEX()メソッド内のlistの型(List<Object>)はObjectではなく、型を指定したほうがよろしいかと思います。(String等)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/27 20:01

    takyafumin様
    ベストアンサー選定後ということで、マナー違反と存じ上げますが、宜しければ最後に2点ほどご質問宜しいでしょうか?

    ・1点目
    ご指摘頂きました1クラスにまとめるといった作業ですが、このご指摘意図としては個々の処理機能として1クラスにまとめた方が処理の流れがわかりやすくなる為。といった所でしょうか?
    当方のコーディング意図としては、知識不足ながらカプセル化としてバグ発生時のメンテナンスやソースの再利用化という観点でクラスを分けて作成をしておりました。

    ・2点目
    こちらは現在新規で迷っている問題です。
    チェッククラスにてエラーを検知後、そのエラーメッセージを元の入力したJSP画面へ表示させたいのです。サーブレットでの処理はできていますが、JSP画面の処理ロジックの想像がつきません。
    試しにエラー表示をしてみようとしたところ、その処理(エラーメッセージをセッションから取得)が初めから読み込まれてしまうので、正常に動きません。
    どのようにして元のJSP画面へ戻したら宜しいでしょうか?
    宜しくお願い致します。

    キャンセル

  • 2016/03/27 20:59

    今、時間がありますので問題ないです。

    >・1点目
    ご指摘頂きました1クラスにまとめるといった作業ですが、このご指摘意図としては個々の処理機能として1クラスにまとめた方が処理の流れがわかりやすくなる為。といった所でしょうか?

    「該当テーブルへのDB処理を担当するクラス」として1つにまとめ、機能ごとにメソッド(select, insert, update, delete, find等)を準備する方式を考えました。

    実際にシステムを構築する際にはもう少し踏み込んで、DB接続処理やクエリの実行部分は他のテーブルへのDB処理を担当するクラスと共通化する必要があるので、親クラスを作成してメソッドとして共有化する、なども考えられます。

    カプセル化・・・クラス内メンバへの外部からの直接アクセスを防ぎ、外部からの操作状態によってメソッドが意図しない動作をしないように設計することと理解しています。
    適切な識別子(public, protected, private)を付与することで実現します。

    ソースの再利用化・・・クラス化する以外にも親クラスとして再利用することも可能です。今回のケースでは、クラスを分けてもクラス間の依存性が強いのと、DB接続やクエリ実行はセットで利用するため、まとめたほうがシンプルだと思いました。
    ※まとめても、処理はメソッド単位で分けます。
    ただし、クラス設計としてはどちらも「アリ」かもしれません。いろいろ試して、後からどちらがよかったかを考えるのが経験としてよろしいかと思います。
    Javaのフレームワーク自体のソースを読むと、もっとすごいことをしています。(DI, コネクションぷーリングなど)少し難しいですが、徐々にフレームワークへ触れる機会を増やすと知識が増え、勉強になります。


    ---

    >・2点目
    こちらは現在新規で迷っている問題です。
    チェッククラスにてエラーを検知後、そのエラーメッセージを元の入力したJSP画面へ表示させたいのです。サーブレットでの処理はできていますが、JSP画面の処理ロジックの想像がつきません。

    よくある実装としては、以下のように実装するかと思います。

    1. サーブレットでエラーメッセージをセッションにセット
    2. JSP側でエラーメッセージがある場合のみエラーメッセージのHTML部分を表示させる

    エラーメッセージが複数ある場合は、エラーメッセージのリスト(List<String>)をセッションにセットし、JSP側でNullかlist.size()==0を判定するとよいかと。
    もう少し踏み込んでの説明となると、コメント欄だけでは厳しいので、ソース部分も記載して新たに質問されると良いかと思います。

    キャンセル

  • 2016/03/29 00:14

    お返事遅れまして申し訳ございません。
    1点目、2点目お目通しさせて頂きました。非常に参考になります。長文でのご説明本当に有難うございます。
    またお見掛け致しましたら、ご指導頂けますと幸いです。

    キャンセル

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

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

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