Tapestry 5 BeanEditForm组件出现问题

时间:2011-03-20 03:00:55

标签: tapestry

我在弄清楚如何使用BeanEditForm组件时遇到了一些麻烦。 你知道,只要我没有为我的bean类使用参数化构造函数(我很需要它们),一切都很好(它显示它应该是什么)。这就是我的Bean类的样子:

public class Celebrity {
    private String firstName;
    private String lastName;
    private long ID;
    private Date dateOfBirth;
    private Occupation occupation;
    private String biography;
    private boolean birthDateVerified;

    public Celebrity() {
    }

    public Celebrity(String firstName, String lastName, Date dateOfBirth, Occupation occupation, String biography, boolean birthDateVerified) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
        this.occupation = occupation;
        this.biography = biography;
        this.birthDateVerified = birthDateVerified;
    }

    public Celebrity(String firstName, String lastName, Date dateOfBirth, Occupation occupation) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
        this.occupation = occupation;
    }


    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }


    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public long getID() {
        return ID;
    }

    public void setID(long ID) {
        this.ID = ID;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public Occupation getOccupation() {
        return occupation;
    }

    public void setOccupation(Occupation occupation) {
        this.occupation = occupation;
    }

    /**
     * @return the biography
     */
    public String getBiography() {
        return biography;
    }


    public void setBiography(String biography) {
        this.biography = biography;
    }

    public boolean getBirthDateVerified() {
        return birthDateVerified;
    }

    public void setBirthDateVerified(boolean birthDateVerified) {
        this.birthDateVerified = birthDateVerified;
    }
}

这是我的挂毯模板:AddNewCelebrity.tml

<html t:type="layout" title="Celebrity Details"
      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
      xmlns:p="tapestry:parameter">

    <head>
        <Title>Adding new celebrety</Title>
    </head>

    <body>
        <t:beaneditform t:id="celebrity"/>
    </body>

</html>

它的Java类:

public class AddNewCelebrity {

    @Persist
    private Celebrity celebrity;

    public Celebrity getCelebrity() {
        return celebrity;
    }

    public void setCelebrity(Celebrity celeb) {
        this.celebrity = celeb;
    }
}

当我不对我的参数化构造函数进行注释时,这是我从tapestry获得的错误:

  

SetupRender中的渲染队列错误[AddNewCelebrity:celebrity.editor]:异常实例化com.celebreties.celebs.model.Celebrity的实例(对于组件'AddNewCelebrity:celebrity.editor'):调用构造函数com.celebreties.celebs时出错。 model.Celebrity(String,String,Date,Occupation,String,boolean)(在Celebrity.java:29)(对于服务'BeanModelSource'):没有服务实现接口java.lang.String。

我正在使用带有Tomcat 6.0.32的tapestry 5.2.4

请提供一些指导方针。

5 个答案:

答案 0 :(得分:5)

显然,BeanEditForm不知道要传递给构造函数的参数。它试图为每个参数寻找匹配的服务,但No service implements the interface java.lang.String因此无法完成。我无法解释为什么它不会简单地使用no-args构造函数而不是尝试猜测其他构造函数之一的参数。

然而,您可以通过在将对象作为参数传递之前自己实例化对象来轻松解决此问题:

public Celebrity getCelebrity() {
    if (celebrity == null) {
      celebrity = new Celebrity(...);
    }
    return celebrity;
}

答案 1 :(得分:2)

前段时间我遇到过类似的问题。 请查看以下主题:http://tapestry-users.832.n2.nabble.com/T5-2-Constructor-issue-td5603058.html

应该帮助您使用@Inject

注释默认构造函数

此致 Michał

答案 2 :(得分:2)

这是最近添加的官方常见问题解答:

http://tapestry.apache.org/beaneditform-faq.html

当您呈现BeanEditForm时,或者提交呈现的表单时,Tapestry必须实例化要编辑的对象的实例。当BeanEditForm的object参数绑定为null时会发生这种情况:Tapestry实例化属性类型的实例,以便BeanEditForm有一个对象从中读取默认值,或者将提交的值推送到。

默认情况下,它使用标准注入机制,这意味着Tapestry将识别具有最多参数的公共构造函数,并尝试为每个构造函数参数查找对象和其他对象。

有两种方法可以对此进行微调,以免出错:

将@Inject注释放在要使用的正确构造函数上(通常是没有参数的构造函数)。

public class MyBean {
   @Inject
   public MyBean() { ... }


   // For testing
   public MyBean(String value, boolean flag, int index) { ... }

   ...
}

或者,为“prepare”事件提供事件处理程序方法,并将实例化的实例放入属性中。

public class MyPage {
  @Property
  public MyBean myBean;

  // The template contains <t:beaneditform t:id="mybeaneditor"/> ...

  void onPrepareFromMyBeanEditor() {
    myBean = new MyBean();
  }
}

答案 3 :(得分:1)

几分钟前我遇到了类似的问题。我正在使用netbeans和我从数据库导入的实体类。无论如何,如果您导入了实体类,IDE会生成3个构造函数,而您真正需要的只是一个 - 空的,您可以简单地擦除其他两个构造函数,如果添加@Property注释,它将正常工作。

像这样:

 @Property
 @Persist
 private Celebrity celebrity;

并删除实体类中的这两个构造函数!

此致 米洛斯·D。

答案 4 :(得分:-2)

如果需要更多构造函数,只需将@Inject注释放在默认构造函数之上。您将能够使用带参数的构造函数,Tapestry将使用默认构造函数。