前端jsp如何跳转到jsp_使用JSP进行前端模块化

前端jsp如何跳转到jsp

介绍

面对Web应用程序的模块化时,我们经常会遇到这样一种情况,即后端服务和其他后端资源的结构良好,并被分组为某种模块结构。

但是,在我们的情况下,由JSP模板组成的前端部分缺少适当的模块化。 是的,有可能包含,但是通常缺少真实的模块结构。 但是,让我们首先考虑一下“真正的”模块结构对我们意味着什么。

将JSP模板文件切成模块时,我们将任意定义两种模块元素:片段和组件。 让我们从后者开始:组件代表任何内容都可以组成的最小部分。 例如,一个组件可能是一个输入字段,一个选择框或仅仅是一个标签。 在内部组件可能会使用其他组件来显示其内容,但是从概念的角度来看,组件是Web开发人员将大型HTML页面切成可管理的片段时应该使用的最小部分。

另一方面,片段是一组逻辑关联的组件。 例如,常规网页可能由三个片段组成:标题,内容和页脚。 每个片段可以细分为子片段。 就是 标题片段可能包括一个显示徽标图像和标题的信息片段,一个允许用户在每个页面上输入用户名和密码的登录片段以及一个菜单片段,用户可以从菜单片段中选择指向特定页面的链接。 菜单片段本身可能由另一组片段组成:主菜单片段,配置文件数据片段和帮助菜单片段。 等等。

这些片段中的每一个都由以下组件组成:例如,登录片段可能由用户名的输入字段组件,密码的输入字段组件和触发执行登录操作的按钮组件组成。 。

创建索引页面时,我们可能会显示以下页面:



  
  
  
    

    
Hello World!

index.jsp

我们可以看到上面定义的片段。 标头片段位于包含的header.jsp文件中,页脚片段位于包含的footer.jsp中,内容片段是页面本身中的其余内容。

现在,让我们看一下header.jsp文件和其中包含登录页面片段的所引用的login-form.jsp文件:

header.jsp

<%@ taglib prefix="comp" tagdir="/WEB-INF/tags/components" %>

login-form.jsp

header.jsp仅包含其他两个片段,login-form.jsp由三个组件组成。 在此示例中,到目前为止的片段被实现为简单包含,而组件被实现为JSP标签。 我们也可能将基于标签的组合用于片段,或者将基于标签的组合用于组件。 从概念上讲,这并不重要-两种方法都有效。 但是,基于标签的组合的详细程度要低得多,因此您应该尽可能使用它。

返回内容:到目前为止,从Web开发人员的角度来看,我们已经到了切片过程的结尾:正如我们在开始时所定义的那样,组件是我们要用来构成页面的最小信息。 但是,让我们窥视一个组件并查看其内部构建方式:

<%@ tag description="Displays a field including a label" %>
<%@ attribute name="name" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="type" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="label" required="false" type="java.lang.String" rtexprvalue="true" %>

fieldPlusLabel的标签实现文件

添加布局

我们已经看到了如何通过一组片段和组件来结构化页面。 但是,到目前为止,我们完全错过了布局。 我们确实希望页面看起来漂亮舒适,因此我们需要为片段和组件定义CSS样式。

这才是真正的麻烦开始的地方。 通常,CSS样式表会添加到HTML页面的头部。 如果在示例中执行此操作,则index.jsp页面将如下所示:



  
    
  
  
    

    
Hello World!

index.jsp

到目前为止,一切都很好–但这完全忽略了我们的模块化策略。 尤其是在移动环境中,我们希望样式表能够反映出页面中包含的片段和组件,而不希望包含很多“镇流器”。 在此示例中,样式表必须包含所有可用片段和组件的所有样式。 但是,如果我们有一个包含大量组件的大型项目,而这些组件都需要某种CSS样式。 如果我们的页面仅使用了其中的一小部分,我们是否真的要为100个组件包括CSS

此外:如果创建新组件,则将逻辑写入组件标签文件中。 然后,我们需要向全局样式表中添加一些内容。 因此,现在应该在模块上下文中实际定义的内容将分为模块(组件)和全局样式表文件。 这当然不是我们打算要做的。

因此,让我们看一下替代方案:还根据片段和组件来分隔样式表文件。 这意味着对于每个组件,我们需要一个相应的样式表文件。 再次让我们看一下index.jsp:



  
    
    
    
    
    
    
  
  
    

    
Hello World!

index.jsp

现在,我们已经对样式表类进行了模块化,以匹配我们的片段和组件结构。 但是,在页面中包含引用的方式仍然不是最佳选择:在index.jsp页面中,我们现在需要知道使用了哪些组件和片段以便允许在标题区域中进行声明。 但是,对页面进行切片的主要原因之一是要使片段和组件尽可能地独立。

另一种选择是根本不在标题区域中声明样式表,而是将它们包括在片段和组件中:

<%@ tag description="Displays a field including a label" %>
<%@ attribute name="name" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="type" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="label" required="false" type="java.lang.String" rtexprvalue="true" %>

fieldPlusLabel.tag

现在,我们将实际的逻辑(HTML元素)和样式表声明放在一起,并设法将模块的概念增强为HTML元素和样式表信息。 但这是正确的方法吗? 样式表声明属于HTML页面的标题,而不是正文。

此外,如果我们多次包含一个组件,那么我们还将多次包含样式表引用-这可能会在将文档加载到浏览器中时导致大量开销。

解决问题

理想的解决方案是简单地在组件中声明所需的样式表文件,然后让页面本身确定页面中使用了哪些片段和组件,以及需要在页眉区域中声明哪些样式表文件。 我们的每个片段和组件都可以在某种父实例上注册自己(及其所需的资源),该实例跟踪页面评估期间引用的所有片段和组件。 然后,评估完成后,它只能添加对实际使用资源的引用。

但是,在传统的JSP中,这是不可能的。 该页面将自上而下进行评估,这意味着将在正文区域对第一个组件进行评估之前很久就对头部区域进行评估(因此将写入所有内容)。 我们陷入了鸡肉和鸡蛋的问题。

但是,JSP通过编写用户定义的标签为我们提供了许多定制评估的可能性。 因此,我们真正需要做的是实现我们自己的三个标签:HtmlTag,HeadTag和BodyTag。 每个配置的配置与您希望进行定期评估的配置不同。

让我们首先查看index.jsp页面的新版本:


<%@ taglib prefix="n" uri="http://sapient.com/example/jsp" %>

  
    
  
  
    

    
Hello World!

index.jsp

如我们所见,传统HTML元素html,head和body已被我们的标签库中的专用标签所取代。 这也意味着它们不会被简单地添加到要发送到客户端的生成HTML文档中,而是会经过特殊处理。 这就是标签库的“魔力”发挥作用的地方。

标记库中的HtmlTag(通过JSP中的n:html标记进行引用)提供了两件事:首先,孩子可以在其中添加内容的注册表。 其次,它提供了修改后的评估过程。 当JSP解析器遇到该标记时,我们的标记库的Java实现将首先将h:html标记的模式设置为主体评估,然后对其所有子代执行首次评估。

在该评估期间,遇到两个子标签:n:head和n:body标签。 由于这两个标签也都在我们的标签库中,因此两者都可以进行特殊处理。 在第一次运行中(在主体评估中),n:head标记将不执行任何操作-不评估子项,不输出到JSP文档中,只会保持沉默。 n:body标记将执行其常规评估(包括其子代),但不会将任何输出写入生成HTML输出中,而是缓冲响应以供以后使用。

在此评估中,每个片段和组件都可以声明所需的样式表,如以下示例所示:

<%@ tag description="Displays a field including a label" %>
<%@ attribute name="name" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="type" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ attribute name="label" required="false" type="java.lang.String" rtexprvalue="true" %>
<%@ taglib prefix="n" uri="http://sapient.com/example/jsp" %>

fieldPlusLabel.tag

在这里,我们可以看到专门的n:link标记。 此实现与常规评估的不同之处在于,它不会在生成的JSP文档中生成任何内容,而只是将定义的样式表注册在n:head标记中以备将来使用。

在n:html以主体评估模式评估其内容之后,它将切换到标头评估模式并对其子项执行另一评估。 现在角色被颠倒了:n:head标签(在身体评估阶段保持沉默)现在变为活动状态,并将其内容呈现到其自己的缓冲区中。 在该评估期间,n:stylesheets标记将请求在主体评估阶段之前添加的样式表的列表。 现在,对于每个样式表,它将在输出中添加相应的链接元素。 这次,n:body标签保持沉默并且不执行任何操作,就像n:head标签在身体评估阶段所做的一样。

第二次运行后,n:html标记将标头评估阶段和主体评估阶段的缓冲输出组合在一起,以生成有效HTML文档head和body元素。 然后,该文档将发送回客户端。

总而言之,通过执行两次评估运行,即在主体区域之后绘制头部区域,我们获得了将样式表注册到主体中的灵活性,该样式表实际上将附加到文档头部。 现在,我们可以独立查看片段或组件,并一起定义其内容和样式表,而评估实际上是在头部和身体区域独立进行的。

前景

我们在样式表中看到的相同逻辑也可以应用于JavaScript块。 还应为每个模块定义一次,但应将其附加到顶部区域。 另一个优化是将引用资源合并到一个大文件中,以便可以将多个请求的额外开销降至最低。

本文显示,通过一些小的更改和taglib的集成,我们能够实现适当的模块化并允许更加简洁和逻辑的开发模型-不仅在后端,而且在JSP前端。

图片由安德鲁·莫雷尔 ( Andrew Morrell)





翻译自: https://jaxenter.com/front-end-modularization-with-jsps-107381.html

前端jsp如何跳转到jsp

你可能感兴趣的:(前端jsp如何跳转到jsp_使用JSP进行前端模块化)