调试Spring MVC集合绑定 [英] Debugging Spring MVC collection binding

查看:118
本文介绍了调试Spring MVC集合绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的用户设置表单:

I have a pretty simple user settings form:

<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>

基本上,您可以设置时区,并提供列表答案忘记的密码问题。绑定到此表单的模型对象基本上是这样的:

Basically, you can set your timezone, and provide answers to a list forgotten password questions. The model object bound to this form is basically this:

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>答案没有更新与表单中的值。我的问题是两个折,首先,我做错了什么?第二,我应该如何在将来调试这种类型的映射问题?

The form displays just fine. It provides a single drop down showing all supported timezones followed by few rows of question/answer pairs with the questions being drop downs containing all of the supported questions. When I submit the form back, processing fails because the List<Answer> answers is not getting updated with the values from the form. My question is two fold, first, what did I do wrong? Second, how should I approach debugging this type of mapping problem in the future?

我已经尝试用调试器逐步执行代码。 setTimeZone()方法正在从表单的值调用,但 setAnswers()方法不是。 setQuestionId() setAnswer() $ c> class。我查看了请求对象,它有所有 answer [x] .questionId answer [x] .answer 参数,但不确定值是什么。您会建议如何追踪这类问题?

I have tried stepping through the code with the debugger. The setTimeZone() method is getting called with the value from the form, but the setAnswers() method is not. Nor are the setQuestionId() or setAnswer() methods of the Answer class. I looked at the Request object and it has keys for all the answer[x].questionId and answer[x].answer parameters, but not sure what the values are. What would you recommend doing to track down this type of issue?

---------------------- ---- UPDATE --------------------------------

-------------------------- UPDATE --------------------------------

我刚刚从调试器中取出这个:

I just pulled this from the debugger:

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中包含的内容。显然,它显示为 answer 返回的值( questionId answer )。为什么spring不会在模型对象上调用 setAnswers()(记住 setTimeZone()

It is what is contained in the requestParameterMap. Clearly it shows that values were returned for answers (both questionId and answer). Why is spring not calling setAnswers() on the model object (remember that setTimeZone() is getting called)?

推荐答案

这是在viewState中的binder的一个问题。它似乎应该工作:

This turns out to be an issue with the binder in the viewState. It seems like this should work:

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

因为答案模型对象。然而,我实际上必须指定列表中的元素的属性:

because answers is the property of the bound model object. However, I actually have to specify the attributes of the elements within the list:

<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>

对于我来说,这将工作(现在),因为我有固定大小的元素。它有点痛苦,必须包括列表中每个元素的每个属性,但它的工作原理。为此而提交的错误/功能请求应该会更容易,但在此之前。 ..

For me this will work (for now) as I have a fixed size number of elements. Its a little painful to have to include every property of every element in the list, but it works. There are bugs/feature requests filed for this that should make it easier, but until then...

这篇关于调试Spring MVC集合绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆