【问题标题】:How to cast a (java.lang.Class) Class to a Class obtained with reflection如何将(java.lang.Class)类转换为通过反射获得的类
【发布时间】:2017-07-28 18:27:10
【问题描述】:

我正在尝试构建一个模块来管理我的数据库目录,例如:国家、企业、用户等。用户应该从组合框中选择目录,系统应该显示一个包含主要列的表(数据库中不为空,有些是我预定义的)。从 3 个目标中,我只实现了 2 个: 1.- 使用反射选择目录后,从实体类中获取@NotNull 字段 2.-显示带有动态列的表格,也可以从上面检索它们。 但是3号给我带来了麻烦。问题是,我在视图中使用以下代码来动态显示列(基于我存储在对象中的@NotNull 字段),(https://www.primefaces.org/showcase/ui/data/datatable/columns.xhtml):

<p:dataTable  id="conceptos" var="pojo" value="#{catalogoMB.comocombo}>
<p:columns value="#{catalogoMB.columns}" var="column" 
columnIndexVar="colIndex" sortBy="#{pojo[column.property]}" filterBy="#
{pojo[column.property]}">
        <f:facet name="header">
        <h:outputText value="#{column.header}" />
        </f:facet>
        <h:outputText value="#{pojo[column.property]}" />
</p:columns>
</p:dataTable> 

因此,例如,以正常方式,没有反射,上面的代码将像这样工作: comcomombo 将具有以下属性:名称、值、id;我的列数组将是相同的:名称、值、id ... 问题是,comocombo 是一个 List&lt;Object&gt; 对象,我在其中存储字段的反射类值,它返回 java.lang.class 而不是 EntityClass 的实例,尽管我设法从该类的 Object 实例调用 setter 和 getter (组合)-据说- 所以当我尝试显示pojo[column.property]-> comocombo["id"]、comocombo["name"] 或 comcomombo["value"] 时,它会向我发送一个异常,说java.lang.class 没有这个任何属性.. ..我怎样才能联系到他们?我读过关于Map&lt;String, String&gt;.cast() 的文章,但我不确定这是否可行。

public void populateT(){ 
comocombo=new ArrayList<>();
Object tt ;
y = tabla.get(tabla.size()-1).getConcpetos(); //result of query type: 
FindAll from the entity Class 
try{
Class combito= Class.forName("sipe.services."+ catName); //the "path" of the 
Entity Classes
for (Integer j=0; j<y.size()-1; j++){
tt=y.get(j);
            for (Integer i=0; i< tabla.size()-1; i++){
            tucampo=minustomayus(y.get(j).getClass().getDeclaredField(tabla.get(i).getNombre_c()).getName()); //tabla.get(i).getNombre_c()-> here I've stored the @NotNull properties' names (countryid, countryname...) whic are the same in  columns = new ArrayList<ColumnModel>();  (catalogoMB.columns in the view) 
            Class cls= Class.forName("sipe.services."+ catName);
            Method method = cls.getDeclaredMethod("get"+tucampo); // for example "countryid" -> getCountryid              
            Class<?> type = null;
            for (Method methods : combito.getDeclaredMethods())
            { //Here I'm trying to invoke setter of the Entity Class in order to store its values..
              //equivalent to: if o is an instance of Entity Class Country: Country o = new Country(); o.setCountryid(2);
                if (methods.getName().contains("set"+tucampo)){
                type=method.getReturnType();
                methods.invoke(combito.newInstance(),method.invoke(tt));
             }
            }

【问题讨论】:

  • 如果我应该理解这一点,您想根据组合框中的选定值动态加载数据表列,其中组合框的值是实体类?
  • 是的@Kaizen,我已经实现了这一点:动态地将列添加到我的数据表中...根据每个实体选择的类...我在尝试根据这些列显示数据时遇到问题因为我的对象是 java.lang.Class(反射的效果),而我在 p:dataTable 上的变量没有达到属性...
  • 你可以回答你的问题并接受:)
  • @Kaizen,不是真的呵呵,我想避免这种情况:serverError: class javax.el.PropertyNotFoundException The class 'java.lang.Class' does not have the property 'id'. 虽然对象说它是反射类的一个实例,但它无法访问属性,所以数据永远不会显示...这是我的问题;我试图为这个问题提供尽可能多的背景信息:P
  • 发布答案的罗杰

标签: jsf reflection primefaces java.lang.class


【解决方案1】:

我是这样工作的,希望对你有帮助

 private void createDynamicColumns(){
            //split column templates
            String[] columnKeys = columnTemplate.split(" ");
            //set first list to null
            //this should be a List with no type specified
            //eg List objects = new ArrayList<>();
            //since you will dynamically populate it based on what the user selects from combobox
            objects = null;
            //clear columns
            columns.clear();
            //create a class from combobox selection
            Class<?> forName = Class.forName("pathToClass." + comboboxSelection);
            //get declared fields in that class
            List<Field> asList = Arrays.asList(forName.getDeclaredFields());
            //for each columkeys
            //if method.getName() can be found in columnKeys
            //add that columnKey to the new columnList;
            for(int i =0;i< asList.size();i++)
                for (String columnKey : columnKeys) {
                    String fieldName = asList.get(i).getName();
                    if (columnKey.equalsIgnoreCase(fieldName)) {
                        columns.add(fieldName);
                    }
                }

          //fetch from the database the objects list
           objects = DAO.findAll();
        }

和 facelets 页面

<p:dataTable var="object" value="#{backingBean.objects}">                    
        <p:columns value="#{BackingBean.columns}" var="column">
            <f:facet name="header">
                <h:outputText value="#{column}" />
            </f:facet>
            <h:outputText value="#{object[column]}" />
        </p:columns>
</p:dataTable>

记得处理异常

【讨论】:

  • 鼓掌鼓掌 谢谢!!我真的没有像你那样实施解决方案,但是这个:value="#{backingBean.objects}" 正是我需要的! =D 我非常感谢和高兴 :D;我更改了我的这一行:&lt;p:dataTable id="conceptos" var="pojo" value="#{catalogoMB.y}&gt; y 是我从“findAll”查询中获得的对象列表,它有效!谢谢
  • 这个 y:y = tabla.get(tabla.size()-1).getConcpetos(); //result of query type:
猜你喜欢
  • 2016-05-24
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
相关资源
最近更新 更多