2011-11-27 6 views
8

Sto creando un semplice libro degli ospiti in JSP per apprendere questa tecnologia. Attualmente ho due classi: guestbook/GuestBook.class e guestbook/Entry.class (non ho ancora finito l'app, quindi ho solo queste classi) che sono aggiunte a WEB-INF/libs/e sono incluse correttamente . Nel mio file index.jsp sto usando la classe guestbook.GuestBook; il suo metodo restituisce Vector. Quando ho iterare su voci e mi piacerebbe stampare un autore della voce, posso vedere:JSP, proprietà EL non trovata

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

devo aggiungere che classe di ingresso è pubblico e l'attributo autore viene dichiarato in modo tale:

public String author; 

Quindi è anche pubblico. Questo è il mio codice quando ho iterare sulle voci:

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

e

entry.class.name 

rendimenti guestbook.Entry

Le classi sono a pacchetto Guestbook (come si può intuire), le voci di vettore è passato a pageContext.

Non so cosa c'è di sbagliato nel mio modo di farlo. Qualcuno può aiutarmi per favore con quello? (Grazie in anticipo!)

risposta

8

JSP EL non riconoscerà i campi pubblici nelle classi, funziona solo con metodi getter (che è comunque una buona pratica - non esporre mai lo stato delle classi come campi pubblici come questo).

Così utilizzare

private String author; 

public String getAuthor() { 
    return author; 
} 

invece di

public String author; 

Come nota a margine, il vostro JSTL è troppo complicato, si può essere semplificata:

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

o addirittura

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

sebbene quest'ultimo non sia XML-escape il nome dell'autore, quindi non è consigliato.

Infine, la classe Vector è obsoleta, è invece necessario utilizzare ArrayList.

3

È anche possibile modificare il resolver EL per accedere ai campi pubblici se non si trova un getter. Per fare questo, è necessario prima creare l'ELResolver speciale:

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) { 
    } 
} 

allora avete bisogno di una classe per la configurazione è:

public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener { 

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

    public void contextDestroyed(ServletContextEvent event) { 
    } 
} 

Finalmente è necessario eseguire questo configuratore di classe quando la il servlet si avvia. Fare questo con l'aggiunta di questa classe come un ascoltatore servlet in web.xml:

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

Ora è possibile fare riferimento ai campi pubblici in JSP.

+0

Genera una StackOverflowException :) Sembra che 'restituisca context.getELResolver(). GetValue ( contesto, base, proprietà);' chiama la stessa implementazione 'getValue'. –

0

Ho avuto un problema in Build Path. javax.servlet.jsp.jstl-1.2.1.jar è stato eliminato ma non rimosso dal percorso di creazione. Dopo averlo rimosso dalla proprietà Build Path, il problema "xxx" non è scomparso.