使用 Wicket 制作一个主要无状态的 Web 应用程序是否困难?

发布于 2024-09-13 07:25:52 字数 560 浏览 16 评论 0原文

我已经使用 Wicket 一两个月了,用它制作简单的 Web 应用程序并习惯模型等等。现在我想继续前进,看看我是否可以运用到目前为止所学到的知识来使用并创建一个中型/大型 Web 应用程序。不过,我并没有花太多时间思考如何让页面无状态。

如果我理解正确的话,创建无状态页面是通过使页面可添加书签并确保没有有状态组件添加到页面来实现的。

对于我正在制作的网站,我想避免“页面过期”消息,让用户通过 cookie 登录,无需登录/创建会话即可使用大量内容,并且我希望分页等功能无状态且可添加书签。

这对于 PHP 等来说没有问题,但在我看来,很多有用的 Wicket 组件都是有状态的。我是否需要做很多工作,例如创建自己的一组无状态组件,或者这没什么大不了的?

我希望有人能帮助我,为我指明正确的方向。

编辑:假设我想创建一个博客。浏览帖子、类别等应该是可能的,而不必担心如果用户决定阅读一篇文章 2 小时,然后尝试通过分页等进一步导航,页面会过期。我希望允许用户一次保持登录状态一个月,但我也不想将他们的会话存储一个月。

我非常感谢任何关于如何使用 Wicket 完成我刚才描述的事情的帮助。

I've been working with Wicket for month or two now, making simple web applications with it and getting used to models and so forth. Now I'd like to move forward and see if I can put what I've learned so far to use and create a medium/large web application. However, I haven't spent much time thinking about how to make pages stateless.

If I understand correctly, making a stateless page is achieved by making the page bookmarkable and making sure that no stateful components are added to the page.

For the website I am making I want to avoid "Page expired" messages, let users be logged in via cookies, make a whole lot of the content available without needing to login/create a session, and I want functionality such as pagination to be stateless and bookmarkable.

This is no problem with e.g. PHP, but it seems to me that a whole lot of the useful Wicket components are stateful. Am I in for a whole lot of work, such as creating my own set of components that are stateless, or is it no big deal?

I hope someone can help me out by pointing me in the right direction.

EDIT: Lets say I wanted to make a blog. Browsing posts, categories and so on should be possible without having to worry that the page will have become expired if a user decides to read an article for 2 hours and then tries to navigate further via e.g. pagination. I want to allow users to stay logged in for a month at a time, but I do not exactly want to store their session for a month either.

I'd greatly appreciate any help on how I can accomplish what I just described, with Wicket.

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

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

发布评论

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

评论(2

香草可樂 2024-09-20 07:25:52

当使用 Wicket 构建无状态页面时,您确实会丢失大多数“智能”内置组件,例如分页表和树。

我认为这对于网站、博客等来说不是一个问题,它们通常具有相当简单的导航模型,并且不使用这种“丰富”组件,而是使用无状态服务器友好、基于 Javascript 的组件/效果,例如 jQuery-UI 或 YUI。

有些事情你会做不同的事情,比如分页。例如,您必须使用页面参数和无状态链接创建自己的机制,而不是使用内置分页组件:

HomePage.html

<html xmlns:wicket="http://wicket.apache.org">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
  <div class="container">

    <div wicket:id="posts">
      <h2 wicket:id="title"></h2>
      <p wicket:id="content"></p>
      Posted on <span wicket:id="date"></span>
    </div>

    <div>
      <a wicket:id="recentPosts"><< Recent posts</a>
      <a wicket:id="previousPosts">Previous posts >></a>
    </div>

  </div>
</body>
</html>

HomePage.java

package wishminimal.ui.home;

import java.util.Iterator;

import org.apache.wicket.PageParameters;
import org.apache.wicket.devutils.stateless.StatelessComponent;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import wishminimal.dao.PostDAO;
import wishminimal.entity.Post;

@StatelessComponent
public class HomePage extends WebPage {

    @SpringBean
    PostDAO postDAO;

    ISortableDataProvider<Post> dataProvider = new SortableDataProvider<Post>() {
        public Iterator<? extends Post> iterator(int first, int count) {
            return postDAO.findAll(first, count).iterator();
        }
        public int size() {
            return postDAO.countAll();
        }
        public IModel<Post> model(Post object) {
            return new CompoundPropertyModel<Post>(object);
        }
    };

    public HomePage(PageParameters params) {
        final int currentPage = params.getAsInteger("p", 0);

        final DataView<Post> dataView = new DataView<Post>("posts", dataProvider, 10) {
            @Override
            protected void populateItem(Item<Post> item) {
                item.add(new Label("title"));
                item.add(new Label("content"));
                item.add(new Label("date"));
            }
        };
        dataView.setCurrentPage(currentPage);
        add(dataView);

        add(new BookmarkablePageLink<Void>("recentPosts", getClass(), new PageParameters("p=" + (currentPage - 1))) {
            @Override
            public boolean isVisible() {
                return currentPage > 0;
            }
        });
        add(new BookmarkablePageLink<Void>("previousPosts", getClass(), new PageParameters("p=" + (currentPage + 1))) {
            @Override
            public boolean isVisible() {
                return currentPage < dataView.getPageCount();
            }
        });
    }
}

虽然这比有状态 Wicket 方便得多,但我仍然发现更好比说无状态 JSF 或 Struts :)

When building stateless pages with Wicket, you do lose most 'smart' built-in components, for example paginated tables and trees.

I think this is less an issue for sites, blogs and the like, which usually have a fairly simpler navigation model and don't use this kind of 'rich' component, and use stateless-server-friendly, Javascript-based components/effects, like jQuery-UI or YUI instead.

Some things you'll do differently, like pagination. For example, instead of using built-in pagination components, you'll have to make your own mechanism, using page parameters and stateless links:

HomePage.html

<html xmlns:wicket="http://wicket.apache.org">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
  <div class="container">

    <div wicket:id="posts">
      <h2 wicket:id="title"></h2>
      <p wicket:id="content"></p>
      Posted on <span wicket:id="date"></span>
    </div>

    <div>
      <a wicket:id="recentPosts"><< Recent posts</a>
      <a wicket:id="previousPosts">Previous posts >></a>
    </div>

  </div>
</body>
</html>

HomePage.java

package wishminimal.ui.home;

import java.util.Iterator;

import org.apache.wicket.PageParameters;
import org.apache.wicket.devutils.stateless.StatelessComponent;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import wishminimal.dao.PostDAO;
import wishminimal.entity.Post;

@StatelessComponent
public class HomePage extends WebPage {

    @SpringBean
    PostDAO postDAO;

    ISortableDataProvider<Post> dataProvider = new SortableDataProvider<Post>() {
        public Iterator<? extends Post> iterator(int first, int count) {
            return postDAO.findAll(first, count).iterator();
        }
        public int size() {
            return postDAO.countAll();
        }
        public IModel<Post> model(Post object) {
            return new CompoundPropertyModel<Post>(object);
        }
    };

    public HomePage(PageParameters params) {
        final int currentPage = params.getAsInteger("p", 0);

        final DataView<Post> dataView = new DataView<Post>("posts", dataProvider, 10) {
            @Override
            protected void populateItem(Item<Post> item) {
                item.add(new Label("title"));
                item.add(new Label("content"));
                item.add(new Label("date"));
            }
        };
        dataView.setCurrentPage(currentPage);
        add(dataView);

        add(new BookmarkablePageLink<Void>("recentPosts", getClass(), new PageParameters("p=" + (currentPage - 1))) {
            @Override
            public boolean isVisible() {
                return currentPage > 0;
            }
        });
        add(new BookmarkablePageLink<Void>("previousPosts", getClass(), new PageParameters("p=" + (currentPage + 1))) {
            @Override
            public boolean isVisible() {
                return currentPage < dataView.getPageCount();
            }
        });
    }
}

While this is much less convenient than stateful Wicket, I still find much better than say, stateless JSF or Struts :)

幻想少年梦 2024-09-20 07:25:52

为了使页面无状态,我执行以下操作:

  1. 使用可添加书签的页面
  2. 在所有情况下都使用无状态表单
  3. 要跨页面传递数据,我使用页面参数作为页面中唯一的构造函数参数
  4. 使用可添加书签的链接

To make pages stateless, I do the following:

  1. Use bookmarkable pages
  2. Use stateless forms in all cases
  3. To pass data across pages, I use page parameters as the only constructor arguments in the pages
  4. Use bookmarkable links
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文