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

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

ただいまの
回答率

89.12%

受け取ったデータが何故かjstlでキャストされず文字列になってしまう

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 655

m.aqua

score 6

前提・実現したいこと

プログラミング初心者です。
Javaで試験申し込み用のアプリケーションを制作しているのですが、申込者一覧を取得時にエラーが出ました。
希望していた結果を表示する方法は一応あり、jstlを使用しない事で望んでいた通りの表示をすることが可能でした。
が、なぜこのようなエラーが起きたのかの根本的な原因の特定が出来ず、このまま放置していては学んでいる意味が無いと思うのでどなたか詳しい方にアドバイスをいただきたいです。

発生している問題・エラーメッセージ

原因
javax.el.PropertyNotFoundException: Property [code] not found on type [java.lang.String]
javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:260)
javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:212)
javax.el.BeanELResolver.property(BeanELResolver.java:347)
javax.el.BeanELResolver.getValue(BeanELResolver.java:92)
org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:110)
org.apache.el.parser.AstValue.getValue(AstValue.java:169)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:944)
org.apache.jsp.WEB_002dINF.jsp.subscribeList_jsp._jspx_meth_c_005fout_005f0(subscribeList_jsp.java:226)
org.apache.jsp.WEB_002dINF.jsp.subscribeList_jsp._jspx_meth_c_005fforEach_005f0(subscribeList_jsp.java:188)
org.apache.jsp.WEB_002dINF.jsp.subscribeList_jsp._jspService(subscribeList_jsp.java:139)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
servlet.SubscribeList.doGet(SubscribeList.java:56)
javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
filter.EncodingFilter.doFilter(EncodingFilter.java:40)

該当のソースコード

package model;

import java.io.Serializable;

public class Subscribe implements Serializable {
    /* 申込者データ*/
    private String id;
    private int code;
    private String number;
    private String name;
    private String address;
    private String birth;
    private String gender;
    private String kana;
    private int year;
    private int count;
    private String testClass;
    private String testName;

    public Subscribe() {}

    /* テーブル結合用 */
    public Subscribe(String id, int code) {
        this.id = id;
        this.code = code;
    }

    public Subscribe(int count, int year) {
        super();
        this.year = year;
        this.count = count;
    }

    /* 申し込み申請時に使用 idは申込者が誰かの判定に必要な為追加 */
    public Subscribe(String id, int code, String number) {
        this.id = id;
        this.code = code;
        this.number = number;
    }

    /* 申請者一覧取得時に使用 genderは念の為にString型へ変更 */
    public Subscribe(String id, int code, String number, String name, String address, String birth, String gender,
            String kana, int year, int count, String testClass, String testName) {
        this.id = id;
        this.code = code;
        this.number = number;
        this.name = name;
        this.address = address;
        this.birth = birth;
        this.gender = gender;
        this.kana = kana;
        this.year = year;
        this.count = count;
        this.testClass = testClass;
        this.testName = testName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBirth() {
        return birth;
    }

    public void setBirth(String birth) {
        this.birth = birth;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getKana() {
        return kana;
    }

    public void setKana(String kana) {
        this.kana = kana;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getTestClass() {
        return testClass;
    }

    public void setTestClass(String testClass) {
        this.testClass = testClass;
    }

    public String getTestName() {
        return testName;
    }

    public void setTestName(String testName) {
        this.testName = testName;
    }



}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model.*,java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>応募者一覧</title>
</head>
<body>
<h1>応募者一覧</h1>
<table>
<c:forEach var="subscribe" items=" ${subscribeList }" >
    <tr><td>
    <c:out value="${subscribe.code }"/>
    </td></tr>
</c:forEach>
</table>
<p><a href="/SubscribeCertify/Manage">管理者トップへ</a></p>
<p><a href="/SubscribeCertify/Logout">ログアウト</a><p>
</body>
</html>
package dao;

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

import model.Subscribe;

public class SubscribeListDAO extends SubscribeCertifyDAO{

    public List<Subscribe> findAll(){
        List<Subscribe> subscribeList = new ArrayList<>();

        try {
            getConnection();

            String sql = "SELECT subscribe.id, subscribe.code, subscribe.number, user.name, user.address, user.birth, user.gender, user.kana, "
                    + "testData.year, testData.count, testData.testClass, testData.testName "
                    + "FROM user INNER JOIN subscribe USING(id) "
                    + "INNER JOIN testData USING(code) "
                    + "ORDER BY number DESC";

            PreparedStatement pstmt = conn.prepareStatement(sql);

            ResultSet rs = pstmt.executeQuery();

            while(rs.next()) {
                String id = rs.getString("subscribe.id");
                int code = rs.getInt("subscribe.code");
                String number = rs.getString("subscribe.number");
                String name = rs.getString("user.name");
                String address = rs.getString("user.address");
                String birth = rs.getString("user.birth");
                String kana = rs.getString("user.kana");
                String gender = rs.getString("user.gender");
                int year = rs.getInt("testData.year");
                int count = rs.getInt("testData.count");
                String testClass = rs.getString("testData.testClass");
                String testName = rs.getString("testData.testName");
                Subscribe subscribes = new Subscribe(id, code, number, name, address, birth, kana, gender, year, count, testClass, testName);

                subscribeList.add(subscribes);
            }
        }catch(SQLException e){
            e.printStackTrace();
            return null;
        }catch(ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }finally {
            closeConnection();
        }
        return subscribeList;
    }
}
package model;

import java.util.List;

import dao.SubscribeListDAO;


public class GetSubscribeListLogic {
    public List<Subscribe> execute(){
        SubscribeListDAO dao = new SubscribeListDAO();
        List<Subscribe> subscribeList = dao.findAll();
        return subscribeList;
    }


}
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.GetSubscribeListLogic;
import model.Subscribe;
import model.User;
/**
 * Servlet implementation class SubscribeList
 */
@WebServlet("/SubscribeList")
public class SubscribeList extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        GetSubscribeListLogic getSubscribeList = new GetSubscribeListLogic();
        List<Subscribe> subscribeList = getSubscribeList.execute();
        request.setAttribute("subscribeList", subscribeList);


        request.setCharacterEncoding("UTF-8");
        HttpSession session = request.getSession();
        User loginUser = (User) session.getAttribute("loginUser");

        if(loginUser == null) {
            response.sendRedirect("/SubscribeCertify/");
        }else {
            String pageStr = request.getParameter("page");
            Integer page;
            if(pageStr == null || pageStr.equals("")) {
                page = 1;
            }else {
                page = Integer.parseInt(pageStr);
            }
//            session.setAttribute("subscribeList", subscribeList);
            request.setAttribute("page", page);
            RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/jsp/subscribeList.jsp");
//            request.getRequestDispatcher("/WEB-INF/jsp/subscribeList.jsp");
            rd.forward(request, response);
        }
    }

}

試したこと

デバッグモードやjsp側で呼び出したsubsclibeListの中身を確認してみた所、jspに渡るまではしっかりと中身が入っていたのですが
いざjsp側で表示をすると、なぜかキャストされずに全て文字列として表示されてしまっていました。

試しに、jstlを使わず<%%>等の手間がかかる方で表示をしてみると今度はちゃんとsubsclibeListの中身が表示され、望んだ形での表示が可能になりました。

補足情報(FW/ツールのバージョンなど)

eclipse Version: 2019-03 (4.11.0)
MySQL 8.0.16
Java11 

よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+2

EL式で使われている変数(${subscribeList })はpageContextオブジェクトなので、
jspでスクリプトレット(<%%>)の変数をpageContextオブジェクトに登録する必要があります。

<c:set var="hoge " value="<%= subscribeList %>" />
<c:forEach var="subscribe" items=" ${hoge}" >
・・・

もしくは下記でも可能なはずです。

<% pageContext.setAttribute("fuga",subscribeList); %> 
<c:forEach var="subscribe" items=" ${fuga }" >
・・・

EL式についての詳しい解説はこちらを参照してください。
http://pgbox.grush.jp/ref/java/jee/jsp/el.html

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/25 23:56

    回答ありがとうございます。
    EL式や暗黙オブジェクトについて、うろ覚えな部分が多いので改めてしっかり読ませていただいています。
    回答いただいた通りに編集し、実行してみましたがエラーの内容に変化はありませんでした。
    下記に変更したjspを記載させていただきます。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="model.*,java.util.*"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%
    List<Subscribe> subscribeList = (List<Subscribe>)request.getAttribute("subscribeList");
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>応募者一覧</title>
    </head>
    <body>
    <h1>応募者一覧</h1>
    <table>
    <% pageContext.setAttribute("subscribeList",subscribeList); %>
    <c:forEach var="subscribe" items=" ${subscribeList }" >
    <tr><td>
    <c:out value="${subscribe.code }"/>
    </td></tr>
    </c:forEach>
    </table>
    <p><a href="/SubscribeCertify/Manage">管理者トップへ</a></p>
    <p><a href="/SubscribeCertify/Logout">ログアウト</a><p>
    </body>
    </html>

    変更の仕方はこの形であっているかと思うのですが、どこか抜けや間違いなどありますでしょうか?

    キャンセル

+1

Subscribeクラスのコードがないので予想ですが、Subscribeのフィールドに対して、アクセサメソッド(いわゆるgetメソッド)がないため、JSTLからフィールドを出力できません。例えば、Subscribeのcodeに対して、

public int getCode() {
  return code;
}


が必要です。

余談ですが、JSTLやEL式では、サーブレットスコープを省略するとJSPのpageContext→リクエスト属性→セッション属性→アプリケーション属性(サーブレットコンテキスト属性)と順番に自動検索します。
例えばJSPの<c:set>で一時的に変数へ格納したオブジェクトに対して別のタグで扱う場合でも、特にスコープは指定する必要ありません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/25 23:42

    回答有り難うございます。
    Subscribeサーブレットについてですが、編集して追加させていただきました。
    また、いわゆるgetメソッドについては一応記述の方はしてありました。
    自動検索の流れ等、まだ知らない事でしたので勉強になります、ありがとうございます。

    キャンセル

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

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