2011-11-27 35 views
8

私はこの技術を学ぶためにJSPで簡単なゲストブックを作成しています。私はWEB-INF/libs /に追加されているguestbook/GuestBook.classとguestbook/Entry.classという2つのクラスを持っています(まだ完成していないので、これらのクラスしかありません)。 。私のファイルindex.jspではguestbook.GuestBookクラスを使用しています。そのメソッドはVectorを返します。私はエントリを反復処理すると、私はエントリの著者を印刷したい場合は、私が見ることができます:JSP、ELプロパティが見つかりません

javax.el.PropertyNotFoundException: Property 'author' not found on type guestbook.Entry 

は、私がそのエントリクラスは公共であると著者属性は、このような方法で宣言されて追加する必要があります。

public String author; 

だから公開です。私はエントリを反復処理するとき、これは私のコードです:

<c:forEach items="${entries}" varStatus="i"> 
    <c:set var="entry" value="${entries[i.index]}" /> 
    <li><c:out value="${entry.author}" /></li> 
</c:forEach> 

entry.class.name 

戻りエントリベクトルは、

クラスは、パッケージゲストブック(あなたが推測できる通り)にあるguestbook.Entry pageContextに渡されます。

自分のやり方が間違っているかどうかわかりません。誰も私にそれをどうお手伝いできますか?

答えて

8

JSP ELはあなたのクラスのパブリックフィールドを認識しません。ゲッターメソッドでしか動作しません(このようなパブリックフィールドとしてクラスの状態を公開しないでください)。

<c:forEach items="${entries}" var="entry"> 
    <li><c:out value="${entry.author}" /></li> 
</c:forEach> 

あるいは

ので、注意点として代わりに

public String author; 

private String author; 

public String getAuthor() { 
    return author; 
} 

を使用し、あなたのJSTLが過度に複雑で、それはのように簡略化することができます

<c:forEach items="${entries}" var="entry"> 
    <li>${entry.author}</li> 
</c:forEach> 

ですが、後者のフォームでは著者名をエスケープしないため、推奨されません。

最後に、Vectorクラスは廃止されました。代わりにArrayListを使用する必要があります。

3

getterが見つからない場合は、パブリックフィールドにアクセスするようにELリゾルバを変更することもできます。これを行うには、あなたが最初にあなたの特別なELResolver作成する必要があります。

public class PublicFieldSupportingELResolver extends ELResolver { 

    @Override 
    public Class<?> getCommonPropertyType(ELContext context, Object base) { 
     return null; 
    } 

    @Override 
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) { 
     return null; 
    } 

    @Override 
    public Class<?> getType(ELContext context, Object base, Object property) { 
     return null; 
    } 

    @Override 
    public Object getValue(ELContext context, Object base, Object property) { 
     try { 
      return context.getELResolver().getValue(
        context, base, property); 
     } catch(RuntimeException ex) { 
      if(property instanceof String && base != null) { 
       try { 
        Field field = base.getClass().getDeclaredField((String) property); 
        Object value = field.get(base); 
        context.setPropertyResolved(true); 
        return value; 
       } catch (Exception e) { 
        throw new PropertyNotFoundException(e); 
       } 
      } else { 
       throw ex; 
      } 
     } 
    } 

    @Override 
    public boolean isReadOnly(ELContext context, Object base, Object property) { 
     return false; 
    } 

    @Override 
    public void setValue(ELContext context, Object base, Object property, Object value) { 
    } 
} 

は、その後、あなたが助けるためにクラスが必要にあなたはそれを設定します。

public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener { 

    public void contextInitialized(ServletContextEvent event) { 
     JspFactory.getDefaultFactory() 
       .getJspApplicationContext(event.getServletContext()) 
       .addELResolver(new PublicFieldSupportingELResolver()); 
    } 

    public void contextDestroyed(ServletContextEvent event) { 
    } 
} 

をで最後にあなたはときに、このコンフィギュラクラスを実行する必要がありますサーブレットが起動します。これを行うには、このクラスをweb.xmlのサーブレットリスナーとして追加します。

<listener> 
    <listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class> 
    </listener> 

これで、JSPのパブリックフィールドを参照できます。

+0

StackOverflowExceptionがスローされました。「return context.getELResolver()。getValue( context、base、property);」と同じgetValue実装を呼び出します。 –

0

ビルドパスに問題がありました。 javax.servlet.jsp.jstl-1.2.1.jarは削除されましたが、ビルドパスから削除されませんでした。ビルドパスプロパティから 'xxx'を削除した後、問題が見つかりませんでした。

関連する問題