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

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

ただいまの
回答率

90.12%

サーブレット/jspについて

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,584
退会済みユーザー

退会済みユーザー

お世話になります。

表題について質問です。
いまMySQLに保存してある{int型 id, string型 name, string型 text}の3つを取得し、jspで出力を行おうとしています。

使用しているファイルは、
GetMutterListLogic.java(BO)
Mutter.java(javaBeans)
Main.java(サーブレット)
MutterDAO.java(DAO)
main.jsp
です。

流れとして、
①GetMutterListLogic.javaとMutterDAO.javaを使用して、DBから情報を取得し、Main.javaで受け取ります。そして、②受け取ったものをリクエストスコープに登録し、jspで登録したものを取り出す。といった流れです。

しかし、②で情報は取得できているのかがわかりません。
というのも、jsp側で、
List< Mutter > mutterList = (List< Mutter >) request.getAttribute( "mutterList" );
として受け取っているつもりなのですが、<%= mutterList %>をすると[]とだけ表示されます。また、<%= mutterList.size() %>とすると0と表示されます。

これは恐らく情報が取得できていないんだろうなと思うのですが、ディレクトリ構造のmodelパッケージの同階層にtestパッケージを作り、その中にテスト用のクラスを作り下記のように実行したところ、しっかりと出力されました。

何か原因がわかる方ご教授のほどお願い致します。

package test;

import java.util.List;

import model.GetMutterListLogic;
import model.Mutter;

public class Test{

    public static void main( String[] args ){
        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();

        for( Mutter mutter : mutterList ) {
            System.out.print( mutter.getUserName() + ":" );
            System.out.println( mutter.getText() );
        }

    }

}

/*
出力結果
接続...ok
rin:wanwanwan!!!
pun:wan!
*/

ここから実際のソースコード

// Main.java
GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );

        RequestDispatcher dispatcher = request.getRequestDispatcher( "/WEB-INF/jsp/main.jsp" );
        dispatcher.forward( request, response );
// GetMutterListLogic.java
package model;

import java.util.List;

import dao.MutterDAO;

public class GetMutterListLogic{
    public List< Mutter > execute(){
        MutterDAO dao = new MutterDAO();
        List< Mutter > mutterList = dao.findAll();
        return mutterList;
    }

}
// main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ page import="model.User, java.util.List, model.Mutter" %>

<%
    User loginUser = (User) request.getAttribute( "loginUser" );
    List< Mutter > mutterList = (List< Mutter >) request.getAttribute( "mutterList" );
    String errorMsg = (String) request.getAttribute( "errorMsg" );
%>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>つぶやくやつ</title>
</head>
<body>

<h3>メイン</h3>
<a href="/docoTsubu/Logout">ログアウト</a>
<p><a href="/docoTsubu/Main">更新</a></p>

<form action="/docoTsubu/Main" method="post">
    <input type="text" name="text"/>    
    <input type="submit" value="つぶやく"/>
</form>

<% if(mutterList != null){%>
        つぶやきはあります。
        <%= mutterList.size()%><% } else { %>
        <p>つぶやいてみよう!</p>
<% } %>


<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>

/********
出力結果

つぶやきはあります。 0 件 

******/

追記情報です。

package servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.GetMutterListLogic;
import model.Mutter;
import model.PostMutterLogic;
import model.User;

@WebServlet( "/Main" )
public class Main extends HttpServlet{
    private static final long serialVersionUID = 1L;

    protected void doGet( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException{

        // DBからつぶやきリストを取得→リクエストスコープに保存
        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );

        // ここでセッションIDをキーにインスタンスを取得
        HttpSession session = request.getSession();
        User loginUser = ( User ) session.getAttribute( "loginUser" );

        if( loginUser == null ) {
            response.sendRedirect( "/docoTsubu/" );
        } else {
            RequestDispatcher dispatcher = request.getRequestDispatcher( "/WEB-INF/jsp/main.jsp" );
            dispatcher.forward( request, response );
        }

    }

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

        String text = request.getParameter( "text" );

        if( text != null && text.length() != 0 ) {
            HttpSession session = request.getSession();
            User loginUser = ( User ) request.getAttribute( "loginUser" );

            Mutter mutter = new Mutter( loginUser.getName(), text );
            PostMutterLogic pm = new PostMutterLogic();
            pm.execute( mutter );

        } else {
            request.setAttribute( "errorMsg", "つぶやきが入力されていません" );
        }

        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );

        RequestDispatcher dispatcher = request.getRequestDispatcher( "/WEB-INF/jsp/main.jsp" );
        dispatcher.forward( request, response );

    }

}

コード

追記2

下記にデバッグ結果を書きます

protected void doGet( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException{

        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );
        // ↑ブレークポイント
    }
/* 
*    mutterList : ArrayList<E>
*       elementData : Object[0]
*       modCount : 0
*       size : 0
*
*/
package test;

import java.util.List;

import model.GetMutterListLogic;
import model.Mutter;

public class Test{

    public static void main( String[] args ){
        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterLista = gm.execute();

        for( Mutter mutter : mutterLista ) {
                 // ↑ブレークポイント
            System.out.print( mutter.getUserName() + ":" );
            System.out.println( mutter.getText() );
        }

    }

}

/*
*
*     mutterList
*       elementData : Object[10]
*       modCount : 2
*       size : 2
*
*/

こう見ると、そもそもサーブレットクラスのMain.javaで取得ができていないようですね、、。


追記3

DAOクラスのfindAll()までデバッグを行いました。

結果、Test.javaではfindAll()でDBからの情報を取得し、しっかりと返り値を返しています。しかし、Main.javaではfindAll()ではtry{}が全てスキップしており、finally{}のみ実行されていました。(コードは最後に書きます)

関係しているファイルは最初に記載した通りで、今回の流れではDBにSELECT文しか送っておらず、かなり簡単なもののはずですが、どこがおかしいのか、、、。

package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Mutter;

public class MutterDAO{
    private final String    DRIVER_NAME    = "com.mysql.jdbc.Driver";
    private final String    JDBC_URL    = "jdbc:mysql://localhost:8889/docoTsubu";
    private final String    DB_USER        = "○○○○○○○";
    private final String    DB_PASS        = "○○○○○○○";

    public List< Mutter > findAll(){
        Connection con = null;
        List< Mutter > mutterList = new ArrayList<>();

        try {
            Class.forName( DRIVER_NAME );
            con = DriverManager.getConnection( JDBC_URL, DB_USER, DB_PASS );

            // SQLの準備
            String sql = "SELECT id, name, text FROM mutter ORDER BY id DESC";
            PreparedStatement pstmt = con.prepareStatement( sql );
            ResultSet rs = pstmt.executeQuery();

            while( rs.next() ) {
                int id = rs.getInt( "id" );
                String userName = rs.getString( "name" );
                String text = rs.getString( "text" );
                Mutter mutter = new Mutter( id, userName, text );
                mutterList.add( mutter );
            }

        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
        } catch ( SQLException e ) {
            e.printStackTrace();
        } finally {
            if( con != null ) {
                try {
                    con.close();

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

        return mutterList;
    }

    public boolean create( Mutter mutter ){
        Connection con = null;
        try {
            con = DriverManager.getConnection( JDBC_URL, DB_USER, DB_PASS );

            String sql = "INSERT INTO mutter( name, text ) VALUES( ?, ? )";
            PreparedStatement pstmt = con.prepareStatement( sql );
            pstmt.setString( 1, mutter.getUserName() );
            pstmt.setString( 2, mutter.getText() );

            int result = pstmt.executeUpdate();

            if( result != 1 ) {
                return false;
            }

        } catch ( SQLException e ) {
            e.printStackTrace();
        } finally {
            if( con != null ) {
                try {
                    con.close();

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

        return true;
    }

}


追記4

Main.javaとTest.javaではDAOのfindAll()内の処理が異なるようです。
1 : Main.java、Test.javaはともにClass.forName( DRIVER_NAME );までは読み込む
2 : Main.javaはその後finally{}へ飛ぶ
3 : Test.javaは順調にcon = DriverManager.getConnection( JDBC_URL, DB_USER, DB_PASS );を読み込む
4 : 仮にClass.forName()でエラーを出していた場合、ClassNotFoundExceptionでエラーを捕捉していない

もはやソースコード上の問題なのか不明です。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • 退会済みユーザー

    退会済みユーザー

    2016/07/31 18:07

    asahida_devさん
    特に自動コミットモードをオフにしていないので、いまはONの状態だと思います!逆にこれはOFFにしてトランザクションを使った方が良いでしょうか??

    キャンセル

  • asahina_dev

    2016/07/31 20:05

    2件以上相関データを登録するなら OFF 推奨

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/08/01 14:09

    asahida_devさん ありがとうございます!
    今日ご指摘いただいたように修正し、再度トライしてみたいと思います。

    キャンセル

回答 4

check解決した方法

0

解決しましたー!

2つの方法を同時に試したのでどちらで解決したのか不明ですが、
1 : jdbcドライバを"mysql-connector-java-5.1.39"のままWEB-INFディレクトリのlibに置いていたのを、"mysql-connector-java-5.1.39-bin.jar"に変更
2 : 別のプロジェクトを作成している時に気付いたのですが、あるクラスをインスタンス化する際に、別プロジェクト配下の同一名のクラスを参照していたので、関係のないプロジェクトを全部閉じる

以上2点で解決しました!

みなさまご迷惑をおかけしました。本当にありがとうございます!
ベストアンサーはA-pZさんにしたいと思います!

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/08/03 18:41

    あれ、ベストアンサー選択できない、、

    キャンセル

0

しかし、②で情報は取得できているのかがわかりません。 

ServletでSystem.out.println()などを使って標準出力にDBから取得した内容を出力すると確認できると思います。Eclipseなどを使っていれば、デバッグ実行時にブレークポイントを設定することで確認したい変数の中身を確認できますよ。
さらに、DAOのfindAll()内でもデバッグできると思いますので、そちらの方が有効な情報がある可能性があります。
ご確認ください。

Servlet > JSPへの受け渡しは正しく記述できているように見えます。(未検証ですが)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/07/31 12:54

    ご回答ありがとうございます!
    DAOのfindAll()は単体テストで情報を取得できていることを確認しているので、DAO自体には問題はないかと思われます。

    『ServletでSystem.out.println()などを使って標準出力にDBから取得した内容を出力すると確認できると思います。Eclipseなどを使っていれば、デバッグ実行時にブレークポイントを設定することで確認したい変数の中身を確認できますよ。』についていまから検証を行いたいと思います。ありがとうございます!

    キャンセル

  • 2016/08/01 14:55

    サーブレット実行時、Exceptionは発生せず、突然finallyが実行されていますか?
    Exceptionが発生している場合、発生しているExceptionとスタックトレースを追記願います。

    また、A-pZさまの回答にもありますが、jdbcドライバのロードでこけている可能性が高いです。
    jdbcドライバはどこに配置し、どのようにクラスパスに設定していますか?
    webアプリケーションではWEB-INF/libに参照するライブラリを配備する必要があります。

    キャンセル

  • 2016/08/03 19:37

    takyahumiさん、申し訳ありません。いまスマホ表示で質問の追記をされていることに気が付きました。

    詳しくは自己解決欄に記してありますが、恐らくご指摘いただいたように、jdbcドライバの配置箇所がよくありませんでした。

    本当にご親切にありがとうございます。

    キャンセル

0

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

        String text = request.getParameter( "text" );

        if( text != null && text.length() != 0 ) {
            HttpSession session = request.getSession();
            User loginUser = ( User ) request.getAttribute( "loginUser" );

            Mutter mutter = new Mutter( loginUser.getName(), text );
            PostMutterLogic pm = new PostMutterLogic();
            pm.execute( mutter );

        } else {
            request.setAttribute( "errorMsg", "つぶやきが入力されていません" );
        }

        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );

        RequestDispatcher dispatcher = request.getRequestDispatcher( "/WEB-INF/jsp/main.jsp" );
        dispatcher.forward( request, response );

    }

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

        String text = request.getParameter( "text" );

        if( text != null && text.length() != 0 ) {
            HttpSession session = request.getSession();
            User loginUser = ( User ) session.getAttribute( "loginUser" );

            Mutter mutter = new Mutter( loginUser.getName(), text );
            PostMutterLogic pm = new PostMutterLogic();
            pm.execute( mutter );

        } else {
            request.setAttribute( "errorMsg", "つぶやきが入力されていません" );
        }

        GetMutterListLogic gm = new GetMutterListLogic();
        List< Mutter > mutterList = gm.execute();
        request.setAttribute( "mutterList", mutterList );

        RequestDispatcher dispatcher = request.getRequestDispatcher( "/WEB-INF/jsp/main.jsp" );
        dispatcher.forward( request, response );

    }

ではないのですか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/07/31 13:12

    ご指摘いただいた点、main.jspの方でも同様のミスをしていました、、。(笑)
    ありがとうございます!
    ただ、今回の問題とは関係のないようで、解決には至りませんでした。

    キャンセル

0

DAOで突然finallyへ遷移しているのであれば、jdbcドライバがWEB-INF/libに配置されていないため、スタックトレースが出でいるはずです。なお、DAOで発生した例外をe.printStackTrace()で出力するだけでは、処理を呼び出したクラスがエラーだったのかを判断できないため、エラーであるかを制御するようにしましょう。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/08/01 14:14

    A-pZさん、ご指摘ありがとうございます!

    Main.javaと同階層にあるTest.javaではDAOは問題なく処理されているのですが、これでも「jdbcドライバがWEB-INF/libに配置されていない」ということが原因とになるのでしょうか?

    ひとまず、ご指摘いただいた箇所を修正し、本日再トライをしてみたいと思います!
    ありがとうございます!

    キャンセル

  • 2016/08/02 14:42

    A-pZさん、お世話になります。
    ご指摘いただいたようにjdbcドライバをWEB-INF/libに配置してパスを通しましたが改善されませんでした。

    デバッグで調べていったところ、Test.javaではDAOのfindALL()のtry{ }は全て処理されていますが、Test.javaではDAOのfindALL()のtry{ }はClass.forName( DRIVER_NAME );の後、すぐにfinally{ }に飛ばされました。(Class.forName( DRIVER_NAME );をブレークポイントに設定)

    キャンセル

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

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