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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Struts

StrutsはJava向けのWebアプリケーションフレームです。MVCモデルに基づいており、JSPやJavaサーブレットを組み合わせ、アプリケーション構築時に使用する各機能を提供しています。

Seasar2

Seasar2はJ2EE/Java EEでの大規模な開発を効率良く行なうためのフレームワークです。 必要な設定ファイルを従来のものと比べて少なくし、依存性を分離して記述しています。 そのため、生産性の高いプログラム開発が可能です。

Q&A

解決済

1回答

16727閲覧

JSPで表示した明細部をActionFormのListにセットしたい

chida3

総合スコア15

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Struts

StrutsはJava向けのWebアプリケーションフレームです。MVCモデルに基づいており、JSPやJavaサーブレットを組み合わせ、アプリケーション構築時に使用する各機能を提供しています。

Seasar2

Seasar2はJ2EE/Java EEでの大規模な開発を効率良く行なうためのフレームワークです。 必要な設定ファイルを従来のものと比べて少なくし、依存性を分離して記述しています。 そのため、生産性の高いプログラム開発が可能です。

0グッド

1クリップ

投稿2017/05/21 12:51

編集2017/06/04 02:34

###前提・実現したいこと
自主勉強の一環で、SAStrutsによるWebアプリ開発をしています。

下記のようなことをやろうとしています。
①ActionFormにListを持たせて、その要素をJSPで一覧として表示。
②明細の各項目の値を変更してsubmit、ActionFormのListから値を取り出して処理。

###発生している問題・エラーメッセージ
①まではできたのですが、
②において、ActionFormのListにアクセスしようとしたとき、NullPointerExceptionが発生します。
どのようにしたら、Listに明細をセットできるのでしょうか……。

###該当のソースコード
■InputForm.java

Java

1public class InputForm { 2 3 //明細部 4 private List<Detail> detailList; 5 6 public List<Detail> getDetailList() { 7 return detailList; 8 } 9 public void setDetailList(List<Detail> detailList) { 10 this.detailList = detailList; 11 } 12 public Detail getDetail(int index) { 13 return getDetailList().get(index); 14 } 15 public void setDetail(Detail detail) { 16 detailList.add(detail); 17 } 18 19 //明細行のDTO 20 public class Detail { 21 private int index; 22 private String str; 23 24 public int getIndex() { 25 return index; 26 } 27 public void setIndex(int index) { 28 this.index = index; 29 } 30 public String getStr() { 31 return str; 32 } 33 public void setStr(String str) { 34 this.str = str; 35 } 36 } 37 38}

■InputAction.java

Java

1public class InputAction { 2 3 @Resource 4 @ActionForm 5 protected InputForm inputForm; 6 7 @Execute(validator=false) 8 public String input() { 9 List<Detail> detailList = new ArrayList<>(); 10 for (int i = 0; i < 7; i++) { 11 Detail detail = inputForm.new Detail(); 12 detail.setIndex(i); 13 detail.setStr("STR"); 14 detailList.add(detail); 15 } 16 inputForm.setDetailList(detailList); 17 18 return "input.jsp"; 19 } 20 21 @Execute(validator=false) 22 public String exec() { 23 //↓ここでNullPointerException 24 inputForm.getDetailList().get(0); 25 26 return "input.jsp"; 27 } 28}

■input.jsp

<%@page pageEncoding="UTF-8"%> <html> <body> <s:form method="get"> <s:submit property="exec" value="submit"/> <table> <tr> <td>No.</td> <td>str</td> </tr> <c:forEach var="detail" items="${inputForm.detailList}"> <tr> <td> <html:text name="detail" property="index" indexed="true"/> </td> <td> <html:text name="detail" property="str" indexed="true"/> </td> </tr> </c:forEach> </table> </s:form> </body> </html>

###参考にしたもの
下記サイトを一部参考にしたのですが、理解できなかったところもあり、反映し切れていません。どうぞご教示おねがいいたします。
http://www.civic-apps.com/2006/06/09/struts-using-list/
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=32607&forum=12

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

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

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

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

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

guest

回答1

0

自己解決

時間がかかってしまいましたが、解決しました。

##修正後のソース

■InputForm.java

java

1public class InputForm { 2 public String classCd; 3 public String categoryCd; 4 public String segmentCd; 5 public String seasonCd; 6 7 //↓setter、getterは不要 8 public List<Detail> detailList; 9}

■input.jsp

<%@page pageEncoding="UTF-8"%> <html> <body> <s:form method="get"> <s:submit property="exec" value="submit"/> <table> <tr> <td>No.</td> <td>str</td> </tr> <c:forEach var="detailList" items="${detailList}"> <tr> <td> <html:text name="detailList" property="index" indexed="true"/> </td> <td> <html:text name="detailList" property="str" indexed="true"/> </td> </tr> </c:forEach> </table> </s:form> </body> </html>

上記に加え、明細部のDtoを作成しました。
■Detail.java

java

1public class Detail { 2 public int index; 3 public String str; 4}

※ActionFormの変更、Dtoの追加にともない、Actionでのインスタンス生成等の箇所を修正しています。

##ポイント
フレームワークの動きについては、S2RequestProcessor.javaを読みました。
以下、括弧内の数字は、リンク先のソースの行数です。

1)Listのsetter、getterは不要
どうやらSAStrutsでは、フレームワークにおいて、リクエストパラメータをActionFormにセットする際、FormのメンバのListがnullだったらインスタンスを生成してくれるようです。(L580)
当初参考にしていたサイトは前身のStrutsを対象としたものだったので、同様に必要なのかと思っていましたが、違っていました。

2)jspでvarに指定する値をListの名前と合わせる
今回の場合は、「detailList」です。
var=detailListとすると、リクエストパラメータのkeyは「detailList[0]」のようになります。
フレームワークにて、ActionFormのプロパティに値をセットする際、セットすべきプロパティをリクエストパラメータのkeyの文字列で決めているようです。(L412-413)
修正前はdetailとしていたため、セットすべきプロパティが見つからず、NullPointerExceptionが発生していました。

3)内部クラスではなく、Dtoとして別クラスにするか、static修飾子をつける
1と2の修正をおこなったあと、以下のようなエラーが発生しました。

HTTPステータス 500 - [ESSR0059]クラス(hoge.form.InputForm)のプロパティ(detailList[2].index)の設定に失敗しました。理由はorg.seasar.framework.exception.InstantiationRuntimeException: [ESSR0041]hoge.form.InputForm$Detailの作成に失敗しました。理由はjava.lang.InstantiationException: hoge.form.InputForm$Detail

フレームワーク側で、Listの要素に持つクラスのインスタンス生成をおこなう箇所がありますが、Detailが内部クラスだったために、newInstanceでエラーが発生していたようです。(L585)

##参考
↓まずこちらを見てなんとなくの対処法がわかりました。
リンク内容

↓フレームワークの内部動作については、ソースそのものを読んでようやく理解。
[sastruts]/trunk/sa-struts/src/main/java/org/seasar/struts/action/S2RequestProcessor.java
リンク内容

フレームワークのソース解析に関しては若干自信ないので、間違っていたらご指摘いただければ幸いです。

投稿2017/05/28 11:06

chida3

総合スコア15

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問