У меня есть этот f:viewParam
, что я пытаюсь связать валидацию и преобразовать userId
в Player
, и я получил неожиданных результатов.е: viewParam с конвертером исключением ViewScoped, когда Invoke второго запроса Аякса
<f:metadata>
<f:viewParam name="userId" value="#{myBean.selectedPlayer}" converter="pConverter"
converterMessage="Bad Request. Unknown User" required="true"
requiredMessage="Bad Request. Please use a link from within the system" />
</f:metadata>
<h:body>
<p:messages id="msgs"/>
<h:form>
<ul>
<li><a href="index2.xhtml?userId=1">Harry</a></li>
<li><a href="index2.xhtml?userId=2">Tom</a></li>
<li><a href="index2.xhtml?userId=3">Peter</a></li>
</ul>
</h:form>
<h:form>
<h:panelGrid columns="2" rendered="#{not empty myBean.selectedPlayer}">
<h:outputText value="Id: #{myBean.selectedPlayer.id}"/>
<h:outputText value="Name: #{myBean.selectedPlayer.name}"/>
</h:panelGrid>
</h:form>
<h:form id="testForm">
<h:inputText value="#{myBean.text}"/>
<p:commandButton value="Switch" update=":msgs testForm"/>
<h:outputText value="#{myBean.text}" rendered="#{not empty myBean.text}"/>
</h:form>
</h:body>
Мой конвертер выглядеть как этот
@FacesConverter(value="pConverter")
public class PConverter implements Converter {
private static final List<Player> playerList;
static{
playerList = new ArrayList<Player>();
playerList.add(new Player(1, "Harry"));
playerList.add(new Player(2, "Tom"));
playerList.add(new Player(3, "Peter"));
}
@Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value == null || !value.matches("\\d+")){
return null;
}
long id = Long.parseLong(value);
for(Player p : playerList){
if(p.getId() == id){
return p;
}
}
throw new ConverterException(new FacesMessage("Unknown userId: " + value));
}
@Override
public String getAsString(FacesContext fc, UIComponent uic, Object value) {
if(!(value instanceof Player) || value == null){
return null;
}
return String.valueOf(((Player)value).getId());
}
}
Как я нажимаю три ссылки (Гарри, Том, Питер), конвертора работы большой. Он конвертирует идентификатор и связывает player
обратно с моим управляемым компонентом. Затем я напечатаю что-то в текстовом поле, а затем нажмите Switch
, когда он работает нормально, то, что я набрал, появляется рядом с кнопкой, но затем я меняю то, что я набираю, и снова нажмите Switch
, затем появится сообщение об ошибке Bad Request. Please use a link from within the system
, которое сообщение об ошибке для required
для f:viewParam
. Если я возьму f: viewParam, тогда все будет работать нормально. Удивительно, но если я переключусь с f: viewParam на o: viewParam (OmniFaces), тогда он отлично работает.
спасибо. Omnifaces довольно удивительный, BalusC. У меня есть один вопрос о 'o: viewParam', в вашем блоге вы сказали, что всезначения будут избегать обращения к' Конвертеру' каждый раз при вызове ajax-запроса, однако кажется, что он всегда попадает внутрь метода 'getAsString()'. Поэтому я задаюсь вопросом, правильно ли это поведение. Я знаю, что 'getAsObject' - это то, что устанавливает значение модели, поэтому не вызывать' getAsObject' - отличное улучшение. И я благодарю вас за это. –
'getAsString()' будет вызываться, когда объект должен быть преобразован в строку (для представления в сгенерированном HTML). Но это должно быть довольно дешевое задание, поскольку оно должно быть строковым значением одного из его свойств. У вас есть объект уже в ваших руках, поэтому нет дорогостоящей работы БД. – BalusC
Большое спасибо. –