扩展Wicket的序列化测试

Adr*_*Cox 5 java wicket jpa-2.0

我正在开发一个使用Wicket 1.5和Hibernate/JPA 2的大型Java应用程序.Wicket有一个标准规则,即存储在会话中的对象必须实现Serializable.我们有一个额外的规则,即JPA管理对象不能存储在会话中.而是通过可拆卸模型在每个请求上加载JPA托管对象.

更复杂的是,在会话中存储Entity对象是合法的,前提是它尚未持久存在.结果,我们的一些课程已经实施Serializable.

如果我想扩展Wicket的序列化测试来检测JPA拥有的对象,我该怎么做呢?如果没有Wicket的本地分支,这可能吗?

Mar*_*rst 5

在我的$ dayjob,我们使用你描述的东西,以及我在几次聚会上呈现的东西(见幻灯片23及其后).你不必为此分叉Wicket.

基本上你要做的是复制序列化器检查器代码并修改它以包括你的检查以及检查序列化错误.然后,在请求周期的最后阶段,您将在受影响的页面上运行自己的序列化程序检查程序.

我们创建的检查检查了我们的公共基类,实体是否持久化了.如果是这样,我们就失败了.另外,我们在基页中有一个Ajax回调,用于检查会话属性以查看是否存在序列化错误.如果是这样,我们将重定向到序列化失败的错误页面,以确保开发人员不会忽略页面层次结构中的实体.

这是我们检查器的核心(check从Wicket的序列化程序检查重写的方法):

private void check(Object obj)
{
    if (obj == null || obj.getClass().isAnnotationPresent(Deprecated.class)
        || obj.getClass().isAnnotationPresent(SkipClass.class))
    {
        return;
    }

    Class< ? > cls = obj.getClass();
    nameStack.add(simpleName);
    traceStack.add(new TraceSlot(obj, fieldDescription));

    if (!(obj instanceof Serializable) && (!Proxy.isProxyClass(cls)))
    {
        throw new WicketNotSerializableException(toPrettyPrintedStack(obj.getClass().getName())
            .toString(), exception);
    }
    if (obj instanceof IdObject)
    {
        Serializable id = ((IdObject) obj).getIdAsSerializable();
        if (id != null && !(id instanceof Long && ((Long) id) <= 0))
        {
            throw new WicketContainsEntityException(toPrettyPrintedStack(
                obj.getClass().getName()).toString(), exception);
        }
    }
    if (obj instanceof LoadableDetachableModel)
    {
        LoadableDetachableModel< ? > ldm = (LoadableDetachableModel< ? >) obj;
        if (ldm.isAttached())
        {
            throw new WicketContainsAttachedLDMException(toPrettyPrintedStack(
                obj.getClass().getName()).toString(), exception);
        }
    }
Run Code Online (Sandbox Code Playgroud)

对于Wicket 1.5,我们创建了自己的PageStoreManager执行这些检查(以及许多其他事情,例如为我们的用户启用服务器端浏览历史记录).我们RequestAdapter通过覆盖PageStoreManager#newRequestAdapter(IPageManagerContext context)并在适配器中执行序列化检查来提供我们自己的:

class DetachCheckingRequestAdapter extends RequestAdapter
{
    public DetachCheckingRequestAdapter(IPageManagerContext context)
    {
        super(context);
    }

    @Override
    protected void storeTouchedPages(List<IManageablePage> touchedPages)
    {
        super.storeTouchedPages(touchedPages);
        if (Application.get().usesDevelopmentConfig())
        {
            for (IManageablePage curPage : touchedPages)
            {
                if (!((Page) curPage).isErrorPage())
                    testDetachedObjects(curPage);
            }
        }
    }

    private void testDetachedObjects(final IManageablePage page)
    {
        try
        {
            NotSerializableException exception = new NotSerializableException();
            EntityAndSerializableChecker checker = new EntityAndSerializableChecker(exception);
            checker.writeObject(page);
        }
        catch (Exception ex)
        {
            log.error("Couldn't test/serialize the Page: " + page + ", error: " + ex);
            Session.get().setDetachException(ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)