1

私は非常に単純なユーザー設定フォームを持っています:

<form:form method="post" id="fm1" cssClass="fm-v clearfix" commandName="${commandName}" htmlEscape="true">
  <div class="row fl-controls-left">
    <spring:message code="screen.userSettings.label.timeZone.accesskey" var="timeZoneAccessKey" />
    <label for="timeZone" class="fl-label"><spring:message code="screen.userSettings.label.timeZone" /></label>
    <form:select id="timeZone" path="timeZone" accesskey="${timeZoneAccessKey}">
      <form:options items="${user.supportedTimeZones}" itemLabel="label" itemValue="id" />
    </form:select>

    <c:forEach items="${user.answers}" var="answer" varStatus="loop">
      <div class="row fl-controls-left">
        <form:select path="answers[${loop.index}].questionId">
          <option value="-1"><spring:message code="screen.userSettings.question.selectOne" /></option>
          <form:options items="${user.supportedQuestions}" itemLabel="question" itemValue="id" />
        </form:select>
        <form:input path="answers[${loop.index}].answer" size="30" autocomplete="false" htmlEscape="true" type="text" cssClass="required" cssErrorClass="error"/>
      </div>
    </c:forEach>
  </div>
</form:form>

基本的に、タイムゾーンを設定し、パスワードを忘れた場合の質問のリストに回答を提供できます。このフォームにバインドされたモデル オブジェクトは基本的に次のとおりです。

public class User implements Serializable {
    private static final long serialVersionUID = 8974875234954842283L;

    private List<Answer> answers;
    private List<Question> supportedQuestions;
    private List<TimeZone> supportedTimeZones;
    private String timeZone;

    public User() {
        credentials = new UsernamePasswordCredentials();
    }

    public List<Answer> getAnswers() {
        return answers;
    }

    public List<Question> getSupportedQuestions() {
        return supportedQuestions;
    }

    public List<TimeZone> getSupportedTimeZones() {
        return supportedTimeZones;
    }

    public String getTimeZone() {
        return timeZone;
    }

    public void setAnswers( List<Answer> answers ) {
        this.answers = answers;
    }

    public void setSupportedQuestions( List<Question> supportedQuestions ) {
        this.supportedQuestions = supportedQuestions;
    }

    public void setSupportedTimeZones( List<TimeZone> supportedTimeZones ) {
        this.supportedTimeZones = supportedTimeZones;
    }

    public void setTimeZone( String timeZone ) {
        this.timeZone = timeZone;
    }

    ...
}

フォームは問題なく表示されます。サポートされているすべてのタイムゾーンを表示する単一のドロップダウンに続いて、サポートされているすべての質問を含むドロップダウンである質問と回答のペアのいくつかの行が表示されます。List<Answer> answersフォームを送信すると、フォームの値で が更新されないため、処理が失敗します。私の質問は 2 つあります。まず、私は何を間違えましたか? 次に、この種のマッピングの問題を今後どのようにデバッグすればよいでしょうか?

デバッガーでコードをステップ実行してみました。メソッドはフォームからのsetTimeZone()値で呼び出されていますが、setAnswers()メソッドはそうではありません。クラスのsetQuestionId()またはsetAnswer()メソッドでもありません。オブジェクトAnswerを調べたところ、すべてのパラメーターとパラメーターのキーがありますが、値が何であるかわかりません。この種の問題を追跡するために何をすることをお勧めしますか?Requestanswer[x].questionIdanswer[x].answer

- - - - - - - - - - - - - アップデート - - - - - - - - - - - - ----------

デバッガーからこれを取得しました:

map[
'answers[4].questionId' -> 'cn=honeymoon,ou=questions,dc=company'
'answers[2].questionId' -> 'cn=honeymoon,ou=questions,dc=company'
'answers[0].questionId' -> 'cn=firstPet,ou=questions,dc=company'
'lt' -> 'LT-786e9b77-efbd-f302-062e-90364cc4634aZe1s2'
'answers[1].answer' -> 'qwer'
'answers[3].answer' -> 'poiu'
'submit' -> 'Save'
'answers[3].questionId' -> 'cn=honeymoon,ou=questions,dc=company'
'answers[1].questionId' -> 'cn=mothersMaiden,ou=questions,dc=company'
'answers[2].answer' -> 'zxcv'
'answers[4].answer' -> 'lkjh'
'timeZone' -> 'America/New_York'
'_eventId' -> 'submit'
'answers[0].answer' -> 'asdf'
]

requestParameterMap に含まれるものです。(とanswersの両方)に対して値が返されたことは明らかです。spring がモデル オブジェクトを呼び出さないのはなぜですか(それが呼び出されていることを思い出してください)。questionIdanswersetAnswers()setTimeZone()

4

1 に答える 1

1

これは、viewState のバインダーに問題があることが判明しました。これはうまくいくはずです:

<binder>
  <binding property="answers" />
  <binding property="timeZone" />
</binder>

answersバインドされたモデル オブジェクトのプロパティであるためです。ただし、実際にはリスト内の要素の属性を指定する必要があります。

<binder>
  <binding property="answers[0].questionId" />
  <binding property="answers[0].answer" />
  <binding property="answers[1].questionId" />
  <binding property="answers[1].answer" />
  <binding property="answers[2].questionId" />
  <binding property="answers[2].answer" />
  <binding property="answers[3].questionId" />
  <binding property="answers[3].answer" />
  <binding property="answers[4].questionId" />
  <binding property="answers[4].answer" />
  <binding property="timeZone" />
</binder>

私にとっては、要素のサイズが固定されているため、これは(今のところ)機能します。リスト内のすべての要素のすべてのプロパティを含める必要があるのは少し面倒ですが、機能します。これを簡単にするバグ/機能リクエストが提出されていますが、それまでは...

于 2012-04-26T22:13:39.543 に答える