【问题标题】:best way to externalize HTML in GWT apps?在 GWT 应用程序中外部化 HTML 的最佳方法?
【发布时间】:2010-10-19 03:38:27
【问题描述】:

在 GWT 应用程序中外部化大量 HTML 的最佳方法是什么?我们有一个相当复杂的 GWT 应用程序,大约有 30 个“页面”;每个页面的底部都有一个指南,它是几段 HTML 标记。我想将 HTML 外部化,使其尽可能保持“未转义”。

我知道并了解如何在 GWT 中使用属性文件;这当然比在 Java 类中嵌入内容要好,但对于 HTML 来说仍然有点丑(你需要对所有内容进行反斜杠,以及转义引号等)

通常这是您将放在 JSP 中的那种东西,但我没有看到任何与 GWT 中的等效项。我正在考虑编写一个小部件,它只会从服务器上的 html 文件中获取内容,然后将文本添加到 HTML 小部件中。但似乎应该有更简单的方法。

【问题讨论】:

  • 在我看来,您只是以错误的方式使用 GWT。 GWT 应用程序中不应该有“大量的 HTML”。我与 数百 个 GWT 屏幕一起工作,我们几乎没有 HTML 标记(在 Java 代码中或在 GWT 主机页面中)。实际的 HTML 是由 GWT 编译器从 Java 代码生成的 JavaScript 代码动态生成的——毕竟这就是 GWT 的全部意义所在。

标签: java html gwt


【解决方案1】:

我在类似的设置中使用过 ClientBundle。我创建了一个包 my.resources 并将我的 HTML 文档和以下类放在那里:

package my.resources;

import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.TextResource;

public interface MyHtmlResources extends ClientBundle {
 public static final MyHtmlResources INSTANCE = GWT.create(MyHtmlResources.class);

 @Source("intro.html")
 public TextResource getIntroHtml();

}

然后我通过从我的 GWT 客户端代码中调用以下代码来获取该文件的内容:

HTML htmlPanel = new HTML();
String html = MyHtmlResources.INSTANCE.getIntroHtml().getText();
htmlPanel.setHTML(html);

更多信息请参见http://code.google.com/webtoolkit/doc/latest/DevGuideClientBundle.html

【讨论】:

  • 这正是我想要的。谢谢,@Futzilogik!但是,由于某种原因,我的“intro.html”中的脚本无法运行,即使它是一个简单的<script>alert("Hi!");</script>。你有什么理由认为那不应该起作用?
【解决方案2】:

您可以使用一些模板机制。尝试FreeMarkerVelocity 模板。您将在将通过模板库检索的文件中包含 HTML。这些文件可以用适当的扩展名命名,例如.html、.css、.js 可自行观察。

【讨论】:

  • 因为 GWT 的全部意义在于编写客户端应用程序。无需去服务器获取此 html。在较小的环境中,可以使用 iframe 等,但 GWT 允许您使用包含 html 资源等的字符串生成对您的语言环境敏感的不同 js。答案是 Client Bundles,如下所述。
  • 虽然 FreeMarker 和 Velocity 是在服务器端工作的好工具,但我认为它在 GWT 客户端环境中并不是一个好的解决方案。 GWT 对可以在客户端执行的 Java 代码施加了限制,而您提到的那些传统模板库将无法运行。
【解决方案3】:

我会说您通过 Frame 加载外部 html。

Frame frame = new Frame();
frame.setUrl(GWT.getModuleBase() + getCurrentPageHelp());
add(frame);

您可以安排一些约定或查找 getCurrentPageHelp() 以返回适当的路径(例如:/manuals/myPage/help.html

这是一个example 正在运行的框架。

【讨论】:

    【解决方案4】:

    在 GWT 2.0 中,您可以使用 UiBinder 执行此操作。

    <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
      <div>
        Hello, <span ui:field='nameSpan’/>, this is just good ‘ol HTML.
      </div>
    </ui:UiBinder>
    

    这些文件与您的 Java 代码分开保存,并且可以作为 HTML 进行编辑。它们还提供与 GWT 小部件的集成,以便您可以轻松地从 GWT 代码访问 HTML 中的元素。

    【讨论】:

      【解决方案5】:

      GWT 2.0 在发布时应该有一个 ClientBundle,它可能会解决这个需求。

      【讨论】:

        【解决方案6】:

        您可以尝试实现Generator 以在编译时从文件加载外部 HTML 并构建一个发出它的类。在线创建生成器似乎没有太多帮助,但 GWT 小组的帖子可能会让您入门:GWT group on groups.google.com

        【讨论】:

          【解决方案7】:

          我正在做类似的研究,到目前为止,我发现解决这个问题的最佳方法是通过DeclarativeUI or UriBind。不幸的是它还在孵化器中,所以我们需要解决这个问题。

          我用几种不同的方式解决它:

          1. 主动覆盖,即:您创建标准 HTML/CSS 并通过 &lt;script&gt; 标签注入 GET 代码。在任何需要从 GWT 代码访问元素的地方,您都可以编写如下代码:

            RootPanel.get("element-name").setVisible(false);
            
          2. 你编写你的代码 100% GWT,然后,如果需要一个大的 HTML 块,你可以通过 IFRAME 或通过 AJAX 将它带到客户端,然后通过 HTML 面板注入它,如下所示:

            String html = "<div id='one' "
               + "style='border:3px dotted blue;'>"
               + "</div><div id='two' "
               + "style='border:3px dotted green;'"
               + "></div>";
            HTMLPanel panel = new HTMLPanel(html);
            panel.setSize("200px", "120px");
            panel.addStyleName("demo-panel");
            panel.add(new Button("Do Nothing"), "one");
            panel.add(new TextBox(), "two");
            RootPanel.get("demo").add(panel);
            

          【讨论】:

          • 问题不在于用于 HTML 数据的小部件;问题是如何将 HTML out 从代码中取出,并将其转换为更自然的内容,例如 .html 文件。
          • 是的。上面的示例并不是要展示如何将 HTML 放入代码中,而只是为了展示您可以引用位于代码之外的 HTML,这些 HTML 可以以多种方式打包。在上面的示例中,它是一个字符串。以同样的方式,您可以通过 URL 引用外部文件。
          • 将 HTML 放入一个文件(如果需要,可以是 *.html),在服务器上加载文件并使用 HTMLPanel() 显示内容。
          【解决方案8】:

          为什么不使用旧的 IFRAME?只需创建一个 iFrame,您希望在其中放置提示并在 GWT 'page' 更改时更改其位置。

          优点:

          • 点击存储在任何结构的单独的可维护 HTML 文件中
          • AJAX 风格的加载,完全没有编码在服务器端
          • 如果需要,应用程序仍然可以与加载的信息进行交互

          缺点:

          • 每个提示文件都应具有指向共享 CSS 的链接,以实现通用外观
          • 难以国际化

          为了使这种方法更好一点,您可能会处理加载错误并在 404 错误时重定向到默认语言/主题。所以,搜索优先级是这样的:

          1. 当前语言的当前主题
          2. 默认语言的当前主题
          3. 当前语言的默认主题
          4. 默认错误页面

          我认为创建这样的 GWT 组件来合并 iFrame 交互非常容易

          【讨论】:

          • 因此,您的服务器上可能有这样的文件结构:/help/welcome/en.html 或 /help/welcome-en.html 此页面将包含主题或 GWT-page 的英文文本欢迎'
          • 因为 GWT 支持使用包含来自 html 文件的参数的 html 的 getter 创建类。它还支持获取生成程序的不同排列,每个排列都有基于语言环境的不同 html。如果你想到了,它在 GWT 中做得更好。
          【解决方案9】:

          GWT Portlets 框架 (http://code.google.com/p/gwtportlets/) 包括一个 WebAppContentPortlet。这会提供来自您的 Web 应用程序的任何内容(静态 HTML、JSP 等)。您可以将它放在具有其他 Portlet 中的附加功能的页面上,并且在页面加载时通过单个异步调用获取所有内容。

          查看 WebAppContentPortlet 和 WebAppContentDataProvider 的源代码,了解它是如何完成的,或者尝试使用框架本身。以下是相关的来源:

          WebAppContentPortlet(客户端)

          ((HasHTML)getWidget()).setHTML(html == null ? "<i>Web App Content</i>" : html);
          

          WebAppContentDataProvider(服务器端):

          HttpServletRequest servletRequest = req.getServletRequest();
          String path = f.path.startsWith("/") ? f.path : "/" + f.path;
          RequestDispatcher rd = servletRequest.getRequestDispatcher(path);
          BufferedResponse res = new BufferedResponse(req.getServletResponse());
          try {
             rd.include(servletRequest, res);
             res.getWriter().flush();
             f.html = new String(res.toByteArray(), res.getCharacterEncoding());
          } catch (Exception e) {
             log.error("Error including '" + path + "': " + e, e);
             f.html = "Error including '" + path +
                  "'<br>(see server log for details)";
          }
          

          【讨论】:

            【解决方案10】:

            您可以将 servlet 与 jsps 一起用于页面的 html 部分,并且仍然包含在页面上运行 gwt 应用程序所需的 javascript。

            【讨论】:

              【解决方案11】:

              我不确定我是否理解您的问题,但我假设您已将这个常见的摘要分解到它自己的小部件中。如果是这样,问题是您不喜欢将 HTML 嵌入 Java 代码的丑陋方式。

              GWT 2.0 有 UiBinder,它允许您在原始 HTMLish 模板中定义 GUI,并且您可以将值从 Java 世界注入到模板中。通读dev guide,它给出了一个很好的大纲。

              【讨论】:

                【解决方案12】:
                【解决方案13】:

                您可以尝试GWT App 使用在运行时生成和绑定的 html 模板,而不是在编译时。

                【讨论】:

                  【解决方案14】:

                  不知道 GWT,但您不能在您的应用程序 html 中定义和锚定 div 标记,然后针对您需要的 HTML 文件执行 get 并附加到 div 吗?这与micro-template 有何不同?

                  更新:

                  我刚刚在另一个StackOverflow 问题的回答中发现了这个不错的 jQuery 插件。

                  【讨论】:

                  • 提问者希望避免往返获取 html。基本上,他们希望使用 ClientBundle 自动将转义页面作为字符串嵌入应用程序中。
                  猜你喜欢
                  • 1970-01-01
                  • 2012-03-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-09-30
                  • 1970-01-01
                  • 2011-09-10
                  • 2017-02-06
                  • 2012-01-14
                  相关资源
                  最近更新 更多