Получить значения вложенного списка из JSP и отправить его обратно в форму - PullRequest
1 голос
/ 21 марта 2019

РЕДАКТИРОВАТЬ Теперь я знаю, что моя проблема связана с этим . Ссылка также предоставила решения, но я не могу понять, как это сделать во 2-м списке.

Сначала я покажу вам структуру кода, над которой я работаю.

Вот класс MyForm:

public class MyForm extends ValidatorForm {
    private List<ADTO> aDTOList;

    // getters and setters for aDTOList below

    public ADTO getADTO(int index) {
        if (aDTOList == null) {
            aDTOList = new ArrayList<ADTO>();
        }
        if (aDTOList.size() - 1 < index) {
            while (aDTOList.size() - 1 < index) {
                aDTOList.add(new ADTO());
            }
        }
        return aDTOList.get(index);
    }

    @Override
    protected ActionErrors execValidate(ActionMapping mapping, HttpServletRequest request) {
          // BODY NOT SHOWN FOR PRIVACY
    }

    @Override
    public void reset(ActionMapping mapping, HttpServletRequest request) { 
        super.reset(mapping, request);
        this.aDTOList = new ArrayList<ADTO>();
    }


}

Вот класс ADTO:

public class ADTO {
    private List<BDTO> bDTOList;
    // getters and setters for bDTOList below

}

Вот класс BDTO:

public class BDTO {
    private String sample1;
    private String sample2;
    // getters and setters for sample1 and sample2 below

}

Я успешно отобразил содержимое aDTOList в JSP, выполнив следующее:

<logic:iterate id="ADTO" name="MyForm" property="aDTOList" indexId="idxRes">
    <logic:iterate id="BDTO" name="ADTO" property="bDTOList" indexId="idxLine">
        <html:hidden name="BDTO" property="sample1" indexed="true"/>
        <html:hidden name="BDTO" property="sample2" indexed="true"/>
    </logic:iterate>
</logic:iterate>

Теперь моя проблема заключается в том, что всякий раз, когда я отправляю форму bDTOList, которая находится внутри aDTOList, она становится равной нулю. aDTOList имеет тот же размер, что и исходный список, который я отобразил, но единственное отличие состоит в том, что все элементы bDTOList в aDTO равно нулю. Структура aDTOList выглядит следующим образом, если размер aDTOList равен 2, а каждый ADTO содержит bDTOList, который также имеет размер 2.

[[null, null],[null, null]]

Таким образом, я думаю, что моя проблема в том, что у меня нет getBDTO в моей форме, но я не знаю, как это реализовать. Кто-нибудь может мне помочь, как это реализовать? Или есть ли другие способы заполнения bDTOList исходными данными?

ПРИМЕЧАНИЕ: Я НЕ МОГУ ИЗМЕНИТЬ СТРУКТУРУ КОДОВ, И КОДЫ ТОЛЬКО ОБРАЗЦЫ КОДОВ

Ответы [ 2 ]

2 голосов
/ 26 марта 2019

После нескольких дней исследований и обработки моего кода я наконец смог получить значения из JSP и отправить их обратно в форму.Я просто выложу ответ для дальнейшего использования.Благодаря этому веб-сайту я смог узнать причину своей проблемы и в итоге принял решение для ее решения.Ниже приведены подробные сведения о том, как я решил свою проблему.

Я обнаружил, что проблема связана с проблемой в Commons BeanUtils с индексированными свойствами, если вы используете java.util.List, а не Arrays, из-за того, что люди тогдаполучить ошибки «индекс вне диапазона» с помощью ActionForms, которые находятся в области запроса.Вот почему необходимо увеличить список при вызове метода get (int).Также вам нужно повторно инициализировать список всякий раз, когда вызывается метод сброса.Для этого вам нужно вставить этот код в метод сброса в форме:

public void reset(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {

    aDTOList = ListUtils.lazyList(new java.util.ArrayList(), new Factory() {
        public Object create() {
            return buildADTOList();
        }
    });
 }

private ADTO buildADTOList() {
    ADTO aDTO = new ADTO();
    List bDTOList = ListUtils.lazyList(new java.util.ArrayList(), new Factory() {
        public Object create() {
            return new BDTO();
        }
    });
    aDTO.setBDTOList(bDTOList);
    return aDTO;
}

Теперь, когда вы вызываете метод сброса, ваш список вырастет до его первоначального размера.Следующая проблема теперь в том, как извлечь значения из JSP и поместить их обратно в список.Для этого вы должны принять к сведению, что значение результирующего атрибута html name вашего тега JSP должно быть в этом формате aDTOList[0].bDTOList[0].sample1.Но если вы используете тег (так же, как в вопросе), значение полученного HTML будет выглядеть следующим образом: Пример:

<logic:iterate id="ADTO" name="MyForm" property="aDTOList" indexId="idxRes">
    <logic:iterate id="BDTO" name="ADTO" property="bDTOList" indexId="idxLine">
        <html:hidden name="BDTO" property="sample1" indexed="true"/>
        <html:hidden name="BDTO" property="sample2" indexed="true"/>
    </logic:iterate>
</logic:iterate>

Это приведет к:

<input type="hidden" name="BDTO[0].sample1" value="..."/>
<input type="hidden" name="BDTO[0].sample2" value="..."/>
<input type="hidden" name="BDTO[1].sample1" value="..."/>
<input type="hidden" name="BDTO[1].sample2" value="..."/>
<input type="hidden" name="BDTO[0].sample1" value="..."/>
<input type="hidden" name="BDTO[0].sample2" value="..."/>
<input type="hidden" name="BDTO[1].sample1" value="..."/>
<input type="hidden" name="BDTO[1].sample2" value="..."/>

Результат не в формате aDTOList[0].bDTOList[0].sample1, поэтому вам нужно использовать <nested:iterate>.
Преобразованный код будет иметь вид:

<nested:iterate property="aDTOList" indexId="idxRes">
    <nested:iterate property="bDTOList" indexId="idxLine">
        <nested:hidden property="sample1"/>
        <nested:hidden property="sample2"/>
    </nested:iterate>
</nested:iterate>

В результате вы получите:

<input type="hidden" name="aDTOList[0].bDTOList[0].sample1" value="..."/>
<input type="hidden" name="aDTOList[0].bDTOList[0].sample2" value="..."/>
<input type="hidden" name="aDTOList[0].bDTOList[1].sample1" value="..."/>
<input type="hidden" name="aDTOList[0].bDTOList[1].sample2" value="..."/>
<input type="hidden" name="aDTOList[1].bDTOList[0].sample1" value="..."/>
<input type="hidden" name="aDTOList[1].bDTOList[0].sample2" value="..."/>
<input type="hidden" name="aDTOList[1].bDTOList[1].sample1" value="..."/>
<input type="hidden" name="aDTOList[1].bDTOList[1].sample2" value="..."/>

Как вы можете видеть, он находится в формате aDTOList[0].bDTOList[0].sample1.

И из этого вы можете извлечь значения из вложенного списка из JSP и отправить его обратно в форму.Я надеюсь, что это послужит руководством для тех людей, которые застряли на несколько дней, решая эту проблему.

0 голосов
/ 29 марта 2019

По предоставленной вами ссылке вы используете Struts 1. Вот как я делаю это в моем проекте:

Форма
Аналогично вашему коду, объявите List в форме действия контейнера.И нужна еще одна важная конфигурация для списка, необходимо переопределить метод reset для ActionForm, чтобы инициировать List с пустыми объектами.Код reset выглядит следующим образом:

// Form Class
  ....
  // Declare the list
  private List<DetailDto> details = new ArrayList<>();
  ....
  // Reset Method
  private Pattern detailParameterPattern = Pattern.compile("details\\[(\\d+)\\].*");
  private static final int FIRST_GROUP_INDEX = 1;

  @Override
  public void reset(ActionMapping actionMapping, HttpServletRequest request) {
    super.reset(actionMapping, request);
    Enumeration<String> paramNames = request.getParameterNames();
    int maxSize = 0;
    boolean matched = false;
    while (paramNames.hasMoreElements()) {
      String paramName = paramNames.nextElement();
      Matcher detailMatcher = detailParameterPattern.matcher(paramName);
      if (detailMatcher.matches()) {
        matched = true;
        String index = detailMatcher.group(FIRST_GROUP_INDEX);
        if (Integer.parseInt(index) > maxSize) {
          maxSize = Integer.parseInt(index);
        }
      }
    }
    if (matched) {
      for (int i = 0; i <= maxSize; i++) {
        details.add(new DetailDto());
      }
    }
  }

JSP
Существует атрибут indexed тегов Struts html.С тегом JSTL forEach, объявите items и переменную, имя переменной должно быть немного хитрым, что оно должно совпадать с именем, которое вы объявили в форме.Код выглядит следующим образом:

<c:forEach items="${form.details}" varStatus="detailsStatus" var="details">
    <tr>
        <td class="resultCell">${detailsStatus.index+1}</td>
        <td class="resultCell">
           <html:checkbox name="details" property="checked" indexed="true" value="Y"/>
....
...

Сопоставление других значений выполняется автоматически структурой Struts.
Ключом здесь является то, что вам нужно инициировать List (или Array) с объектамивместо пустого List (или Array), потому что Struts не может создать для него объект.

...