2011-11-27 68 views
8

Tôi đang tạo một cuốn sách khách đơn giản trong JSP để tìm hiểu công nghệ này. Hiện tại tôi có hai lớp: guestbook/GuestBook.class và guestbook/Entry.class (tôi chưa hoàn thành ứng dụng, vì vậy tôi chỉ có các lớp này) được thêm vào WEB-INF/libs/và chúng được bao gồm đúng cách . Trong tệp index.jsp của tôi, tôi đang sử dụng lớp guestbook.GuestBook; phương thức của nó trả về Vector. Khi tôi duyệt qua các mục và tôi muốn in một tác giả của entry, tôi có thể thấy:JSP, EL tài sản không tìm thấy

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

Tôi phải thêm rằng lớp Entry là công và thuộc tính tác giả được khai báo theo cách như vậy:

public String author; 

Vì vậy, nó cũng là công khai. Đây là mã của tôi khi tôi lặp qua các mục:

<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 

lợi nhuận guestbook.Entry

Các lớp học nằm trong gói lưu bút (như bạn có thể đoán), mục vector là được chuyển đến pageContext.

Tôi không biết mình đang làm gì sai. Ai có thể giúp tôi với điều đó không? (Cảm ơn trước!)

Trả lời

8

JSP EL sẽ không nhận ra trường công khai trong lớp học của bạn, nó chỉ hoạt động với phương thức getter (thực hành tốt - không bao giờ để lộ trạng thái của lớp học của bạn dưới dạng trường công khai như thế này).

Vì vậy, sử dụng

private String author; 

public String getAuthor() { 
    return author; 
} 

thay vì

public String author; 

Là một mặt lưu ý, JSTL của bạn là quá phức tạp, nó có thể được đơn giản hóa để:

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

hoặc thậm chí

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

mặc dù biểu mẫu thứ hai sẽ không loại trừ XML tên tác giả, vì vậy không được khuyên.

Cuối cùng, lớp Vector đã lỗi thời, bạn nên sử dụng ArrayList thay thế.

3

Bạn cũng có thể sửa đổi EL-resolver để truy cập vào các trường công cộng nếu không tìm thấy getter. Để làm điều này, trước tiên bạn cần phải tạo ra ELResolver đặc biệt của bạn:

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

Sau đó, bạn cần một lớp học để giúp bạn cấu hình nó:

public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener { 

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

    public void contextDestroyed(ServletContextEvent event) { 
    } 
} 

Cuối cùng bạn cần phải chạy này configurer lớp khi servlet khởi động. Thực hiện việc này bằng cách thêm lớp này làm người nghe servlet trong web.xml của bạn:

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

Bây giờ bạn có thể tham khảo các trường công khai trong JSP của bạn.

+0

Ném một StackOverflowException :) Có vẻ như 'return context.getELResolver(). GetValue ( ngữ cảnh, cơ sở, thuộc tính);' gọi cùng một thực thi 'getValue'. –

0

Tôi gặp sự cố trong Đường dẫn xây dựng. javax.servlet.jsp.jstl-1.2.1.jar đã bị xóa nhưng không bị xóa khỏi Đường dẫn xây dựng. Sau khi gỡ bỏ nó từ Build Path Property 'xxx' không tìm thấy vấn đề biến mất.

Các vấn đề liên quan