【Struts2】サーバからのデータが画面に表示されない件について

Struts2

あまりに初歩的なミスをしたので戒めのために公開したいと思います。

結論: 画面にDBのデータが表示されない原因

やりたいことはDBから取り出したデータをJSPで画面に表示ことです。以下のコードを見て下さい。
結論としてはメソッドの中で todoItemList をローカル変数として定義していました。ご存知の通り、インスタンス変数と同名のメソッドをローカル変数として定義した場合は、ローカル変数の方が使用され、これはメソッド終了時に解放されるわけです。ですので、当然JSPからの(これはサーブレットに置き換えられますが)呼び出しに nullが格納された todoItemList にアクセスしているので当然画面に表示されません。

public class TodoAction extends ActionSupport {
    @Autowired
    private TodoItemDAO todoItemDAO;
    private List<TodoItemDTO> todoItemList;

    public String execute() throws Exception {
        List<TodoItemDTO> todoItemList = todoItemDAO.getAllTodoItems();
        return SUCCESS;
    }
    public List<TodoItemDTO> getTodoItemList() {
        return todoItemList;
    }

だから、インスタンス変数にするために先頭の型を削除します。

public String execute() throws Exception {
        //インスタンス変数を使用する(先頭の型を削除する)
        todoItemList = todoItemDAO.getAllTodoItems();
        return SUCCESS;
    }

詳細: うまくいかなかったコード振り返る

コードの内容としてはDAOのメソッドでDBからデータを取り出して、それをDTOに格納して呼び出したActionのフィールドを通して、jspで受け取り画面に表示するという処理を書きました。

Action.java は以下の通りです。いろいろDBに接続するための設定を試していたので、コメントアウトとかが多くなってますがそれを含めてご参照下さい。

package jp.co.example.action;

import com.opensymphony.xwork2.ActionSupport;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import jp.co.example.dao.TodoItemDAO;
import jp.co.example.dto.TodoItemDTO;

@Controller
public class TodoAction extends ActionSupport {

    @Autowired
    private TodoItemDAO todoItemDAO;

    private TodoItemDTO todoItem;
    private List<TodoItemDTO> todoItemList;

    public String execute() throws Exception {
//        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//        TodoItemDAO dao = (TodoItemDAO)ctx.getBean("todoItemDAO");

        TodoItemDTO todoItem = todoItemDAO.getRowTodoItems();
        List<TodoItemDTO> todoItemList = todoItemDAO.getAllTodoItems();

//        System.out.print("itemid: " + dto.get(0).getItemid());
//        System.out.print("userid: " + dto.get(0).getUserid());

//        DbUtils.loadDriver(JDBC_DRIVER);
//        QueryRunner run = new QueryRunner(CustomDataSource.getInstance());
//        ResultSetHandler<TodoItemDTO> resultHandler = new BeanHandler<TodoItemDTO>(TodoItemDTO.class);
//
//        TodoItemDTO dto = run.query("SELECT * FROM todoitem WHERE itemid=?",
//           resultHandler, 1);

        //Display values
        System.out.print("itemid: " + todoItemList.get(0).getItemid());
        System.out.print("userid: " + todoItemList.get(0).getUserid());
        return SUCCESS;
    }
    public TodoItemDTO getTodoItem() {
        return todoItem;
    }
    public List<TodoItemDTO> getTodoItemList() {
        return todoItemList;
    }
}

jspのコードは以下です。確認するポイントは value に設定する値です。設定する値が間違っていないか、スペルミスがないかを確認しました。

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
  <title>todo</title>
  <link href="<s:url value='/styles/todo.css'/>" rel="stylesheet" type="text/css" media="all"/>
  <s:head />
</head>
<body>
  <h1>Todo Items</h1>
  <table border="1">
    <thead>
      <tr>
        <th>タスク</th>
        <th>作成日</th>
        <th>期限</th>
        <th>完了</th>
      </tr>
    </thead>
    <tbody>
      <s:iterator value="todoItemList">
        <tr>
          <td><s:property value="title" /></td>
          <td><s:property value="created_date" /></td>
          <td><s:property value="limited_date" /></td>
          <td><s:property value="done" /></td>
        </tr>
      </s:iterator>
    </tbody>
  </table>
</body>
</html>

まとめ

原因は冒頭に述べた通りですが、いろいろ試しすぎてコメントの部分が多くなり、本来のコードが埋もれてインスタンス変数と同名の変数をローカル変数で再定義していることに気づきにくかったことが原因のような気もしました。不要なコメントは削除するのが良いですが、いろいろ切り替えたい場合などありますので気をつけなければと。。反省です。

タイトルとURLをコピーしました