2

「p:autocomplete」ウィジェットを正常に機能させることができません...

ここに示すように、オートコンプリートウィジェットを使用しています...

<p:autoComplete id="abc"  dropdown="true" value="#{testBean.parmMap['inputval']}" completeMethod="#{testBean.testList}" var="items" itemLabel="#{items.label}" itemValue="#{items}" converter="#{itemConverter}" ></p:autoComplete>

次のエラーメッセージが表示されます...

javax.el.PropertyNotFoundException:/index.xhtml @ 18,245 itemLabel = "#{items.label}":プロパティ'label'がタイプjava.lang.Stringに見つかりません

私はこのエラーを乗り越えることができませんでした。問題がどこにあるのかわからない -以下に示す関連コードのほとんどを含めました。あなたが私に提供できるどんな指導にも感謝します!

これがフェイスレットページ全体です-index.xhtml...

<?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:util="http://java.sun.com/jsf/composite/util"      
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:p="http://primefaces.org/ui">      
    <f:view contentType="text/html">
        <h:head>
            <title>testprimeac</title>
            <meta charset="utf-8" />
        </h:head>
        <h:body>
            <h:form id="form1">
                <p:autoComplete id="abc"  dropdown="true" value="#{testBean.parmMap['inputval']}" completeMethod="#{testBean.testList}" var="items" itemLabel="#{items.label}" itemValue="#{items}" converter="#{itemConverter}" ></p:autoComplete>
            </h:form>
        </h:body>
    </f:view>
</html>`

これが「アイテム」クラスです...

package aaa.bbb.ccc.war;

public class Item
{

    private String label;
    private String value;

    public String getLabel()
    {
        return label;
    }

    public void setLabel(String label)
    {
        this.label = label;
    }

    public String getValue()
    {
        return value;
    }

    public void setValue(String value)
    {
        this.value = value;
    }
}

これがItemConverterクラスです... package aaa.bbb.ccc.war;

import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

public class ItemConverter implements Converter
{

    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue)
    {
        if (submittedValue.trim().equals(""))
        {
            return null;
        }
        else
        {
            itemList = getItemList();

            try
            {
                for (Item item : itemList)
                {
                    if (item.getValue().equalsIgnoreCase(submittedValue))
                    {
                        return item;
                    }
                }

            }
            catch (Exception e)
            {
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid item object"));
            }
        }

        return null;
    }

    @Override
    public String getAsString(FacesContext facesContext, UIComponent component, Object value)
    {
        if (value == null || value.equals(""))
        {
            return "";
        }
        else
        {
            return String.valueOf(((Item) value).getValue());
        }
    }
    private static List<Item> itemList;

    private static List<Item> getItemList()
    {
        if (null == itemList)
        {
            refData = getRefData();
            itemList = refData.getTestList();
        }

        return itemList;
    }
    private static RefData refData;

    private static RefData getRefData()
    {
        refData = (RefData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("refData");
        if (null == refData)
        {
            refData = new RefData();
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", refData);
        }
        return refData;
    }
}

これがTestBeanクラスです... package aaa.bbb.ccc.war;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("testBean")
@Scope("request")
public class TestBean implements Serializable
{

    private RefData refData;
    private LinkedHashMap<String, String> parmMap;

    public TestBean()
    {
    }

    public Map<String, String> getParmMap()
    {
        refData = getRefData();
        return refData.getParmMap();
    }

    public void setParmMap(LinkedHashMap<String, String> m)
    {
        refData = getRefData();
        refData.setParmMap(m);
        storeRefData(refData);
    }

    public void setTestList(List<Item> list) throws Exception
    {
        try
        {
            refData = getRefData();
            refData.setTestList(list);
            storeRefData(refData);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public List<Item> getTestList()
    {
        refData = getRefData();
        return refData.getTestList();
    }

    private static RefData getRefData()
    {
        RefData refData = (RefData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("refData");
        if (null == refData)
        {
            refData = new RefData();
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", refData);
        }
        return refData;
    }

    private static void storeRefData(RefData r)
    {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", r);
    }
}

これがRefDataクラス(TestBeanで参照)です... package aaa.bbb.ccc.war;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

public class RefData implements Serializable
{

    public RefData() //(String key)
    {
    }
    private static final Map<String, String> listBoxEntryMap;

    static
    {
        Map<String, String> m = new LinkedHashMap<String, String>();
        m.put("aaavalue", "aaalabel");
        m.put("bbbvalue", "aablabel");
        m.put("cccvalue", "abblabel");
        m.put("dddvalue", "bbblabel");
        m.put("eeevalue", "bbclabel");
        m.put("fffvalue", "bcclabel");
        m.put("gggvalue", "ccclabel");
        m.put("hhhvalue", "ccalabel");
        m.put("iiivalue", "caalabel");
        m.put("jjjvalue", "aaclabel");
        m.put("kkkvalue", "acclabel");
        m.put("lllvalue", "bbalabel");
        m.put("mmmvalue", "baalabel");

        listBoxEntryMap = Collections.unmodifiableMap(m);
    }
    private Map<String, String> parmMap;

    public Map getParmMap()
    {
        if (null == this.parmMap)
        {
            this.parmMap = new LinkedHashMap<String, String>();
            this.parmMap.put("inputval", "");
        }

        return this.parmMap;
    }

    public void setParmMap(Map m)
    {
        this.parmMap = m;
    }
    List<Item> testList = new ArrayList<Item>();

    public void setTestList(List<Item> data) throws IOException
    {
        testList = data;
    }

    public List<Item> getTestList()
    {
        try
        {
            if (null == testList || testList.isEmpty())
            {
                testList = getListOfItems();
            }

            return testList; //(list);
        }
        catch (Exception ex)
        {
            java.util.logging.Logger.getLogger(RefData.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public static List<Item> getListOfItems()
    {
        List<Item> list = null;
        try
        {
            Map<String, String> map = listBoxEntryMap;
            Iterator iter = map.keySet().iterator();

            list = new ArrayList<Item>();
            Item item = null;

            while (iter.hasNext())
            {
                String key = (String) iter.next();
                String val = (String) map.get(key);
                item = new Item();
                item.setLabel(key);
                item.setValue(val);
                list.add(item);
            }
        }
        catch (Exception e)
        {
            System.out.println("Exception during query call..." + e.getMessage());
            e.printStackTrace();
        }

        return list;
    }
}

FWIW-これがpom.xml(primefaces依存関係を含む)です...

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>aaa.bbb.ccc</groupId>
    <artifactId>testprimeac-war</artifactId>
    <packaging>war</packaging>
    <version>1</version>
    <name>testprimeac-war</name>
    <url>http://maven.apache.org</url>
    <properties>
        <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
        <jsf-version>2.1.11</jsf-version>
    </properties>    
    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>                
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.1.11</version>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.1.11</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>el-impl</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>        
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>3.4.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
            </plugin>
        </plugins>
        <finalName>testprimeac-${project.version}</finalName>       
    </build>
</project>
4

1 に答える 1

2

最初の段落で行ったアサーションの+1:ここには情報が多すぎます。基本Stringタイプにバインドしているため、コンバーターは不要です。

私がここで見る2つの主な問題は

  1. 値バインディングでタイプセーフコレクションを使用しないという選択。文字列値を保持するためにプレーンを使用するLinkedHashMapと、オブジェクトとして格納されるため、問題が発生する可能性が高くなります。コンパイラは、ここで自動ボクシングを行う義務はないと思います。

  2. バッキングのcompleteMethod実装は、基本的にオブジェクトのストアを返しStringます。varこれは、オートコンプリートでの変数を提供するものです。明白なことを言うと、あなたはそれを求めることはできませんgetLabel()

2つの方法のいずれかを進めることができます

  1. データストアを文字列のタイプセーフLinkedListに変更し、コンバーターを失い、問題がないはずです。あなた varは明白itemになり、itemLabelそしてitemValue両方ともになります#{item}

  2. POJOを実装して選択オブジェクトをカプセル化し、コンバーターを保持すると、バッキングデータストアがPOJOの単純なリストになり、選択が文字列ではなくPOJOのインスタンスになります。

編集:あなたの説明では、問題はオートコンプリートドロップダウンによって返されるタイプの不一致(タイプitem)とvalueオートコンプリートのバッキングBeanへのバインド(Stringタイプ)の結果です。ドロップダウン選択によって返されるタイプは、バッキングBeanでバインドしているタイプと同じである必要があります。

于 2012-12-04T19:38:53.153 に答える