2011-11-27 19 views
8

Estoy creando un libro de visitas simple en JSP para aprender esta tecnología. Actualmente tengo dos clases: guestbook/GuestBook.class y guestbook/Entry.class (todavía no he terminado la aplicación, así que solo tengo estas clases) que se agregan a WEB-INF/libs/y están incluidas correctamente . En mi archivo index.jsp estoy usando guestbook.GuestBook class; su método devuelve Vector. Cuando iterar sobre las entradas y me gustaría imprimir un autor de la entrada, puedo ver:Propiedad JSP, EL no encontrada

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

debo añadir que la clase de entrada es pública y el atributo autor se declara de tal manera:

public String author; 

Así que es público, también. Este es mi código cuando iterar sobre las entradas:

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

y

entry.class.name 

vuelve guestbook.Entry

Las clases son en el libro de paquetes (como se puede adivinar), entradas vector es pasado a pageContext.

No sé qué hay de malo en mi forma de hacerlo. ¿Alguien puede ayudarme por favor con eso? (¡Gracias de antemano!)

Respuesta

8

JSP EL no reconocerá los campos públicos en sus clases, solo funciona con métodos getter (lo cual es una buena práctica de todos modos: nunca exponga el estado de sus clases como campos públicos como este).

Así que utilice

private String author; 

public String getAuthor() { 
    return author; 
} 

en lugar de

public String author; 

Como nota al margen, el JSTL es demasiado complicado, se puede simplificar a:

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

o incluso

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

aunque la última forma no escapará XML del nombre del autor, por lo que no se recomienda.

Por último, la clase Vector está obsoleta, en su lugar debe usar ArrayList.

3

También puede modificar EL-resolver para acceder a los campos públicos si no se encuentra un getter. Para ello, primero tiene que crear su ELResolver especial:

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

entonces necesita una clase para ayudar a configurarlo:

public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener { 

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

    public void contextDestroyed(ServletContextEvent event) { 
    } 
} 

Por fin se necesita para ejecutar esta clase configurador cuando el servlet se inicia. Para ello, agregue esta clase como oyente servlet en su web.xml:

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

Ahora se puede hacer referencia a los campos públicos en las JSP.

+0

Lanza una StackOverflowException :) Parece que 'return context.getELResolver(). GetValue ( context, base, property);' llama a la misma implementación 'getValue'. –

0

Tuve un problema en Build Path. javax.servlet.jsp.jstl-1.2.1.jar se eliminó pero no se eliminó de la ruta de compilación. Después de eliminarlo de Build Path Property, el problema 'xxx' no encontrado desapareció.

Cuestiones relacionadas