SelectOneMenu中的JSF转换器问题
我又一次遇到麻烦了。我的观点是: 在我的项目中,我需要一个转换器(显然)将SelectOneMenu组件中的项转换为相应bean中的列表属性。在我的jsf页面中,我有:SelectOneMenu中的JSF转换器问题,jsf,converter,Jsf,Converter,我又一次遇到麻烦了。我的观点是: 在我的项目中,我需要一个转换器(显然)将SelectOneMenu组件中的项转换为相应bean中的列表属性。在我的jsf页面中,我有: <p:selectOneMenu id="ddlPublicType" value="#{publicBean.selectedPublicType}" effect="fade" converter="#{publicBean.conversor}" > <f:selectItems valu
<p:selectOneMenu id="ddlPublicType" value="#{publicBean.selectedPublicType}" effect="fade" converter="#{publicBean.conversor}" >
<f:selectItems value="#{publicoBean.lstPublicTypes}" var="pt" itemLabel="#{pt.label}" itemValue="#{pt.value}"></f:selectItems>
</p:selectOneMenu>
我的豆豆是:
@ManagedBean(name = "publicBean")
@RequestScoped
public class PublicBean {
// Campos
private String name; // Nome do evento
private TdPublicType selectedPublicType = null;
private List<SelectItem> lstPublicTypes = null;
private static PublicTypeDAO publicTypeDao; // DAO
static {
publicTypeDao = new PublicTypeDAO();
}
// Construtor
public PublicoBean() {
lstPublicTypes = new ArrayList<SelectItem>();
List<TdPublicType> lst = publicTypeDao.consultarTodos();
ListIterator<TdPublicType> i = lst.listIterator();
lst.add(new SelectItem("-1","Select..."));
while (i.hasNext()) {
TdPublicType actual = (TdPublicType) i.next();
lstPublicTypes.add(new SelectItem(actual.getIdPublicType(), actual.getNamePublicType()));
}
}
// Getters e Setters
...
public Converter getConversor() {
return new Converter() {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// This value parameter seems to be the value i had passed into SelectItem constructor
TdPublicType publicType = null; // Retrieving the PublicType from Database based on ID in value parameter
try {
if (value.compareTo("-1") == 0 || value == null) {
return null;
}
publicType = publicTypeDao.findById(Integer.parseInt(value));
} catch (Exception e) {
FacesMessage msg = new FacesMessage("Error in data conversion.");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage("info", msg);
}
return publicType;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value.toString(); // The value parameter is a TdPublicType object ?
}
};
}
...
}
@ManagedBean(name=“publicBean”)
@请求范围
公共类公共bean{
//坎波斯
私有字符串名称;//Nome do evento
私有TdPublicType selectedPublicType=null;
私有列表lstPublicTypes=null;
私有静态PublicTypeDAO PublicTypeDAO;//DAO
静止的{
publicTypeDao=新的publicTypeDao();
}
//承包商
公共图书馆{
lstPublicTypes=newarraylist();
List lst=publicTypeDao.consultarTodos();
ListIterator i=lst.ListIterator();
添加(新的选择项(“-1”,“选择…”);
while(i.hasNext()){
TdPublicType实际=(TdPublicType)i.next();
添加(新的SelectItem(actual.getIdPublicType(),actual.getNamePublicType());
}
}
//接球手
...
公共转换器getConversor(){
返回新转换器(){
@凌驾
公共对象getAsObject(FacesContext上下文、UIComponent组件、字符串值){
//这个value参数似乎是我传递给SelectItem构造函数的值
TdPublicType publicType=null;//根据值参数中的ID从数据库检索publicType
试一试{
if(value.compareTo(“-1”)==0 | | value==null){
返回null;
}
publicType=publicTypeDao.findById(Integer.parseInt(value));
}捕获(例外e){
FacesMessage msg=新的FacesMessage(“数据转换错误”);
消息设置严重性(FacesMessage.SEVERITY_错误);
FacesContext.getCurrentInstance().addMessage(“info”,msg);
}
返回公共类型;
}
@凌驾
公共字符串getAsString(FacesContext上下文、UIComponent、对象值){
返回值.toString();//值参数是TdPublicType对象吗?
}
};
}
...
}
在getAsObject()方法中,value参数似乎是我传递给SelectItem构造函数的值。但是在getAsString()方法中,该值似乎也是Id的字符串表示形式。该参数不应为TdPublicType类型?我的代码中有什么错误吗?getAsString()应该将对象
(对于类型TdPublicType
)转换为字符串
,该字符串唯一地标识实例,例如某个ID,以便可以在HTML代码中内联并作为HTTP请求参数传递。getAsObject()
应该将唯一的字符串
表示转换回具体的对象
实例,以便可以将提交的HTTP请求参数转换回原始对象实例
基本上(忽略了琐碎的预检查和异常处理):
更新:还有一个问题,您将
TdPublicType
类的值
属性指定为项值,而不是TdPublicType
实例本身。这样,转换器将检索值
属性,而不是getAsString()
中的TdPublicType
实例。相应地进行修正:
<f:selectItems value="#{publicoBean.lstPublicTypes}" var="pt"
itemLabel="#{pt.label}" itemValue="#{pt}"/>
现在代码正在运行。我的错误在于加载方法。我是这样做的:
// Loading menu
List<TdPublicType> l = daoPublicType.retrieveAll();
Iterator<TdPublicType> i = l.iterator();
while (i.hasNext()) {
TdPublicType actual = (TdPublicType) i.next();
lstMenuPublicType.add(new SelectItem(actual.getIdtPublicType(), actual.getNamePublicType()));
}
//加载菜单
List l=daoplictype.retrieveAll();
迭代器i=l.迭代器();
while(i.hasNext()){
TdPublicType实际=(TdPublicType)i.next();
添加(新的SelectItem(actual.getIdtPublicType(),actual.getNamePublicType());
}
但正确的方法是:
// Loading menu
List<TdPublicType> l = daoPublicType.retrieveAll();
Iterator<TdPublicType> i = l.iterator();
while (i.hasNext()) {
TdPublicType actual = (TdPublicType) i.next();
lstMenuPublicType.add(new SelectItem(actual, actual.getNamePublicType())); // In the first parameter i passed the PublicType object itself not his id.
}
//加载菜单
List l=daoplictype.retrieveAll();
迭代器i=l.迭代器();
while(i.hasNext()){
TdPublicType实际=(TdPublicType)i.next();
lstmenuppublicType.add(new-SelectItem(actual,actual.getNamePublicType());//在第一个参数中,我传递了PublicType对象本身,而不是他的id。
}
use可以使用通用转换器,它将转换支持bean中的值。
你不需要任何铸造也
@FacesConverter(value = "GConverter")
public class GConverter implements Converter{
private static Map<Object, String> entities = new WeakHashMap<Object, String>();
@Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
synchronized (entities) {
if (!entities.containsKey(entity)) {
String uuid = UUID.randomUUID().toString();
entities.put(entity, uuid);
return uuid;
} else {
return entities.get(entity);
}
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
for (Entry<Object, String> entry : entities.entrySet()) {
if (entry.getValue().equals(uuid)) {
return entry.getKey();
}
}
return null;
}
}
@facescoverter(value=“GConverter”)
公共类GConverter实现转换器{
私有静态映射实体=new WeakHashMap();
@凌驾
公共字符串getAsString(FacesContext上下文、UIComponent组件、对象实体){
已同步(实体){
如果(!entities.containsKey(实体)){
字符串uuid=uuid.randomUUID().toString();
实体。put(实体,uuid);
返回uuid;
}否则{
返回实体。获取(实体);
}
}
}
@凌驾
公共对象getAsObject(FacesContext上下文、UIComponent组件、字符串uuid){
for(条目:entities.entrySet()){
if(entry.getValue().equals(uuid)){
return entry.getKey();
}
}
返回null;
}
}
示例用法是
<p:selectOneMenu id="ddlPublicType" value="#{publicBean.selectedPublicType}" effect="fade" converter="GConverter" >
<f:selectItems value="#{publicoBean.lstPublicTypes}" var="pt" itemLabel="#{pt.label}" itemValue="#{pt}"></f:selectItems>
</p:selectOneMenu>
是否需要重载TdPublicType的toString()?在getAsString()方法内部生成了一个异常,表示无法从字符串转换为TdPublicType。然后模型值显然不是类型TdPublicType
。实际上,您使用了itemValue=“#{pt.value}”
而不是itemValue=“#{pt}”
。相应地修复它。他仍然返回一个整数作为组件的支持模型,但我已经将itemValue属性更改为#{pt}。我发现了为什么getAsString()的值参数返回一个整数而不是TdPublicType对象,我需要一个List而不是List作为的值属性。是的,这是正确的。列表
<p:selectOneMenu id="ddlPublicType" value="#{publicBean.selectedPublicType}" effect="fade" converter="GConverter" >
<f:selectItems value="#{publicoBean.lstPublicTypes}" var="pt" itemLabel="#{pt.label}" itemValue="#{pt}"></f:selectItems>
</p:selectOneMenu>