Apache Wicket:在表单验证器中注入依赖项(使用Guice)

时间:2013-06-24 21:19:12

标签: validation dependency-injection wicket guice

(这基本上是对this question的跟进。)

我需要在我的一个表单验证器中访问数据库服务层(以确保在注册新用户时尚未收到电子邮件)。

我尝试了以下内容(为简洁起见省略了一些输入字段):

public class RegistrationPage extends WebPage {

    @Inject
    private UserService userService;

    public RegistrationPage() {

        add(new FeedbackPanel("feedback"));

        TextField<String> email = new TextField<String>("email", Model.of(""));

        ...

        email.add(new IValidator<String>() {

            @Override
            public void validate(IValidatable<String> validatable) {

                String email = validatable.getValue();

                if (userService.findUserByEmail(email) != null) {

                    // report error...

                }
            }
        });

        Form<?> form = new Form<Void>("registrationForm") { ... };

        form.add(email);
        add(form);
    }
}

不幸的是,这会导致

java.lang.IllegalStateException: EntityManager is closed

我怀疑问题是由于我正在使用open-session-in-view并且多个表单提交跨越多个请求。 userService为第一个请求注入,并且(非法)在后续请求中重用。 (如果验证失败并且用户再次尝试提交表单,则会发生多个表单提交。)

我的问题

解决此问题的最佳方法是什么?就像我解决上一个similar problem一样?在这种情况下,无疑会变得更加混乱。

1 个答案:

答案 0 :(得分:0)

你想要的生命周期和wicket使用的生命周期有点不同。

首先想一想,了解Wicket组件的实例和注入:

  1. 实例组件
  2. 调用注射器 - IComponentInstantionListener.onInstantiation(组件组件)
  3. 注入注释字段
  4. 使用组件(渲染等)
  5. 下一个请求 - 使用带注入字段的相同组件
  6. 怎么办? 使用注入字段的代理类。当调用代理类时,它会使用当前的bean。

    请参阅http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/spring/injection/annot/SpringComponentInjector.html

    处的SprinComponentInejctor

    http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.html

    处的AnnotProxyFieldValueFactory

    即使您必须编写自己的实现或查看Wicket Contrib或Wicket Stuff。