GWT 中具有人性化 URL 的多个“页面”

Posted

技术标签:

【中文标题】GWT 中具有人性化 URL 的多个“页面”【英文标题】:Multiple "pages" in GWT with human friendly URLs 【发布时间】:2011-01-24 23:55:43 【问题描述】:

我正在玩一个 GWT/GAE 项目,该项目将具有三个不同的“页面”,尽管它并不是真正意义上的 GWT 页面。顶部视图(每个页面一个)将具有完全不同的布局,但某些小部件将被共享。

其中一个页面是通过默认 url (http://www.site.com) 加载的主页,但另外两个需要额外的 URL 信息来区分页面类型。他们还需要一个名称参数(例如http://www.site.com/project/project-name。我知道至少有两种解决方案。

    使用 GWT 历史机制,让页面类型和参数(例如项目名称)成为历史令牌的一部分。 使用带有 url 映射模式的 servlet(如 /project/*)

第一个选择乍一看似乎很明显,但它有几个缺点。首先,用户应该能够轻松记住并直接键入项目的 URL。很难使用历史令牌生成对人类友好的 URL。其次,我使用的是 gwt-presenter,这种方法意味着我们需要在一个令牌中支持子位置,我宁愿避免这种情况。第三,用户通常会停留在一个页面上,因此页面信息是“静态”URL 的一部分更有意义。

使用 servlet 解决了所有这些问题,但也会产生其他问题。

所以我的第一个问题是,这里最好的解决方案是什么?

如果我选择 servlet 解决方案,就会出现新问题。

    将 GWT 应用程序拆分为三个独立的模块可能是有意义的,每个模块都有一个入口点。映射到特定页面的每个 servlet 将简单地将请求转发到处理该页面的 GWT 模块。由于用户通常停留在一个页面上,因此浏览器只需要加载该页面的 js。根据我所阅读的内容,不建议使用此解决方案。

我也可以坚持使用一个模块,但是 GWT 需要找出它应该显示哪个页面。它可以查询服务器或解析 URL 本身。

    如果我坚持使用一个 GWT 模块,我需要将页面信息保存在服务器端。我自然会想到会话,但我不确定将页面信息与用户数据混合是否是个好主意。会话通常存在于用户登录和注销之间,但在这种情况下,它需要不同的行为。通过会话处理此问题会是不好的做法吗?

一个 GWT 模块 + servlet 解决方案也会导致另一个问题。如果用户从项目页面转到主页面,GWT 怎么知道这已经发生了?该应用程序不会重新加载,因此将被视为简单的状态更改。每次状态变化都必须检查页面信息似乎相当低效。

有人愿意引导我走出包围我的迷雾黑暗吗? :-)

【问题讨论】:

【参考方案1】:

我会选择历史令牌。这是处理这种情况的标准方法。不过,我不明白,您所说的“很难使用历史标记生成一个对人类友好的 URL”是什么意思——它们对我来说似乎非常友好:) 如果您使用 servlet 来处理 url,我认为这会导致重新加载整个页面 - 我认为您希望避免这种情况。

其次,我正在使用 gwt-presenter 和 这种方法意味着我们需要 在一个令牌中支持子位置, 我宁愿避免。

如果你对 gwt-presenter 不满意(就像我一样 :)),推出你自己的类来帮助 MVP - 这真的很容易(你可以从头开始或修改 gwt-presenter 类)并且你'将获得适合您需求的解决方案。我正是这样做的,因为 gwt-presenter 对我来说似乎“复杂”/复杂 - 通用,而我所需要的只是它提供(或尝试提供)的一个子集。

至于多模块的想法 - 这是一个很好的想法,但我建议使用Code Splitting - 这种情况(页面/应用程序可以分为“独立”模块/块)就是它的意思用于,加上您只引导您的应用程序一次,因此在页面之间切换时无需下载额外的代码。 另外,以这种方式共享状态应该更容易(例如通过事件总线)。

【讨论】:

我同意历史令牌似乎是直观的选择,但我仍然不相信它是最优的 :-)。我对非人类友好的 URL 的意思是 GWT 历史记录以 # 为标记前缀(大多数用户不会记得)。此外,由于用户通常希望 url 仅包含 /,因此我需要使用 / 作为位置和参数分隔符,这很难维护。还是我在这里遗漏了与历史处理相关的内容?我同意这个解决方案的代码拆分是有意义的。 用户“记住”网址的全部意义并没有完全让我明白(但话又说回来,我不知道您正在处理什么样的页面以及用户可能是谁) - 我认为现在没有人试图记住网址,而不是当有像 del.icio.us 这样的网站时,人们会为他们经常访问的网站添加书签。此外,地址中的 hash/# 不是 Google 想出来的,它是所有浏览器使用和支持的标准方式,通常指的是 DOM 元素的 id,但在 Web 应用程序的情况下 - 它的状态。 Gmail 使用它,越来越多的网站也使用它。 你可能是对的。也许我在整个“友好”的 URL 事情上投入了太多精力。对于 Gmail,它没有任何区别,因为您总是访问主站点。在我的例子中,90% 的用户会直接进入项目页面,这就是为什么我认为如果它是像 site.com/project/theproject 这样的自然 URL 而不是像 site.com/#page=project&name=theproject 这样的东西会很好。我会重新考虑一下这种方法:-)。感谢您的意见。 作为妥协,您可以在您的 HTTP 服务器配置(Apache、nginx 等)中设置重写规则,以便当用户到达 example.com/someurl 时,他/她将被重定向到example.com/#someurl。一段时间后,您应该注意到#addresses 的使用率会更高,因为用户会将它们相互复制。顺便说一句,site.com/#page=project&name=theproject 很麻烦,这就是为什么我更喜欢使用 site.com/#page/project/theproject 格式的原因(而且 Google 似乎也是如此 - 请参阅 Gmail) - 然后你只需在/ 拆分它并处理你得到的令牌。【参考方案2】:

根据您发布的内容,我假设您来自使用服务器端框架构建网站:JSP, JSF, Wicket, php 或类似的。 GWT 不是构建基于页面的导航网站的解决方案,就像使用上述框架一样。使用 GWT,您可以在浏览器中加载一个 web 应用程序并留在那里。处理用户事件、与服务器对话和更新小部件;在这里使用gwt-presenter 是一件好事,因为您不得不考虑分离控制器逻辑和视图状态。 您确实可以利用 GWT 的所有功能来构建高性能的浏览器应用程序,但它绝对用于构建网站(使用通过服务器会话传输请求参数的超链接页面)。

这是迄今为止@*** 上关于 GWT 被问得最多的问题 :) “如何在 GWT 中定义页面和它们之间的导航?”简短的回答:“你没有。”

改用 Wicket,它可以在 App Engine 上正常运行,让您可以定义页面书签和上面提到的所有内容。看这里:http://stronglytypedblog.blogspot.com/2009/04/wicket-on-google-app-engine.html

【讨论】:

如果您不能拥有多个 URL,您将无法使用与 URL 模式匹配的安全约束等功能。 code.google.com/appengine/docs/java/config/…

以上是关于GWT 中具有人性化 URL 的多个“页面”的主要内容,如果未能解决你的问题,请参考以下文章

Django:让用户创建具有个性化网址的网站

如何在 asp.net mvc 应用程序中使用个性化 url

如何在 ASP.NET 中获取 Web 部件个性化提供者的对象?

Springboot 自定义多个404页面

基于用户兴趣的个性化网页动态实时生成系统(论文+程序设计源码+数据库文件)

个性化数据管理工具