给定组件:https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml
我的测试的完整来源是:https://github.com/dannymk/PrimefacesTest
无法使用转换器使组件与对象一起工作。不知道如何解决这个问题。
package org.primefaces.test;
import java.io.Serializable;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
/**
* @return the id
*/
public Integer getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
package org.primefaces.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Daniel Maldonado
*/
public class PlayerService implements Serializable{
private List<Player> available = new ArrayList<>();
public PlayerService() {
available.add(new Player(1, "One"));
available.add(new Player(2, "Two"));
available.add(new Player(3, "Three"));
available.add(new Player(4, "Four"));
available.add(new Player(5, "Five"));
}
/**
* @return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* @param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
}
java prettyprint-override">package org.primefaces.test;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author Daniel Maldonado
*/
@Named
@FacesConverter(value = "playerConverter", managed = true)
public class PlayerConverter implements Converter<Player> {
@Inject
PlayerService service;
@Override
public Player getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
Player found = service.getAvailable().stream()
.filter(player -> player.getName().equals(value))
.findAny()
.orElse(null);
return found;
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Player o) {
if (o != null){
return o.getName();
}
return null;
}
}
package org.primefaces.test;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Data;
@Data
@Named
@ViewScoped
public class TestView implements Serializable {
private String hello;
private List<Player> available;
private Player selected;
@Inject
PlayerService service;
@PostConstruct
public void init() {
setHello("Welcome to PrimeFaces!!!");
this.available = service.getAvailable();
}
/**
* @return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* @param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
/**
* @return the selected
*/
public Player getSelected() {
return selected;
}
/**
* @param selected the selected to set
*/
public void setSelected(Player selected) {
this.selected = selected;
}
/**
* @return the hello
*/
public String getHello() {
return hello;
}
/**
* @param hello the hello to set
*/
public void setHello(String hello) {
this.hello = hello;
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
我会出现以下错误:
java.lang.ClassCastException: java.lang.String cannot be cast to org.primefaces.test.Player
at org.primefaces.test.PlayerConverter.getAsString(PlayerConverter.java:38)
我改变什么似乎无关紧要,相信我,我已经尝试了很多转换器的实现,并且在视图中使用了“#{palyerConverter}”而不是
“playerConverter”
,但仍然无法使其工作。
多亏了@Jasper de Vries,最后只做了几处改动就成功了:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter">
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
并且特别不要忘记在“列出”的Object中实现EQUALS方法:
package org.primefaces.test;
import java.io.Serializable;
import java.util.Objects;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Player))
return false;
Player compare = (Player) obj;
return Objects.equals(compare.getId(), this.getId());
}
@Override
public int hashCode() {
int hash = 1;
return hash * 31 + this.getName().hashCode();
}
/**
* @return the id
*/
public Integer getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
你的问题在这一行:
html prettyprint-override"><f:selectItem itemLabel="Select One" itemValue="" />
当前,您正在传递一个空字符串作为项值,这是您的转换器所不期望的。可以使用itemValue=“#{null}”
或从no-select选项中完全删除itemValue。
另见:
在JSF中向selectOneMenu添加“无选择”选项的最佳方式
问题内容: 如果我有带签名的元组,则无法将其强制转换为。编译器说: 错误:无法表示元组转换((String,Bool)’到’(String,Any)’ 但这应该可行,因为可以安全地使用它。如果执行类似的操作,几乎会引发相同的错误: 错误: 无法将类型’(Swift.String,Swift.Bool)’的值强制转换为’(protocol <>,protocol <>)) 那么,有什么变通办法,尤其
问题内容: 是否有一种优雅的方法将原语数组转换为相应容器对象的数组- 例如,将a 转换为a ?还是我坚持循环浏览并手动执行? 是的,循环并不完全困难。有点丑。 问题答案: Apache Commons Apache Commons / Lang 有一个ArrayUtils类,用于定义这些方法。 所有称为 从原始数组转换为包装器数组的方法 从包装对象数组到原始数组的所有转换 例: 番石榴 但是然后我
我有一个与PHP链接的JavaScript AJAX。PHP有以下代码: 它的输出将是一个字符串: 我想用这些元素创建一个JavaScript数组: 是否有预定义的函数要使用?你有解决办法吗?
我想将web设计师用纯HTML编写的复杂div容器转换为React组件。此div容器具有React to manage的状态。我知道我可以将div转换为JSX,但这意味着设计师和我都要加倍努力。危险的是,Html不处理状态。我可以创建React的子类。组件,定义状态并在不使用JSX的情况下将状态值呈现到div容器中? 下面是div容器标记的一个片段:
如果您需要在Aurelia应用程序中转换某些值,则可以使用converters而不是手动将值转换为所需的格式。 转换日期 当我们想要将默认日期值转换为某种特定格式时,我们可以使用momentJS库。 这是一个用于操作日期的小型库。 C:\Users\username\Desktop\aureliaApp>jspm install moment 让我们创建一个新文件converters.js 。
XStream转换器是XStream库的关键组件,它负责将对象转换为XML,反之亦然。 XStream为常见类型提供了大量转换器,例如基元,字符串,文件,集合,数组和日期。 使用转换器 让我们使用SingleValueConvertor,其目的是将对象转换为单个字符串。 我们将使用SingleValueConvertor将对象写为属性字符串。 创建转换器 class NameConverter i