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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java EE

Java EE(Java Enterprise Edition)はJavaベースのテクノロジーとその相互運用の仕様をまとめたものです。サーバとクライアントのアーキテクチャを規定し、特定アプリケーションのクラス用に定義されたテクノロジー設定のプロファイルを使用します。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Q&A

解決済

2回答

16305閲覧

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

kyasubaru

総合スコア21

Java EE

Java EE(Java Enterprise Edition)はJavaベースのテクノロジーとその相互運用の仕様をまとめたものです。サーバとクライアントのアーキテクチャを規定し、特定アプリケーションのクラス用に定義されたテクノロジー設定のプロファイルを使用します。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

0グッド

0クリップ

投稿2016/03/22 15:20

編集2016/03/25 15:30

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

以下動作環境
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クラスがサーブレットから呼ばれます。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

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

Java

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

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

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

投稿2016/03/22 15:26

編集2016/03/22 16:32
Odacchi

総合スコア907

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyasubaru

2016/03/22 16:05

ご回答ありがとうございます。 御指摘頂いたとおり、クラス名下のフィールド宣言箇所で HttpServletRequest request = null; と修正しましたが解決出来ませんでした。 また問題発生箇所の上でローカル変数として request = null; とも修正しましたが、解決しませんでした。
Odacchi

2016/03/22 16:29 編集

nullではだめということです。 nullは何も参照していないことを表してます。 何も参照していないので、getSession()メソッドを呼び出すことができません。 HttpServletRequest型のインスタンスを生成して、代入してください。 他にHttpServletの実装などはありませんか?
kyasubaru

2016/03/25 15:31 編集

ご返信遅れまして申し訳ございません。 はい実装は当クラスのみです。少々低いレベルのご質問かもしれませんが、 「他にHttpServletの実装などはありませんか? 」 とご指摘頂きました個所が解釈できかねております。 他クラスで実装しているとするとどういった使い方があるのでしょうか? またHttpServletRequest request = new HttpServletRequest();としたところインスタンスを作成できませんと表示されましたがなぜなのでしょうか? お手すきの際にでもご回答お待ちしております。 補足追加致しました。
Odacchi

2016/03/25 16:23

HttpServletRequestは、クラスではなくインタフェースなので、インスタンスを生成できません。 今の状態はどんな感じかというと、 あなたはタクシーというサービスを受けようと思っている人とします。 タクシーというサービスを受けるためには、「車」と「運転手」と「あなた」が必要です。 今のあなたのソースコードは「車や車のハンドル、ブレーキ、アクセル(DBとDBへのアクセスの実装)」を作りこんでいるだけで、肝心の運転手(HttpServlet)が存在していません。 あなたはブラウザなどを介して、運転手に「サービスを受けたい」とリクエスト(HttpServletRequest)をしようとしているわけですが、運転手が居ないタクシーにいくら語りかけても、タクシーはウンともスンとも言いません(;・∀・) したがって、HttpServletクラスを継承して、あなたのリクエストに答えてくれる運転手を作ってください。そうすれば、運転手はあなたが望むサービスをしてくれることでしょう。 下記など参考になりませんか? http://www.wakhok.ac.jp/~tomoharu/web2004/text/index_c10.html
kyasubaru

2016/03/27 10:09

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

0

ベストアンサー

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

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

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

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

投稿2016/03/23 00:53

takyafumin

総合スコア2335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyasubaru

2016/03/25 15:34

ご回答ありがとうございます。ご質問させて頂いてよろしいでしょうか? ご指摘頂きました 「質問のソースを確認したところ、サーブレットから呼び出すUtilクラスではないでしょうか?」 上記の個所が解釈しかねております。 また厚かましいご依頼で申し訳ございませんが、上記の追記ソースを踏まえたうえで、こうしたほうがいいなどご指導頂ければ幸いです。 ぜひ宜しくお願い致します。
takyafumin

2016/03/26 04:41 編集

> 上記の個所が解釈しかねております。 下記をもとに勝手に判断しました。 * パッケージ名が「util」であったこと * 機能がDBアクセスするクラスであったこと * HttpServletを継承していないこと 追加で提示いただいたソースを拝読しました。 手厳しいかもしれませんが、Servletに関する基礎的な部分の理解が足りてないと感じました。 まず下記のような書籍を参考に、写経のようにサンプルソースの写しと動作検証を行い、少しずつ機能追加(カスタマイズ)してServletへの理解を深めるのが解決への近道では?と思います。 * http://www.amazon.co.jp/10%E6%97%A5%E3%81%A7%E3%81%8A%E3%81%BC%E3%81%88%E3%82%8BJSP-%E3%82%B5%E3%83%BC%E3%83%96%E3%83%AC%E3%83%83%E3%83%88%E5%85%A5%E9%96%80%E6%95%99%E5%AE%A4-%E7%AC%AC4%E7%89%88-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4798140341 (Eclipseでの開発例ではないが、JSP, Servletの役割や仕組みの説明あり。立ち読みもよいかと思います) --- > また厚かましいご依頼で申し訳ございませんが、上記の追記ソースを踏まえたうえで、こうしたほうがいいなどご指導頂ければ幸いです。 手厳しいことだけだと失礼だと思いますので、ソースに対する修正提案です。 難しいことを言っているかもしれませんが、考え方として参考としてください。 * 各クラスは機能が分かるようなクラス名にする * Exceptionが発生した際、後続の処理に影響する場合は適切なエラー処理を行う * ResultSetやConnectionは、エラー発生時にも必ずcloseされるよう実装する * Sessionを扱うのはServletだけにする * R001, JdbcDriver, QueryExcuteは1クラスにメソッドとして定義する - クラス:Users - public List<String> getMailAddresses() - 内部でR001, JdbcDriver, QueryExecuteと同様の処理を実装 - 戻り値はDB検索で取得したメールアドレスのリスト --- 書籍は安いものではないですが、Webでの参考情報に比べると知識体系がきちんと構成されており、理解しやすい構造になっているものが多いと個人的には感じています。 「理解のしやすさ」には個人差があるので共有できる感覚ではないですが、立ち読みで試し読みし、自分の理解にあった説明がある書籍を手元に1冊準備しておくとよろしいかと思います。
kyasubaru

2016/03/27 10:16

ご親切にご回答ありがとうございます。 セッション取得に関しましてはサーブレットで行う事により解決できました。本当にありがとうございます。 作成ソースに対しての修正案有難うございます。まだ考え付いたことのみコーディングしているだけなので、ご指摘頂きましたことを拝見させて頂きますと技術力の低さを痛感しております。 ますはご指摘頂いた点の修正を試みてみたいと考えています。 また今後こちらのサイトで不明点などをご質問させていただくかと思いますので、お見掛けになりましたら、手厳しい事でも指摘頂けたらと幸いでございます。
takyafumin

2016/03/27 10:38

解決に至ったようでよかったです。 自分も過去には同じようにサーブレットの機能や役割への理解に苦労しました。 クラスごとの「役割」を意識して設計、実装していくと良いかと思います。 引き続きがんばってください。
kyasubaru

2016/03/27 11:01

takyafumin様 ベストアンサー選定後ということで、マナー違反と存じ上げますが、宜しければ最後に2点ほどご質問宜しいでしょうか? ・1点目 ご指摘頂きました1クラスにまとめるといった作業ですが、このご指摘意図としては個々の処理機能として1クラスにまとめた方が処理の流れがわかりやすくなる為。といった所でしょうか? 当方のコーディング意図としては、知識不足ながらカプセル化としてバグ発生時のメンテナンスやソースの再利用化という観点でクラスを分けて作成をしておりました。 ・2点目 こちらは現在新規で迷っている問題です。 チェッククラスにてエラーを検知後、そのエラーメッセージを元の入力したJSP画面へ表示させたいのです。サーブレットでの処理はできていますが、JSP画面の処理ロジックの想像がつきません。 試しにエラー表示をしてみようとしたところ、その処理(エラーメッセージをセッションから取得)が初めから読み込まれてしまうので、正常に動きません。 どのようにして元のJSP画面へ戻したら宜しいでしょうか? 宜しくお願い致します。
takyafumin

2016/03/27 11: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を判定するとよいかと。 もう少し踏み込んでの説明となると、コメント欄だけでは厳しいので、ソース部分も記載して新たに質問されると良いかと思います。
kyasubaru

2016/03/28 15:14

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問