Wicket为什么在新标签页中打开链接时页面过期?

灵魂磁铁

我正在构建具有以下规范的wicket bootsrap Web应用程序(来自pom.xml):

检票口版本:6.15.0

wicket-bootstrap-core.version:0.9.3-SNAPSHOT

我有一个基础页面,它是我其他页面的父页面,并添加了标记在顶部的水平导航栏,其中包含关键组件:

BootstrapBookmarkablePageLink扩展了BookmarkablePageLink

这是我的BasePage.java的一部分

public abstract class BasePage extends GenericWebPage<Void> {

private static final long serialVersionUID = 1L;
String username;

public WicketApplication getApp() {
    return WicketApplication.class.cast(getApplication());
}

public BasePage(final PageParameters parameters) {
    super(parameters);

    // Read session data
    cachedUsername = (String)
BasicAuthenticationSession.get().getAttribute("username");

    // create navbar
    add(newNavbar("navbar"));

}

/**
 * @return application properties
 */
public Properties getProperties() {
    return WicketApplication.get().getProperties();
}

/**
 * creates a new {@link Navbar} instance
 *
 * @param markupId
 * The components markup id.
 * @return a new {@link Navbar} instance
 */

protected Navbar newNavbar(String markupId) {
    Navbar navbar = new Navbar(markupId) {
        private static final long serialVersionUID = 1L;

        @Override
        protected TransparentWebMarkupContainer newCollapseContainer(String  
componentId) {
            TransparentWebMarkupContainer container = 
super.newCollapseContainer(componentId);
            container.add(new CssClassNameAppender("bs-navbar-collapse"));
            return container;
        }
    };

    navbar.setPosition(Navbar.Position.TOP);
    // navbar.setInverted(true);

    NavbarButton<Void> myTab = new NavbarButton<Void>(MyPage.class, new  
PageParameters().add("name", "")
            .add("status", "All").add("date", ""), Model.of("My page"));
    NavbarButton<Void> myOtherTab = new NavbarButton<Void>
(MyOtherPage.class, new PageParameters().add("status", "initial")
            .add("date", ""), Model.of("My other page"));


navbar.addComponents(NavbarComponents.transform(
Navbar.ComponentPosition.LEFT, 
myTab, myOtherTab));

    return navbar;
}
}

然后,MyPage呈现一个过滤器表单,一个html表,ajaxbuttons和一些链接。我的一些组件是ajax组件:

public class MyPage extends BasePage {
private static final long serialVersionUID = 5772520351966806522L;
@SuppressWarnings("unused")
private static final Logger LOG = LoggerFactory.getLogger(MyPage.class);
private static final Integer DAYS = 270;

private DashboardFilteringPageForm filteringForm;
private CityInitialForm ncForm;
private String CityName;
private String startDate;
private CitysTablePanel citysTable;
private WebMarkupContainer numberOfNodes;

public MyPage(PageParameters parameters) throws ParseException {
    super(parameters);

    // get Citys list from repo
    final List<City> repoCitys = (List<City>) methodToGetCities();

    // select number of nodes
    numberOfNodes = new WebMarkupContainer("numberOfNodes") {
        private static final long serialVersionUID = 5772520351966806522L;
    };
    numberOfNodes.setOutputMarkupId(true);

    ncForm = new CityInitialForm("ncForm");

    // validation
    add(new FeedbackPanel("feedbackPanel")).setOutputMarkupId(true);
    ncForm.getNumberField().setRequired(true);

    ncForm.add(new AjaxButton("ncButton") {
        private static final long serialVersionUID = -6846211690328190809L;

        @Override
        protected void onInitialize() {
            super.onInitialize();
            add(newAjaxFormSubmitBehavior("change"));
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {

            // redirect to other page

        }

        @Override
        protected void updateAjaxAttributes(AjaxRequestAttributes 
attributes) {
            super.updateAjaxAttributes(attributes);
            attributes.getAjaxCallListeners().add(new 
DisableComponentListener(citysTable));
        }

    });

    numberOfNodes.add(ncForm);

    // filters
    CityName = parameters.get("name").toString() == null ? "" : 
parameters.get("name").toString();
    startDate = parameters.get("date").toString();

    filteringForm = new DashboardFilteringPageForm("filteringForm") {
        private static final long serialVersionUID = -1702151172272765464L;
    };

    // initialize form inputs
    filteringForm.setCityName(CityName);
    try {
        filteringForm.setStartDate(new SimpleDateFormat("EE MMM dd HH:mm:ss 
z yyyy", Locale.ENGLISH)
                .parse(getStartDate().equals("") ? 
CortexWebUtil.subtractDays(new Date(), DAYS).toString() : getStartDate()));
    } catch (Exception e) {
        setResponsePage(SignInPage.class, new PageParameters());
    }

    filteringForm.add(new AjaxButton("button") {
        private static final long serialVersionUID = -6846211690328190809L;

        @Override
        protected void onInitialize() {
            super.onInitialize();
            add(newAjaxFormSubmitBehavior("change"));
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> paForm) {
            // retrieve Citys
            filterCitysAjax(target, "All");
        }

        @Override
        protected void updateAjaxAttributes(AjaxRequestAttributes 
attributes) {
            super.updateAjaxAttributes(attributes);
            attributes.getAjaxCallListeners().add(new 
DisableComponentListener(citysTable));
        }

    });

    filteringForm.getCityNameTextField().add(new OnChangeAjaxBehavior() {

        private static final long serialVersionUID = 1468056167693038096L;

        @Override
        protected void onUpdate(AjaxRequestTarget target) {
            try {
                filterCitysAjax(target, "All");
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }

        }

        @Override
        protected void updateAjaxAttributes(AjaxRequestAttributes 
attributes) {
            super.updateAjaxAttributes(attributes);
            attributes.getAjaxCallListeners().add(new 
DisableComponentListener(citysTable));
        }
    });

    // new City link
    AjaxLink<Void> newCityLink = newCityLink("newCity", repoCitys);

    // Citys table
    citysTable = new CitysTablePanel("CitysTable", repoCitys);
    citysTable.setOutputMarkupId(true);

    // add components
    add(filteringForm, newCityLink, numberOfNodes, citysTable);

}


private void filterCitysAjax(AjaxRequestTarget target, String status) {

    methodToFilterResults();

    //  re-render table component 
    CitysTablePanel cityTableNew = new CitysTablePanel("CitysTable", citys);
    cityTableNew.setOutputMarkupId(true);
    cityTableNew.setVisibilityAllowed(true);
    cityTableNew.setVisible(true);
    citysTable.replaceWith(cityTableNew);
    target.add(cityTableNew);
    citysTable = cityTableNew;
    target.appendJavaScript(CortexWebUtil.TABLE_ODD_EVEN_ROWS);

}

private AjaxLink<Void> newCityLink(String string, final List<City> Citys) {

    final AjaxLink<Void> newCityLink = new AjaxLink<Void>(string) {
        private static final long serialVersionUID = -5420108740617806989L;

        @Override
        public void onClick(final AjaxRequestTarget target) {
                numberOfNodes.add(new AttributeModifier("style", 
"display:block"));
                target.add(numberOfNodes);
        }
    };

    // new City image
    Image newCityImage = new Image("newCityIcon", new 
ContextRelativeResource("/img/new_City_icon.png"));
    add(newCityLink);
    newCityLink.add(newCityImage);

    return newCityLink;

}

}

因此MyPage可以工作,但是当我在新选项卡中打开MyOtherPage Link并触发MyPage中的ajax组件(例如AjaxButton)时,我会收到页面过期错误。

为什么会这样呢?我需要使用无状态页面吗?无状态链接

为什么要在新选项卡中打开链接并使用Ajax组件这么麻烦?我一定很想念..

马丁

以下是一些可能的原因:

  • MyPage无法序列化

    Wicket将有状态页面存储在页面存储中(默认情况下在磁盘中)。稍后,当您单击有状态链接时,Wicket会尝试加载页面。首先,它会在http会话中查找该页面以其活动形式(即未序列化)的形式。如果找不到,则Wicket会在磁盘中查找。Wicket仅保留Http会话中最后一个用户请求中使用的页面(以保持较小的内存占用)。通过单击MyOtherPage链接,可以将MyOtherPage的实例放入Http会话,而旧实例(MyPage的实例)仅位于磁盘中。但是:如果MyPage无法序列化为byte [],则无法将其存储在磁盘中,因此以后的请求将因PageExpiredException而失败。

    待办事项:检查您的日志中是否包含NotSerializableException,并附上原因的调试信息。

  • MyOtherPage太大

    默认情况下,Wicket在磁盘中每个用户会话最多写入10M。如果假设MyPage为2M,而MyOtherPage为9M(两个大小都很大,但我不知道您的应用程序会发生什么...),则保存MyOtherPage将从磁盘上删除MyPage。以后尝试加载MyPage的尝试将失败,并显示PageExpiredException。

    待办事项:查看您对Wicket模型的使用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Vaadin在新标签页中打开链接

GWT在新标签页中打开页面

传递POST数据时,jQuery在新标签页中打开页面

在新标签页中打开链接或打开新窗口时,Google Chrome会清除当前页面的CSS样式

pandoc:在新标签页中打开链接

在结帐页面上的新标签页中打开“条款和条件”链接

我的html链接仅在新标签页中打开时打开?

在新标签页中打开链接的按钮

在新标签页中打开[innerHTML]绑定的Angular 6链接

在新标签页中打开应用程序页面时出现Angular Service Worker问题

如何使按钮在JavaScript的新标签页中打开链接?

在新标签页中打开页面

有什么办法可以从内部html(角度6)中的新标签页中打开链接

当对每个请求使用session_regenerate_id()时,为什么打开新标签会导致先前标签中的页面注销?

在新标签页中打开链接时,Firefox的HTTP引荐来源网址是什么?

WordPress中的jQuery .load(在新标签页中打开链接时出现问题)

如何使用JavaScript在新标签页中打开链接

phpBB在新标签页中打开链接

使用JQuery在新标签页中打开链接

在页面加载的新标签页中打开特定链接

在新标签页中打开时,修补程序链接变成get吗?

创建后,为什么Firefox仍会切换到新选项卡?没有打勾“当您在新标签页中打开链接时,请立即切换到该链接”

为什么超链接无法在新标签页中打开?

绑定点击事件以在新标签页中打开链接

重新编写页面上的所有链接以通过javascript在新标签页中打开

在新标签页中打开链接

使用标签助手时获取锚标签链接以在新标签页中打开

为什么带有 rel="noopener noreferrer" 的链接总是在新标签页中打开?

如何在使用 css 按钮时在新标签页中打开链接