В моем $ 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);
}
}
Для 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);
}
}
}