Методы набора UIInput не вызываются при отправке страницы JSF с <f:viewParams>

У меня есть простая форма на моей странице JSF, которая выглядит следующим образом:

<html 
  xmlns = "http://www.w3.org/1999/xhtml"
  xmlns:h = "http://xmlns.jcp.org/jsf/html"
  xmlns:f = "http://java.sun.com/jsf/core"
>
  <f:view>
    <h:head>
      <f:metadata>
        <f:viewParam name = "cities" value = "#{myBean.cities}" />
      </f:metadata>
    </h:head>
    <h:body>
      <h:form>
        <h:messages id = "messages" />
        <h:selectManyCheckbox value = "#{myBean.cities}" label = "Select City" >
          <f:selectItems value = "#{myBean.allCities}" />
        </p:selectManyCheckbox>
        <h:commandButton value = "Submit">
          <f:ajax execute = "@form" render = "output"/>
        </h:commandButton>
      </h:form>
      <h:panelGroup id = "output">
        Number of Selected Cities: #{myBean.cities.size()}
      </h:panelGroup>
    </h:body>
  </f:view>
</html>

Соответствующий фоновый компонент:

Со следующими методами bean:

@Named
@RequestScoped
public class MyBean {
  private List<String> cities = new ArrayList<>();

  public List<String> getCities() {
    return cities;
  }

  public void setCities(List<String> cities) {
    this.cities = cities;
  }

  public List<String> getAllCities() {
    return new ArrayList<>(Arrays.asList(new String [] {
      "Los Angeles",
      "St. Louis",
      "San Francisco",
      "Dallas",
      }));
  }
}

Наблюдения:

  1. Я добавил логирование входа и выхода методов getCities и setCities. Во время обновления страницы JSF вызывается метод getCities. Однако при отправке setCities никогда не вызывается.
  2. Я не получаю никаких ошибок или исключений в журнале консоли (для javax.faces.PROJECT_STAGE установлено значение РАЗРАБОТКА в web.xml).
  3. Никакие ошибки не передаются <h:messages/>
  4. методы set не вызываются ни для каких полей ввода формы. Страница ведет себя «странно».

Проблема похожа на проблему № 3 в принятом ответе от Метод commandButton/commandLink/ajax action/listener не вызван или входное значение не установлено/не обновлено, однако у меня нет явной проблемы с преобразованием для <p:selectCheckboxMenu>. Согласно документации, он должен отлично справляться с List<String>.

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

Итак, просто присутствие этого f:viewParam, указывающего на то же свойство bean-компонента типа Collection, что и ввод, молча предотвращает отправку пользовательского ввода?

Selaron 21.02.2019 08:36

да. Он не дает сбой при первом рендеринге (когда параметры GET не указаны), но, как ни странно, он терпит неудачу при отправке (ajax) формы.

YoYo 21.02.2019 22:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
67
1

Ответы 1

Короче говоря, <f:viewParam> пока не поддерживает список значений.

Подпись свойства citiesList<String>.

Обратите внимание, что когда мы пытаемся передать параметр для cities (добавляем ?cities=Dallas в конец URL-адреса запроса), мы внезапно получаем соответствующую ошибку преобразования в <h:messages/>, утверждая:

Conversion Error setting value 'Dallas' for 'null Converter'.

Кроме того, согласно упомянутым сообщениям, мы также должны включать сообщения для обновлений ajax:

    <h:commandButton value = "Submit">
      <f:ajax execute = "@form" render = "output"/>
      <f:ajax execute = "@form" render = "messages"/>
    </h:commandButton>

Следуя этому, не при первом посещении, а хотя бы при отправке мы получаем соответствующую ошибку:

Conversion Error setting value '[]' for 'null Converter'.

Я не уверен, почему <f:viewParam> нужно устанавливать во время отправки в стиле ajax?

Чтобы решить, вы можете либо предоставить <f:converter>, либо предоставить дополнительные геттеры/сеттеры, которые обрабатывают настройку/получение типа массива или списка на основе строки.

Выбрав быстрое решение, мы можем изменить <f:viewParam> следующим образом:

<f:viewParam name = "cities" value = "#{myBean.citiesCsv}" />

В то время как для вспомогательного компонента мы добавляем следующий метод:

  public void setCitiesCsv(String csv) {
    if (csv.isEmpty()) {
      cities = new ArrayList<>();
    } else {
      cities = 
         Stream.of(csv.split(","))
           .collect(Collectors.toCollection(ArrayList<String>::new));
    }
  }

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

Похожие сообщения

Я понятия не имею, как ваш обширный ответ является ответом на вопрос.

Kukeltje 20.02.2019 20:19

Разработчики должны научиться делать минимальный воспроизводимый пример и ничего не подозревать. Подозрение у конспирологов, а не у разработчиков. Разработчики сужают круг проблем путем отладки, большую часть которых составляет создание минимальный воспроизводимый пример. И уверен, №3 в stackoverflow.com/questions/2118656 не помог бы?

Kukeltje 20.02.2019 21:31

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

Kukeltje 20.02.2019 21:35

Таким образом, ответ, на который вы ссылались, (@BalusC написал более обширный, чем тот, который я пробовал, обрабатывая гораздо больше сценариев) почти получил его - проблема в том, что это не применимо: «Вы можете использовать <h: messages>». К сожалению, для viewParams ошибки преобразования заполняют сообщения нет (по крайней мере, то, что я наблюдал). Также № 3 находится на UIInput, а не на viewParam. лол, я не конспиролог. Но во всем остальном вы правы.

YoYo 20.02.2019 21:54

Я мог бы быть тем, с чем вы столкнулись, является совершенно новым случаем и действительным сам по себе. Приятно знать, что h:messages не помогает. Затем нам нужно выяснить в stackoverflow (или другой поисковой системе), есть ли способ зафиксировать эти ошибки преобразования в параметре просмотра. Пробовали запускать в режиме разработки? (как указано в ссылке/ответе). А какая у вас версия и реализация JSF? И я думаю, проверьте stackoverflow.com/questions/26755749, чтобы предотвратить это в будущем.

Kukeltje 20.02.2019 21:57
<o:viewParamValidationFailed> будет полезно, но не решит проблему «забыл конвертацию». Для этого он должен быть универсальным, что-то, что я могу добавить к шаблонам, которые используют все мои разработчики. Но вы дали некоторую работу и дополнительную проверку, которую я должен пройти.
YoYo 20.02.2019 22:04

Я нашел свой ответ в stackoverflow.com/questions/44419951/…, в котором предлагается попробовать использовать аннотацию @Param из showcase.omnifaces.org/cdi/Параметры. Это может работает с многозначными параметрами, если все сделано правильно и преобразователями одновременно. Да, вы не видите в представлении, что ему нужен параметр, но это может быть что-то, на что стоит обратить внимание, поскольку вы можете использовать обычный метод получения/установки, чем (с некоторыми аннотациями или...

Kukeltje 20.02.2019 23:12

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

YoYo 21.02.2019 02:06

Другие вопросы по теме