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

#java #select #struts2 #jsp-tags

#java #выберите #struts2 #jsp-теги

Вопрос:

Я запутался, пытаясь использовать тег 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;
    }
}
  

Ответ №1:

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

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

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

Комментарии:

1. Откуда: struts.apache.org/2.1.6/docs/select.html : Примечание: Для любого из тегов, использующих списки (select, вероятно, является наиболее распространенным), который использует нотацию списка OGNL, следует отметить, что созданный ключ map (например, в месяцах ’01’, ’02’ и т.д.) вводится. ‘1’ — это символ, ’01’ — это строка, «1» — это строка. Это важно, поскольку, если значение, возвращаемое вашим атрибутом «value», ОТЛИЧАЕТСЯ от типа ключа в атрибуте «list», они НЕ БУДУТ СОВПАДАТЬ, даже если их строковые значения могут быть эквивалентны. Если они не совпадают, ничто в вашем списке не будет выбрано автоматически.