Java Web应用程序技术

时间:2020-01-09 14:11:13  来源:igfitidea点击:

本教程是对Java Web应用程序体系结构和技术的介绍。它不是要进行详细描述,而是要对可用的各种选择进行概述。详细说明位于其自己的教程中(有关我可以使用的主题的主题)。小程序是Java的第一个Web技术。 Applet是一个小型Java程序,可以从Web服务器下载并在浏览器中执行。就像Flash电影或者ActiveX组件一样。小程序在开始时就引起了媒体的极大兴趣,但从未真正成为Web应用程序GUI平台。如今,Applets是一项"古老"技术,将来会被更现代的RIA(Rich Internet Application)技术JavaFX取代。

Applets

Applets可以完全在浏览器的客户端运行,也可以连接回下载它的服务器以发送和接收数据。

Servlet是Java的第一个服务器端Web技术。它旨在替代早期的网络技术" CGI脚本"。 CGI脚本是当请求到达并由该CGI脚本处理时在Web服务器上执行的程序。因此,无论何时到达Web服务器的CGI脚本请求,都将开始和结束CGI脚本过程。启动新进程的速度相当慢,并且可能会占用大量内存。因此,Sun提出了Sevlets。 CGI脚本可以用多种语言编写,例如Perl或者C。

Servlets

Servlet是实现特殊Servlet接口的普通Java类。然后,将此类部署在Servlet容器中。 Servlet容器已连接到Web服务器。当HTTP请求到达应由Servlet处理的Web服务器时,Web服务器会将请求转发到Servlet容器。然后,servlet容器将请求转发到要处理该请求的servlet。

由于servlet容器一直在运行,因此servlet也一直在运行。换句话说,当对给定servlet的请求到达时,该servlet已经加载到内存中,并准备处理该请求。无需启动CGI脚本或者Java进程。

如今,大多数Servlet容器都带有内置的Web服务器,因此我们不必经常在Java Web服务器和Java Servlet容器之间进行区分。带有servlet容器的Java Web服务器的示例是:

雄猫码头

就个人而言,我更喜欢Jetty,因为它体积小且易于使用。它也非常快速地启动和停止。在开发过程中,快速重启非常方便。

JSP是Java Server Pages的缩写。 JSP是对以下抱怨的一种反应:将HTML嵌入到Servlet(Java代码)中是一个坏主意。如果需要更改站点的布局,则必须在Java代码中进行更改。这并不总是那么容易,因为HTML生成代码与域逻辑代码交错在一起。 JSP也是对当时微软发布的新Web技术ASP(活动服务器页面)和PHP的一种反应,它们都是与JSP类似的技术。

JSP

在JSP中,角色是相反的。在JSP中,我们可以像在标准HTML页面中一样编写HTML。然后,我们可以在HTML内插入" scriplets"(少量Java代码)。例如,我们可以重复一段HTML,或者在两段HTML之间进行选择。

这是一个小的Servlet和JSP示例,以更好地说明它们之间的区别:

如我们所见,JSP示例比Servlet示例短很多,并且更容易获得HTML概述。然而,这并非总是如此。如果我们使用的领域逻辑很多,HTML很少的应用程序,则使用servlet可能会更容易。如果我们有很多HTML内容,并且到处都是逻辑,那么JSP可能会更适合该任务。

public void service(ServletRequest request, ServletResponse response){
    PrintWriter writer = ((HttpServletResponse) response)).getWriter();

    writer.write("<html>");
    writer.write("<body>");
    writer.write("<table>");

    for(int i=0; i<10; i++){
       writer.write("<tr><td>");
       writer.write("" + i);
       writer.write("</td></tr>");
    }

    writer.write("</table>");
    writer.write("</body>");
    writer.write("</html>");
}
<html>
<body>
<table>
    <%
        for(int i=0; i<10; i++){
            %><tr><td><%=i%></td></tr><%
        }
    %>
</table>
</body>
</html>

JSP确实使将一些代码编织到HTML中变得更加容易。但是,它不能将视图(HTML)与控件(域逻辑)完全分开。如果JSP页面内所需的Java代码数量增加,那么JSP的外观将很快变得像意大利面条,很像带有大量HTML生成代码的Servlet。 Servlet和JSP都不是完美的解决方案。

模型2架构

作为对此的回应,有人(我不记得是谁)提出了一种新的Web应用程序体系结构,称为"模型2"。在模型2架构中,Servlet首先处理请求并执行所有必要的域逻辑。 servlet完成后,它将所有必要的数据添加到请求属性,并将请求转发到JSP(或者其他视图技术)。然后,JSP呈现要发送回浏览器的HTML。这提供了域逻辑和HTML生成的更清晰的分离。

最早和最受欢迎的Model 2体系结构Web框架之一是Struts

模型2体系结构的最大问题是域逻辑(控件)和HTML生成(视图)的硬分离。有时,我们需要几个较小的组件来分别处理请求的一部分并生成发送回浏览器的最终HTML页面的一部分。在严格的模型2架构中,这可能很难做到。一旦域逻辑(控件)执行完成,然后将请求转发到视图(JSP)。此视图可以再次其中包含其他较小的控件,并且这些控件中的每个控件也可以将请求转发到视图。

该模型的问题是控制逻辑和视图逻辑的交织。执行变为:

假设上面示例中的最后一个控件遇到错误,并且想要中止整个请求处理。正常的做法是将500 HTTP错误发送回浏览器。但是,由于视图生成已经在顺利进行,因此最后一个组件可能无法更改响应头!它也不能发送回HTTP重定向标头。如果在最后一个控件中引发异常,浏览器将返回半页,并且没有错误消息。

control --> view
            --> control --> view
            --> control --> view
                            --> control --> view

基于组件的体系结构受Swing,AWT和其他窗口工具箱中的桌面组件库的启发。也可以将它们视为对Model 2体系结构的改进。

基于组件的架构

在基于组件的Web应用程序中,我们将拥有与页面上的各种组件匹配的组件。例如,具有表单的页面将具有与表单字段相对应的表单组件。基于组件的Web框架将尝试将表单字段中的值填充到表单组件中,因此将自动为我们完成。有点像Swing应用程序中的表单字段。这就是Apache Wicket的工作方式。

就我个人而言,我对服务器端有太多组件并没有太疯狂。从表单字段组件中复制值并不总是比从HTTP请求对象中复制值容易得多。我更喜欢访问原始HTTP请求。实际上,当使用通过HTTP / XML或者HTTP / SOAP与服务器端进行通信的RIA前端(如Flex,JavaFX或者Silverlight)时,匹配请求参数的服务器端组件实际上可能会带来更多好处,而不是给我们带来好处。

某些基于组件的Web框架体系结构还通过将模型2体系结构的1遍请求处理拆分为2遍请求处理过程,避免了2遍模型的控制-视图-控制交织问题。如下图所示:

首先,层次结构中的所有组件都执行其控制逻辑(域逻辑)。如果此时有任何组件引发异常,则可以中止整个请求,并将50X HTTP响应发送回浏览器,或者显示错误页面等。层次结构中的任何组件也可以发出HTTP重定向响应,如果需要的话。

component.control
    --> component.control
    --> component.control
    --> component.control
            --> component.control
component.view
    --> component.view
    --> component.view
    --> component.view
            --> component.view

其次,层次结构中的所有组件都将执行其视图逻辑。视图逻辑通常生成HTML或者XML。当生成HTML时,视图逻辑通常是通过将请求转发到JSP来实现的,该JSP生成了整个HTML的组成部分。父组件(例如JSP)的视图逻辑通常具有标记,这些标记指定在所生成的HTML / XML中应在每个子HTML / XML中包括的位置。

与严格的Model 2架构相比,基于组件的架构的另一个优势是,基于组件的架构中的每个组件都知道其子组件(如果有的话)。这意味着,如果该子组件不应处理该请求,则该父组件可以禁用(避免调用)其子组件中的一个或者多个。此外,必要时,组件可以在请求处理时添加新的子代。例如,一个组件可以根据添加一个ChildA或者ChildB的请求来决定,然后将请求处理传递给添加的组件。

在模型2架构中,控件不知道其子级。只有视图知道将儿童包括在何处。禁用子控件+视图将更加困难。可能需要通过请求属性将禁用信号发送到子控件+视图。添加新组件也非常困难。我们将不得不在运行时修改视图。但是,视图通常是JSP的视图,在运行时修改起来不太容易。

JSF

JSF是Java Server Faces的缩写。 JSF是由Sun开发的基于组件的Web框架。 JSF是JSP的替代品。

JavaFX

JavaFX是受Adobe Flex启发由Sun开发的一种RIA(Rich Internet Application)技术。 RIA应用程序的工作方式类似于Applet。它是一个小程序,可以在用户浏览器中下载并执行。与传统的Applet相比,RIA技术通常更适合与服务器端进行通信。它们通常也更易于布局。

Adobe Flex

Adobe Flex是最早出现的RIA技术之一。 Flex是用于在Flash中创建RIA应用程序的GUI框架。 Flex应用程序被编译为Flash文件,然后可以将其包含在HTML页面中。使用MXML是一种非常类似于HTML的XML格式,Flex的布局非常容易。

尽管Flex不是Java,但我将其包括在内是因为将Flex RIA应用程序与Java服务器端集成非常容易。 Flex可以通过RMI,SOAP或者简单的HTTP / XML调用Java服务器端。我更喜欢HTTP / XML机制,因为它很容易开发和调试。此外,Flex的发布时间比JavaFX长得多,因此(在撰写本文时)更加成熟。