Tapestry 5 BeanEditForm组件出现问题

发布于 2024-10-24 10:50:03 字数 3401 浏览 4 评论 0原文

我在弄清楚如何使用 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;
    }
}

这是当我不注释参数化构造函数时从挂毯中得到的错误:

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。

我正在使用 Tapestry 5.2.4 和 Tomcat 6.0.32

请给出一些指导方针我能做什么。

I am having a bit trouble figuring out how to work with BeanEditForm component.
You see, everything is fine with it (it displays what it should) as long as i don't use parametrized constructors for my bean class (and i kind a need them). This is how my Bean class looks like:

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;
    }
}

This is my tapestry template: 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>

And its Java class:

public class AddNewCelebrity {

    @Persist
    private Celebrity celebrity;

    public Celebrity getCelebrity() {
        return celebrity;
    }

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

This is the error that I get from tapestry when i don't comment my parametrized constructors:

Render queue error in SetupRender[AddNewCelebrity:celebrity.editor]: Exception instantiating instance of com.celebreties.celebs.model.Celebrity (for component 'AddNewCelebrity:celebrity.editor'): Error invoking constructor com.celebreties.celebs.model.Celebrity(String, String, Date, Occupation, String, boolean) (at Celebrity.java:29) (for service 'BeanModelSource'): No service implements the interface java.lang.String.

I'm using tapestry 5.2.4 with Tomcat 6.0.32

Please give some guidelines what can I do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟凡古楼 2024-10-31 10:50:03

显然,BeanEditForm 不知道将哪些参数传递给构造函数。它尝试为每个参数寻找匹配的服务,但没有服务实现 java.lang.String 接口,因此无法完成。我无法真正解释为什么它不会简单地使用无参数构造函数,而是尝试猜测其他构造函数之一的参数。

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

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

Apparently, the BeanEditForm doesn't know what parameters to pass to the constructor. It tries to look for a matching service for each parameter but No service implements the interface java.lang.String so it can't be done. I can't really explain why it won't simply use the no-args constructor instead of trying to guess parameters for one of the other constructors.

Nevertheless, you can easily work around this by simply instantiating the object yourself before passing it as a parameter:

public Celebrity getCelebrity() {
    if (celebrity == null) {
      celebrity = new Celebrity(...);
    }
    return celebrity;
}
哑剧 2024-10-31 10:50:03

我前段时间也遇到过类似的问题。
请检查此线程:http://tapestry- users.832.n2.nabble.com/T5-2-Constructor-issue-td5603058.html

应该对您有帮助的是 默认构造函数

使用 @Inject注解
米哈乌

I had similar problem some time ago.
Please check this thread: http://tapestry-users.832.n2.nabble.com/T5-2-Constructor-issue-td5603058.html

What should help you is to annotate default constructor with @Inject

Regards
Michał

昵称有卵用 2024-10-31 10:50:03

最近将此添加为官方常见问题解答:

http://tapestry.apache.org/beaneditform-faq。 当您渲染BeanEditForm

或提交渲染的表单时,Tapestry 必须实例化要编辑的对象的实例。当 BeanEditForm 的对象参数绑定为 null 时,会发生这种情况:Tapestry 实例化属性类型的实例,以便 BeanEditForm 具有一个对象来读取默认值或将提交的值推入其中。

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

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

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

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


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

   ...
}

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

public class MyPage {
  @Property
  public MyBean myBean;

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

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

This was recently added as an official FAQ:

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

When you render a BeanEditForm, or when the rendered form is submitted, Tapestry must instantiate an instance of the object to be edited. This occurs when the BeanEditForm's object parameter is bound to null: Tapestry instantiates an instance of the property type so that the BeanEditForm has an object to read default values from, or to push submitted values into.

By default, this uses the standard injection mechanism, which means that Tapestry will identify the public constructor with the most parameters, and attempt to find objects and other objects for each constructor parameter.

There's two ways to fine tune this so you don't get errors:

Place an @Inject annotation on the correct constructor to use (often, the constructor with no parameters).

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


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

   ...
}

Or, provide an event handler method for the "prepare" event, and put an instantiated instance into the property.

public class MyPage {
  @Property
  public MyBean myBean;

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

  void onPrepareFromMyBeanEditor() {
    myBean = new MyBean();
  }
}
给妤﹃绝世温柔 2024-10-31 10:50:03

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

像这样:

 @Property
 @Persist
 private Celebrity celebrity;

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

问候,
米洛斯·D.

I encountered the similar problem just a few minutes ago. I am using netbeans and i imported entity classes from databes. Anyway if you imported entity classes IDE generates 3 constructors, and all you really need is one - the empty one, su you can simply erase the other two constructors and it will work fine if you add @Property annotation.

like so:

 @Property
 @Persist
 private Celebrity celebrity;

and erase those two constructors in entity class!

Regards,
Milos D.

穿越时光隧道 2024-10-31 10:50:03

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

If you need more constructors, just put annotation @Inject above default constructor. You will be able to use constructor with parameters, and Tapestry will use default constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文