深入webx框架(li)

时间:2021-09-13 13:34:14

目录

1、Webx简介

2、创建webx应用

 

一、Webx简介

深入webx框架(li)

  Webx本质上就是一个Web框架,它建立在Java Servlet API基础之上。上图所示是webx的架构图。webx本身类似于spring容器,webx turbine类似于springMVC框架。webx中有一个特别明显的原则:约定优于配置

  1.web控制器: 所有web请求都交给一个叫WebxControlServlet(即图上的web控制器)。当然你也可以配置只有部分经过webx控制器,其它部分经过其它的控制器。

  2.service框架,webx控制器初始化时会初始化service框架,service框架会初始化下面这些service(ResourceLoaderService, RunDataService,ModuleLoaderService,PipelineService,FormService,MappingService,PullService,URIBrokerService,VelocityService)。当然你也可以扩展更多的service。

  3.管道处理web请求: 当请求到达时,管道pipeline会调用valves一个传递一个地处理。

  4.web应用: 就是基于webx框架开发的应用。一般有三个层,VO(View Object),显示层。AO(Application Object),显示层(一般处理大粒度的业务逻辑与控制逻辑)。BO(Business Object)业务逻辑(细数度的业务逻辑)。DO(Data Object)数据层(一般与持久层通信)。这里其实还少画了一个层,就是持久层,持久层主要是DAO(Data Access Object)。

  5.Spring框架: 即开源的Spring框架,并做了简单扩展。

  从一个web请求到结束都经历了哪些阶段:首先,web请求首先到WebxControlServlet处理, WebxControlServlet获取管道服务,交给管道服务。其次,web请求到达管道服务,管道服务有多个阈[yù]值(Valve),Valve非常类似于Filter,但有一个比较大的区别是,Filter是顺序从配置文件配置好后就固定了,而Valve由于是Webx特定设计的,支持流程跳转。如:支持switch分支,支持goto,支持try/catch/finally分支,请求经过各个Valve。不过Valve是可以跳转或有判定条件,并不是每个Valve都需要经过。最后,管理处理完后就直接生成响应。当然,中间有可能走外部重定向那就会开启另一个web请求流程webx(spring)本身类似与一个spring容器,webx turbine(spring MVC)框架才是真正的web框架

  上帝是如何创造万物的呢?上帝如果要创造人,那就是把先人的骨架给创建出来,然后就可以补上所有器官与血管,然后才是肉,皮等等。那么webx相当于(web应用)上帝,webx turbine框架相当于人的骨架,而且我的应用框架当然相当于是器官与血管,最后我们的应用就相当于是肉啊,皮啊,其它的等等。这么一看就很好理解了吧。如果上帝想创建能飞的动物会是怎么样呢?那就需要先弄个能飞的骨架出来。也就是如果我们觉得turbine框架不好,要来个新的,你也可以自己定义一个新的框架基于webx框架即可。与Spring比较,webx相当于spring容器。webx turbine相当于spring的MVC框架(webx service框架根当于spring容器,都是IOC,或叫DI原理)。在spring上可以建立许多新的MVC框架,或直接整合新的MVC框架(比如用spring容器可以整合struts框架,springMVC框架);同样在webx上可以立许多新的MVC框架。

  webx中涉及特色,管道与过滤器涉及模式filter。Filter机制在项目中常用来实现如下功能:页面授权,根据登录用户的权限,阻止或许可用户访问特定的页面;日志和审计,记录和检查用户访问WEB应用的情况。Filter的通用性很好。任何filter均独立于其它filter和servlet,因此它可以和任意其它filter和servlet组合搭配。下面是一段配置示例 ── 通过SetLoggingContextFilter,日志系统可以记录当前请求的信息,例如:URL、referrer URL、query string等

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
">
    <filter>
        <filter-name>mdc</filter-name>
        <filter-class>com.alibaba.citrus.webx.servlet.SetLoggingContextFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>mdc</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

 

  Filter工作原理(Filter chain),多个filter和至多一个servlet被串联成一个链,被称为Filter Chain。执行的时候,引擎将控制权交给链条中的头一个filter(如果有的话)。然后,就像击鼓传花一样,控制权被依次传递给filter chain中的下一个filter或servlet。每一个得到控制权的filter可以做下面的事:继续传递控制权或立即终止filter chain;Filter可将控制权传递给链条中的下一个filter或者最终的servlet;Filter也可以不将控制权传递给下一个filter或servlet,这样便中止了整个filter chain的执行。预处理。在传递控制权给下一个filter或servlet之前,filter可以预先做一些事情:设置request、response中的参数,例如:character encoding、content type等;将HttpServletRequestWrapper传递给链条中的下一位,filter可以通过wrapper改变request中的任意值;将HttpServletResponseWrapper传递给链条中的下一位,filter可以通过wrapper来拦截后续filter或servlet对response的修改、提交。在控制权从filter chain中返回以后,filter还可以做一些后续提交的操作。例如,将response中拦截而来的数据,压缩或转换格式,并发送给客户端或filter chain的上一级,通过try、catch还可以捕获filter chain下一级所有的异常,并做处理。

  filter的限制,Filter是很有用的。作为servlet的补充,filter也是很成功的。但是filter并没有被设计用来完成一切事情。事实上,filter的设计限制了filter的用途。每个filter具有下面的限制:Filter可以访问和修改数据。但它只能访问和修改HttpServletRequest、HttpServletResponse、ServletContext等容器级的对象,而不能(或很难)访问应用程序中的状态。所以filter无法实现和应用逻辑密切相关的功能;Filter可以影响执行流程。但它不能改变filter chain的结构和顺序。Filter chain的结构和顺序是由web.xml中定义的。当filter得到控制权以后,它只能选择继续下去,或者立即结束,而没法进行循环、分支、条件判断等更复杂的控制。因此,filter只能用来实现粗粒度的流程控制功能(例如,当用户未获授权时,停止执行filter chain),难以应付更细致的应用程序内的控制需求;Filter与其它filter和servlet之间,除了request和response对象以外,无法共享其它的状态。这既是优点又是缺点。优点是使filter更独立、更通用;缺点是filter与其它filter、servlet之间难以协作,有时甚至会引起无谓的性能损失。

二、创建webx应用

 

      mvn archetype:create -DgroupId=com.alibaba.study -DpackageName=com.alibaba.study -DartifactId=webapp -DarchetypeArtifactId=maven-archetype-webapp

 

  WEB应用是JavaEE平台中最重要的一种应用。JavaEE WEB应用建立在Servlet API的基础之上。本文将由浅入深地指导你创建一个基本的WEB应用。上图,先用mvn命令创建一个web项目。得到如下的配置文件

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.alibaba.study</groupId>
  <artifactId>testWeb</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>testWeb Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
     <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>testWeb</finalName>
  </build>
</project>

 

  我们依次在上述配置文件中加入,在dependencies节中加入servlet依赖:

 

<!-- 应证了那句话:webx是建立在Java Servlet API基础之上的容器 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.4</version>
        <scope>provided</scope>
    </dependency>

 

  再加入maven配置:

 

      <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>5</source>
                <target>5</target>
            </configuration>
        </plugin>
    </plugins>

 

  接下来执行:

 

mvn eclipse:eclipse -Dwtpversion=2.0

 

  这样便生成了.classpath和.project这两个eclipse相关的文件。Dwtpversion表示为项目增加Dwt支持,这样项目就成为一个Dwt可识别的web项目,这样就可以通过eclipsewtp部署到web服务器。注意:目前mvn支持的wtp版本最高为2.0,所以目前只能写2.0,而不能写最新的3.2。请打开Eclipse并导入这个项目,至此,你就可以在eclipse下开发项目了。接着,通过Eclipse导入刚才创建的项目。

 

package com.alibaba.study;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

public class HelloServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=GBK");

        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.println("<head>");
        out.println("  <title>SimpleServlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("  <p>你好,世界!</p>");
        out.println("</body>");
        out.println("</html>");
    }
}

 

接着创建HelloServlet.java类,这是一个简单而完整的Servlet程序。我们一会来介绍它所包含的技术内涵,现在,让我们先把这个程序跑起来。为此,我们需要修改一下web.xml。在开发环境中,这个文件位于src/descriptors/web目录下,然而在build的时候,它将被复制到WEB应用的WEB-INF目录下。

 

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.alibaba.study.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

 

然后执行命令mvn package,如果一切正常,你会发现在项目的target目录多了一个WAR包:testWeb.war。最后一步,就是把这个WAR包布署到应用服务器上,我们采用eclipse下配置tomcat方式进行。在testWeb项目上面点击右键,选择run as ->Run on Server。

  分析一下Servlet的执行过程,这个Servlet是怎么被执行的呢?首先,我们必须了解,无论采用何种技术,WEB应用的本质是相同的。即浏览器和服务器之间,通过HTTP协议通信。所以WEB协议是跨平台的,而不是专属于Java的。因此,为了更好地理解Java Servlet,我建议你安装一个IE的插件如HttpWatch,或者代理软件如TCP Monitor。通过它们,你可以观测浏览器和服务器之间的通信情况,从而更好地理解HTTP协议和Java Servlet。

深入webx框架(li)

通过它,我们可以看到浏览器发送给WEB服务器的请求的内容:“GET /workshop/hello HTTP/1.1”;我们也可以看到服务器发回浏览器的响应:“HTTP/1.1 200 OK”。这个工具非常有用,尤其对我们跟踪重定向、session、cookie特别有用。通过它也可以观测到一些不明显的错误,而这些错误可能无法在浏览器中直接表现出来。现在,我们已经了解了:WEB应用就是接收浏览器发送的HTTP请求,然后作出响应,返回给浏览器。而Servlet只不过是WEB应用中的一个“插件”,用来处理某一种请求。

深入webx框架(li)

当应用服务器接收到一个HTTP请求时,它就会:

 

1.根据URL找到相应的WEB应用。例如:在http://localhost:8080/workshop/hello中,/workshop决定了该请求应该交给workshop应用来处理。这部分URL被称为Context Path

 

2.进一步根据URL的余下部分,在web.xml中查找匹配的servlet。由于我们在web.xml中指定了<servlet-mapping>,将/hello映射到helloServlet上,所以,应用服务器会找到这个servlet,并执行它。这部分URL被称为Servlet Path

Servlet收到请求时,其service()方法将被执行。不过一般来说,我们不需要实现service方法,只需要实现doGetdoPost这两个方法就可以了,它们分别对应着HTTP GetHTTP Post两种类型的请求。

三、  

 

 

 

 

 
  深入webx框架(li)