Struts2 выбрать сохранение тега и проблему с отзывом

Я запутался, пытаясь использовать тег struts2. Я следовал нескольким примерам, и все они, похоже, имеют один и тот же шаблон использования, но это не работает для меня (ниже приведен весь соответствующий код).

По сути, раскрывающийся список выбора struts2 позволяет мне отображать начальный список и сохранять значение, но не отображается правильно, когда я открываю страницу для редактирования объекта. После отображения страницы все выбранные значения отображают значение по умолчанию вместо ожидаемого значения. Если я изменю выбранное значение и снова сохраню страницу, оно правильно сохранит значение. Где-то тег неправильно устанавливает значение SELECTED списка опций. Я могу просмотреть правильное изменение, сохраняемое в базе данных, поэтому я знаю, что действие правильно получает объект.

Я считаю, что проблема лежит где-то в строке <s:select list="lifeInsuranceStatuses" name="domainObject.lifeInsuranceCoverages[%{#status.index}].lifeInsuranceStatus.oid" listKey="oid" listValue="status" theme="simple" /> JSP, но я могу ошибаться. Кажется, что все части этой страницы работают, за исключением установки правильного значения раскрывающегося списка при вызове объекта.

Где я ожидаю этого

public class MemberAction
    extends AbstractAction<Member>
{
    private static final long serialVersionUID = 1L;
    private Service<LifeInsuranceStatus> lifeInsuranceStatusService;

    // Code removed for brevity...

    public List<LifeInsuranceStatus> getLifeInsuranceStatuses()
    {
        return lifeInsuranceStatusService.getObjects().getResponse();
    }

    public Service<LifeInsuranceStatus> getLifeInsuranceStatusService()
    {
        return lifeInsuranceStatusService;
    }

    public void setLifeInsuranceStatusService(Service<LifeInsuranceStatus> lifeInsuranceStatusService)
    {
        this.lifeInsuranceStatusService = lifeInsuranceStatusService;
    }
}

Моя страница JSP выглядит следующим образом:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<s:form action="saveMember" method="post">
<table border="1">
    <tr>
        <td>
            <s:text name="domainObject.lifeInsuranceCoveragesn.lifeInsuranceStatus.status" />
        </td>
    </tr>
    <s:div id="LifeInsuranceCoverages" theme="simple">
        <s:iterator value="domainObject.lifeInsuranceCoverages" status="status">
            <tr class="lifeInsuranceCoverageRow<s:property value="%{#status.index}" />">
                <td>
                    <s:select list="lifeInsuranceStatuses" name="domainObject.lifeInsuranceCoverages[%{#status.index}].lifeInsuranceStatus.oid" listKey="oid" listValue="status" theme="simple" />
                </td>
            </tr>
        </s:iterator>
    </s:div>

    <tr id="addLifeInsuranceCoverageRow">
        <td>
            <a href="#" onClick="return LifeInsuranceCoverages.addRow()">Add Life Insurance Coverage...</a>
        </td>
    </tr>
</table>

<s:submit key="submit" />
</s:form>

И моя модель выглядит так:

public class Member
    extends Person
{
    private static final long serialVersionUID = 1L;

    private List<LifeInsuranceCoverage> lifeInsuranceCoverages;

    public List<LifeInsuranceCoverage> getLifeInsuranceCoverages()
    {
        if (lifeInsuranceCoverages == null)
        {
            lifeInsuranceCoverages = new ArrayList<LifeInsuranceCoverage>();
        }

        return lifeInsuranceCoverages;
    }

    public LifeInsuranceCoverage getActiveLifeInsuranceCoverage()
    {
        if (lifeInsuranceCoverages == null || lifeInsuranceCoverages.size() < 1)
        {
            return null;
        }
        else
        {
            return lifeInsuranceCoverages.get(lifeInsuranceCoverages.size() - 1);
        }
    }

    public void setLifeInsuranceCoverages(List<LifeInsuranceCoverage> lifeInsuranceCoverages)
    {
        this.lifeInsuranceCoverages = lifeInsuranceCoverages;

        for (LifeInsuranceCoverage lifeInsuranceCoverage : this.lifeInsuranceCoverages)
        {
            lifeInsuranceCoverage.setMember(this);
        }
    }

    public void addLifeInsuranceCoverage(LifeInsuranceCoverage lifeInsuranceCoverage)
    {
        lifeInsuranceCoverage.setMember(this);
        getLifeInsuranceCoverages().add(lifeInsuranceCoverage);
    }

    public void removeLifeInsuranceCoverage(LifeInsuranceCoverage lifeInsuranceCoverage)
    {
        getLifeInsuranceCoverages().remove(lifeInsuranceCoverage);
        lifeInsuranceCoverage.setMember(null);
    }
}

... а также ...

public class LifeInsuranceCoverage
    extends AbstractDomainObject
{
    private static final long serialVersionUID = 1L;
    private Member member;
    private LifeInsuranceStatus lifeInsuranceStatus;

    public LifeInsuranceStatus getLifeInsuranceStatus()
    {
        return lifeInsuranceStatus;
    }

    public void setLifeInsuranceStatus(LifeInsuranceStatus lifeInsuranceStatus)
    {
        this.lifeInsuranceStatus = lifeInsuranceStatus;
    } 

    public Member getMember()
    {
        return member;
    }

    public void setMember(Member member)
    {
        this.member = member;
    }
}

... а также ...

public class LifeInsuranceStatus
    extends AbstractDomainObject
{
    private static final long serialVersionUID = 1L;
    private String status;

    public String getStatus()
    {
        return status;
    }

    public void setStatus(String status)
    {
        this.status = status;
    }
}

... а также ...

public abstract class AbstractDomainObject
    implements DomainObject
{
    private static final long serialVersionUID = 1L;
    private Long oid;

    public Long getOid()
    {
        return oid;
    }

    public void setOid(Long oid)
    {
        this.oid = oid;
    }
}

person Jon    schedule 14.04.2011    source источник


Ответы (1)


Я смог выяснить эту проблему после некоторых проб и ошибок. Решение, которое я нашел, не имеет для меня смысла, но оно работает независимо.

Чтобы исправить это, мне пришлось сделать две вещи. Во-первых, я добавил метод toString() в класс LifeInsuranceStatus, который возвращал только значение status. Затем я удалил часть listKey тега struts2. Как только я сделал эти две вещи вместе, значение, которое я сохранил в базе данных, было правильно вызвано и сохранено должным образом.

Я хотел бы знать, почему это сработало именно так. Кто-нибудь лучше разбирается в тегах struts2 или почему другой выпадающий список, в котором использовалось перечисление, отлично работал без удаления части тега listKey...

person Jon    schedule 15.04.2011
comment
Из: struts.apache.org/2.1.6/docs/select.html: Примечание. Для любого из тегов, использующих списки (выберите, вероятно, наиболее распространенный), который использует нотацию списка OGNL, следует отметить, что созданный ключ сопоставления (в примере месяцев '01', '02' и т. д.). «1» — это символ, «01» — это строка, 1 — это строка. Это важно, поскольку, если значение, возвращаемое вашим атрибутом значения, НЕ того же типа, что и ключ в атрибуте списка, они НЕ СООТВЕТСТВУЮТ, даже если их строковые значения могут быть эквивалентны. Если они не совпадают, ничего в вашем списке не будет выбрано автоматически. - person Nate; 20.04.2011