38

instanceofELでチェックインする方法はありますか?

例えば

<h:link rendered="#{model instanceof ClassA}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model instanceof ClassB}">      
    #{errorMessage2}
</h:link>
4

7 に答える 7

57

と比較するClass#getName()か、おそらくより良いでしょClass#getSimpleName()String

<h:link rendered="#{model['class'].simpleName eq 'ClassA'}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model['class'].simpleName eq 'ClassB'}">      
    #{errorMessage2}
</h:link>

は予約済みのJavaリテラルであるため、中Object#getClass()括弧表記で指定することの重要性に注意してください。そうしないと、EL2.2以降でEL例外がスローされます。['class']class

タイプセーフな代替手段は、モデルの共通基本クラスにいくつかpublic enum Type { A, B }を追加することです。public abstract Type getType()

<h:link rendered="#{model.type eq 'A'}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{model.type eq 'B'}">      
    #{errorMessage2}
</h:link>

無効な値があると、EL2.2以降の実行時にEL例外がスローされます。

OmniFacesを使用している場合は、バージョン3.0以降を使用できます#{of:isInstance()}

<h:link rendered="#{of:isInstance('com.example.ClassA', model)}">      
    #{errorMessage1}
</h:link>
<h:link rendered="#{of:isInstance('com.example.ClassB', model)}">      
    #{errorMessage2}
</h:link>
于 2012-04-25T13:47:39.250 に答える
6

それはでは機能しませんEL。これにはバッキングBeanを使用します。

public class MyBean {

    public boolean getIsClassA() {
        if(model instanceof ClassA) {
            return true;
        }
        return false;
    }


}

次に、バッキングBeanを呼び出してチェックを実行します。

<h:link outcome="#{PageNameA}?faces-redirect=true&amp;" rendered="#{myBean.isClassA}">      
    #{errorMessage}
</h:link>

于 2012-04-25T11:01:52.603 に答える
4

できます:

rendered="#{node.getClass().getSimpleName() == 'Logt_anno'}"
于 2013-10-18T16:34:14.273 に答える
3

次のような静的関数を定義します。

public boolean isInstanceOf( Object obj, Class targetClass) {
        return targetClass.isInstance(obj);
    }

そのためのカスタムEL関数を定義し、それを使用します。文字列名を渡してforName()、メソッド内で実行することもできます。

于 2015-11-18T13:48:13.173 に答える
2

方法があります、参照してください

JSF EL:instanceofは予約されていますが、まだ実装されていませんか?

ただし、instanceof少なくともMojarra 2.1では、演算子はまだ実装されていません。ここでバグに投票してください:

http://java.net/jira/browse/JSP_SPEC_PUBLIC-113

現在の最善の回避策は、クラスごとにブールテストメソッドを作成するのではなく、クラス名をバッキングBeanゲッターに格納することです。

public String getSelectedNodeClassName()
{
    return selectedNode.getClass().getSimpleName();
}

つまり、BalusCとflashのソリューションを組み合わせたものになります。ただし、JSFではBalusCよりもはるかに読みやすく、さらに将来のinstanceofオペレーターの使用に非常に似ています。

rendered="#{nodeManager.selectedNodeClassName eq 'ChapterNode'}"

フラッシュが示唆するように、これはバッキングBeanのクラステストごとに1つのメソッドを生成しません。ただし、これはフラッシュよりも遅くなる可能性があります。

于 2012-05-03T05:36:37.730 に答える
1

JSP ELと以前の式の構文が混在しているため、あまりエレガントではありませんが、追加のJavaコードは必要ありません。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<c:set var="interfaceClass" value="<%=com.example.ClassA.class%>"/>
<c:set var="implementationClass" value="${model['class']}"/>
<c:if test="${interfaceClass.isAssignableFrom(implementationClass)}">
    <%-- Your logic here. --%>
</c:if>
于 2017-05-31T14:31:05.557 に答える
0

そのためにヘルパーBeanを使用できます。

@ManagedBean
public class Helper {
  public boolean isInstance(Object bean, String fullyQualifiedClassName) {
    return Class.forName(fullyQualifiedClassName).isInstance(bean);
  }
}

使用法:

<h:link rendered="#{helper.isInstance(model, 'package.ClassA')}">
  #{errorMessage1}
</h:link>

これには、継承が考慮され、変更できないクラスをテストできるという利点があります(BalusCのソリューションの両方の欠点)。

単純なクラス名を使用したい場合(名前の衝突を恐れない場合)は、手動で、またはorg.reflectionsのようなクラスパススキャナーを使用して入力するルックアップマップを使用できます。

@ManagedBean
@ApplicationScoped
public class Helper {
  private Map<String, Class<? extends MyBaseClass>> classes = 
      new Reflections("myrootpackage").getSubTypesOf(MyBaseClass.class).stream()
      .collect(Collectors.toMap(Class::getSimpleName, Function.identity()));

  public boolean isInstance(Object bean, String simpleClassName) {
    final Class<? extends MyBaseClass> c = this.classes.get(simpleClassName);
    return c != null && c.isInstance(bean);
  }
}

ヘルパー関数をELResolverに移動することもできます。

public class InstanceOfELResolver extends ELResolver {

  public Object invoke(final ELContext context, final Object base, 
      final Object method, final Class<?>[] paramTypes, final Object[] params) {
    if ("isInstanceOf".equals(method) && params.length == 1) {
      context.setPropertyResolved(true);
      try {
        return params[0] != null && Class.forName(params[0].toString()).isInstance(base);
      } catch (final ClassNotFoundException e) {
        return false;
      }
    }
    return null;
  }

  // ... All other methods with default implementation ...
}

使用法:

<h:link rendered="#{model.isInstanceOf('package.ClassA')}">
  #{errorMessage1}
</h:link>
于 2018-06-01T09:40:24.347 に答える