加载中
luodis 2011/05/24 10:07 回答了问题: java 私塾课堂笔记——WebService


  七:SOAP
   1:简单的soap示例
[code]
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
 <env:Header>
 </env:Header>
 <env:Body>
  <cms:getNumberOfArticles xmlns:cms="http://www.daily-moon.com/cms">
    <cms:category>classifieds</cms:category>
    <cms:subcategory>forsale</cms:subcategory>
  </cms:getNumberOfArticles>
 </env:Body>
</env:Envelope>[/code]
 
   2:soap信封
      Web 服务消息的基本单元是实际的 SOAP 信封。这是包含处理消息所必需的所有信息的 XML 文档
[code]
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
 <env:Header>
</env:Header>
 <env:Body>
</env:Body>
</env:Envelope>[code]
 
   3:soap的Header
      SOAP 消息中的 Header 用于提供有关消息本身的信息,与用于应用程序的信息相对。例如,Header 可以包括路由信息
[code]
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
 <env:Header>
  <wsa:ReplyTo xmlns:wsa=
        "http://schemas.xmlSOAP.org/ws/2004/08/addressing">
   <wsa:Address>
http://schemas.xmlSOAP.org/ws/2004/08/addressing/role/anonymous
   </wsa:Address>
  </wsa:ReplyTo>
  <wsa:From>
   <wsa:Address>
http://localhost:8080/axis2/services/MyService</wsa:Address>
  </wsa:From>
  <wsa:MessageID>ECE5B3F187F29D28BC11433905662036</wsa:MessageID>
  </env:Header>
<env:Body>
</env:Body>
</env:Envelope>[/code]
 
本例中有一个 WS-Addressing 元素,其中包含有关消息将送达何处以及应将应答送达何处的信息。Header 可包含关于消息本身的所有类型的消息。事实上,SOAP 规范中使用了大量篇幅说明哪些元素可以放入 Header以及应由“SOAP 中间层”如何对其进行处理。也就是说,SOAP 规范并不假定消息将直接从一个点传递到另一个点(从客户机到服务器)。
规范考虑了 SOAP 消息在送达最终目的地的过程中可能实际由多个中间层处理的情况,很清楚地说明了中间层应如何对待在 Header 中找到的信息。不过,对此的讨论不在本教程的范围之内。因此,目前只要知道 Header 可以提供许许多多的功能(如果您需要)即可。

   4:soap的Body
      发送 SOAP 消息时,都是有目的性的。您在尝试告诉接收者执行某种操作,或尝试向服务器传递相关信息。此信息称为“有效负载”。有效负载位于 Envelope 的 Body 中。它还具有自己的命名空间,在本例中其命名空间与内容管理系统对应。在此情况下,可以完全随意地选择命名空间。只需要与 SOAP 命名空间相异即可
[code]
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
 <env:Header>
...
</env:Header>
 <env:Body>
  <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms">
    <cms:category>classifieds</category>
    <cms:subcategory>forsale</cms:subcategory>
    <cms:articleHeadline></cms:articleHeadline>
    <cms:articleText>Vintage 1963 T-Bird.  Less than 300 miles. 
Driven by my daughter until I took it away.  Serious inquires only. 
555-3264 after 7 PM.</cms:articleText>
  </cms:addArticle>
 </env:Body>
</env:Envelope>[/code]
 
     在此例中,有效负载很简单,其中包含将文章添加到 Daily Moon 的内容管理系统的指令。

   4:样式和编码
      这个主要是在WSDL(Web服务描述语言)中讲述。
      简单来说,有两种不同的主流 SOAP消息编程样式。第一种是 RPC 样式,基于使用 SOAP 消息创建远程过程调用(Remote Procedure Call)的概念。在此样式中,基本思路是在向服务器发送命令(如“添加文章”),并将该命令的参数(如要添加的文章和应该添加到的类别)作为整个方法的子元素包含在其中
[code]
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
<env:Header> [/code]
      RPC 样式的替代方法将数据直接作为 SOAP 体的内容处理,并在应用服务器对消息进行路由的信息中包含有关其所属的过程或函数的信息
[code]
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
 <env:Header>
 </env:Header>
 <env:Body>
  <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms">
    <cms:category>classifieds</category>
    <cms:subcategory>forsale</cms:subcategory>
    <cms:articleHeadline></cms:articleHeadline>
    <cms:articleText>Vintage 1963 T-Bird.  Less than 300
miles.  Driven by my daughter until I took it away. 
Serious inquires only.  555-3264 after 7 PM.</cms:articleText>
  </cms:addArticle>
 </env:Body>
</env:Envelope>
[/code]
 
   第二个样式称为 document/literal 样式,即将相应的数据直接添加到消息中
[code]
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">
  <env:Header>
  </env:Header>
  <env:Body>
    <category>classifieds</category>
    <subcategory>forsale</subcategory>
    <articleHeadline></articleHeadline>
    <articleText>Vintage 1963 T-Bird.  Less than 300 miles.
  Driven by my daughter until I took it away.  Serious
inquires only.  555-3264 after 7 PM.</articleText>
</env:Body>
</env:Envelope>[/code]
   在这种情况下,消息本身并不包含有关数据所提交到的进程的信息,此工作由路由软件进行。例如,所有对特定 URL 或端点的调用都可能指向特定的操作。另外,从技术上讲,可以使用 document/encoded 样式,但目前还没有人这样做,因此可以将其忽略。
   5:消息交换模式
      发送消息,就实质而言,只有两个选择:
        请求/响应:在请求/响应模式种,以 SOAP 消息的形式发送请求,然后直接等待发送回响应。请求可以为同步的,也可以是异步的。
        单向消息传递:这种情况也称为“Fire and Forget”方法,发送请求但并不等待响应。可以在仅传递信息时或并不关心接收者对此如何响应时使用此方法。

【终于完了!!】

@luodis
java 私塾课堂笔记——WebService 一:什么是WebService WebService(Web服务)...
luodis 2011/05/20 09:36 回答了问题: java 私塾课堂笔记——WebService


  五:认识Axis2
      Axis2是什么?
      Apache Axis2 是Axis的后续版本,是新一代的SOAP引擎。Axis2是通过用Java语言开发Web Service的工具,Axis2封装了SOAP消息的处理,同时还有做了其他的大量的工作来简化Web Sercice的开发者的工作。
      Axis2能做什么?
      Axis2的主要特点有:
       (1)提供了一个处理SOAP消息的框架,这个框架是极易扩展的,用户可以在每个服务或操作上扩展它。用户也可以在这个框架的基础上对不同的消息交换模型(Message Exchange Patterns)MEPs进行建模
       (2)采用名为 AXIOM(AXIs Object Model)的新核心 XML 处理模型,利用新的XML解析器提供的灵活性按需构造对象模型。
       (3)支持不同的消息交换模式。目前Axis2支持三种模式:In-Only、Robust-In和In-Out。In-Only消息交换模式只有SOAP请求,而不需要应答;Robust-In消息交换模式发送SOAP请求,只有在出错的情况下才返回应答;In-Out消息交换模式总是存在SOAP请求和应答。
       (4)提供阻塞和非阻塞客户端 API。
       (5)支持内置的 Web服务寻址 (WS-Addressing)
       (6)灵活的数据绑定,可选择直接使用 AXIOM,ADB,或使用 XMLBeans、JiBX 或 JAXB 2.0 等专用数据绑定框架。
       (7)新的部署模型,支持热部署,可以用或者不用WSDL来部署
       (8)支持HTTP,SMTP,JMS,TCP传输协议。
       (9)支持REST (Representational State Transfer)。
       (10)提供了代码生成器,可以生成服务器端和客户端的代码
     除了上述的这些功能,在内存和速度等性能方面也是Axis2的重点。Axis2的核心框架是构建在WSDL,SOAP和WS-Addressing上,其他的如JAX-RP,SAAJ和WS-Policy是在核心框架之上的层
 
  六:WSDL
   1:WSDL 的用途
      创建服务时,通常的原因都是因为希望其他人使用此服务。为了使用服务,需要知道向服务发送什么信息、服务将发送回什么信息以及在何处能找到此服务。当然,可以将这些放入字处理文档中,但相比之下,如果此信息采用标准的、最好为人机均可读的格式,则要有用得多。
      WSDL 就提供了这样的标准格式。除了不会造成混淆不清外,其主要优势是,由于 WSDL 是事实标准,且采用 XML 格式,因而可由计算机进行处理,便于自动创建客户机(甚至自动创建服务的框架)。
      注意这里我们讲述的还是wsdl1.0,但是wsdl2.0已经出来了,2007年推出wsdl2.0。
    Wsdl文档结构:
      WSDL 文档是利用这些主要的元素来描述某个 web service 的:
      <portType>: web service 执行的操作
      <message>: web service 使用的消息
      <types> :web service 使用的数据类型
      <binding> :web service 使用的通信协议
     一个 WSDL 文档的主要结构是类似这样的:
      <definitions>
      <types>
         definition of types........
      </types>
      <message>
         definition of a message....
      </message>
      <portType>
         definition of a port.......
      </portType>
      <binding>
         definition of a binding....
      </binding>
 
    </definitions>WSDL 文档可包含其它的元素,比如 extension 元素,以及一个 service 元素,此元素可把若干个 web services 的定义组合在一个单一的 WSDL 文档中。

         1:<portType> 元素是最重要的 WSDL 元素。它可描述一个 web service、可被执行的操作,以及相关的消息。可以把 <portType> 元素比作传统编程语言中的一个函数库(或一个模块、或一个类)。
         2:<message> 元素定义一个操作的数据元素。每个消息均由一个或多个部件组成。可以把这些部件比作传统编程语言中一个函数调用的参数。
         3:<types> 元素定义 web service 使用的数据类型。为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。
         4:<binding> 元素为每个端口定义消息格式和协议细节
     WSDL的PortType:
     操作类型:WSDL中定义了四种类型:
         One-way :此操作可接受消息,但不会返回响应。
         Request-response: 此操走可接受一个请求并会返回一个响应
         Solicit-response :此操作可发送一个请求,并会等待一个响应。
         Notification :此操作可发送一条消息,但不会等待响应。
      1:一个 one-way 操作的例子:
[code]
<message name="newTermValues">
   <part name="term" type="xs:string"/>
   <part name="value" type="xs:string"/>
</message>

<portType name="glossaryTerms">
   <operation name="setTerm">
      <input name="newTerm" message="newTermValues"/>
   </operation>
</portType >[/code]
 
2:一个 request-response 操作的例子:
[code]
<message name="getTermRequest">
   <part name="term" type="xs:string"/>
</message>

<message name="getTermResponse">
   <part name="value" type="xs:string"/>
</message>

<portType name="glossaryTerms">
  <operation name="getTerm">
    <input message="getTermRequest"/>
    <output message="getTermResponse"/>
  </operation>
</portType>[/code]

      WSDL的绑定:
         绑定到 SOAP
         一个请求 - 响应操作的例子:
[code]
<message name="getTermRequest">
   <part name="term" type="xs:string" />
</message>

<message name="getTermResponse">
   <part name="value" type="xs:string" />
</message>

<portType name="glossaryTerms">
  <operation name="getTerm">
      <input message="getTermRequest" />
      <output message="getTermResponse" />
  </operation>
</portType>

<binding type="glossaryTerms" name="b1">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
  <operation>
    <soap:operation
     soapAction="http://example.com/getTerm" />
    <input>
      <soap:body use="literal" />
    </input>
    <output>
      <soap:body use="literal" />
    </output>
  </operation>
</binding>[/code]
 
binding 元素有两个属性 - name 属性和 type 属性。
name 属性定义 binding 的名称,而 type 属性指向用于 binding 的端口,在这个例子中是 "glossaryTerms" 端口。
soap:binding 元素有两个属性 - style 属性和 transport 属性。
style 属性可取值 "rpc" 或 "document"。在这个例子中我们使用 document。transport 属性定义了要使用的 SOAP 协议。在这个例子中我们使用 HTTP。

operation 元素定义了每个端口提供的操作符。
对于每个操作,相应的 SOAP 行为都需要被定义。同时您必须如何对输入和输出进行编码。在这个例子中我们使用了 "literal"。

例子:
下面是前面的HelloWorld生成的wsdl文件:
[code]
<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://pojo.service.quickstart.samples" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://pojo.service.quickstart.samples">
    <wsdl:types>
        <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://pojo.service.quickstart.samples">
            <xs:element name="getPrice">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="symbol" nillable="true" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="getPriceResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="return" type="xs:double"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="update">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="symbol" nillable="true" type="xs:string"/>
                        <xs:element minOccurs="0" name="price" type="xs:double"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="getPriceRequest">
        <wsdl:part name="parameters" element="ns:getPrice"/>
    </wsdl:message>
    <wsdl:message name="getPriceResponse">
        <wsdl:part name="parameters" element="ns:getPriceResponse"/>
    </wsdl:message>
    <wsdl:message name="updateRequest">
        <wsdl:part name="parameters" element="ns:update"/>
    </wsdl:message>
    <wsdl:portType name="StockQuoteServicePortType">
        <wsdl:operation name="getPrice">
            <wsdl:input message="ns:getPriceRequest" wsaw:Action="urn:getPrice"/>
            <wsdl:output message="ns:getPriceResponse" wsaw:Action="urn:getPriceResponse"/>
        </wsdl:operation>
        <wsdl:operation name="update">
            <wsdl:input message="ns:updateRequest" wsaw:Action="urn:update"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="StockQuoteServiceSoap11Binding" type="ns:StockQuoteServicePortType">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <wsdl:operation name="getPrice">
            <soap:operation soapAction="urn:getPrice" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="update">
            <soap:operation soapAction="urn:update" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="StockQuoteServiceSoap12Binding" type="ns:StockQuoteServicePortType">
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <wsdl:operation name="getPrice">
            <soap12:operation soapAction="urn:getPrice" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="update">
            <soap12:operation soapAction="urn:update" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="StockQuoteServiceHttpBinding" type="ns:StockQuoteServicePortType">
        <http:binding verb="POST"/>
        <wsdl:operation name="getPrice">
            <http:operation location="StockQuoteService/getPrice"/>
            <wsdl:input>
                <mime:content type="text/xml" part="getPrice"/>
            </wsdl:input>
            <wsdl:output>
                <mime:content type="text/xml" part="getPrice"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="update">
            <http:operation location="StockQuoteService/update"/>
            <wsdl:input>
                <mime:content type="text/xml" part="update"/>
            </wsdl:input>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="StockQuoteService">
        <wsdl:port name="StockQuoteServiceHttpSoap11Endpoint" binding="ns:StockQuoteServiceSoap11Binding">
            <soap:address location="http://localhost:8080/axis2/services/StockQuoteService"/>
        </wsdl:port>
        <wsdl:port name="StockQuoteServiceHttpSoap12Endpoint" binding="ns:StockQuoteServiceSoap12Binding">
            <soap12:address location="http://localhost:8080/axis2/services/StockQuoteService"/>
        </wsdl:port>
        <wsdl:port name="StockQuoteServiceHttpEndpoint" binding="ns:StockQuoteServiceHttpBinding">
            <http:address location="http://localhost:8080/axis2/services/StockQuoteService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>
[/code]
 
【还有一篇……】

@luodis
java 私塾课堂笔记——WebService 一:什么是WebService WebService(Web服务)...
luodis 2011/05/18 14:53 回答了问题: java 私塾课堂笔记——WebService


      Axis2的客户端调用
         Web services提供的服务多种多样,有的可以马上获得结果,有的要消耗很长的时间。所以,如果我们需要多种调用方式来对付不同的情况。
         大多数的Web services都提供阻塞(Blocking)和非阻塞(Non-Blocking)两种API。
             Blocking API - 调用端要等被调用的函数运行完毕才继续往下走。
             Non-Bloking API - 调用端运行完调用函数以后就直接往下走了,调用端和被调用端是异步执行的。返回值是用回调函数来实现的。
         这种异步叫做API层异步(API Level Asynchrony)。他们只用到一个连接来发送和接收消息,而且,如果是那种需要运行很长时间的函数,还会碰到Time Out 错误,如果用两个连接分别处理发送和接收消息,调用的时间就可以缩短,也可以解决Time Out 问题。用两个连接来分别处理发送和接收消息,叫做传输层异步(Transport Level Asynchrony)。
         将前面的 2 种异步结合起来,就有了四种不同的调用模式
      服务的调用代码:
blocking invocation
[code]
try {
   OMElement payload = ClientUtil.getEchoOMElement();
   Options options = new Options();
   options.setTo(targetEPR); // this sets the location of MyService service
   ServiceClient serviceClient = new ServiceClient();
   serviceClient.setOptions(options);
   OMElement result = sender.sendReceive(payload);
   System.out.println(result);
} catch (AxisFault axisFault) {
   axisFault.printStackTrace();
} [/code]
 
IN-ONLY
[code]
try {
   OMElement payload = ClientUtil.getPingOMElement();
   Options options = new Options();
   options.setTo(targetEPR);
   ServiceClient serviceClient = new ServiceClient();
   serviceClient.setOptions(options);
   serviceClient.fireAndForget(payload);
} catch (AxisFault axisFault) {
   axisFault.printStackTrace();
} [/code]
 EchoBlockingClient
    将第一段代码的调用代码改为 serviceClient.sendReceiveNonblocking(payload, callback); 具体的例子在 "Axis2Home/samples/userguide/src/userguide/clients" 中
Axis 提供三个方法来接收 callback 对象
public abstract void onComplete(AsyncResult result);
public abstract void onError(Exception e);
public boolean isComplete() {}
其中,前面两个是需要用户来实现的
[code]
try {
OMElement payload = ClientUtil.getEchoOMElement();
    Options options = new Options();
    options.setTo(targetEPR);
    options.setAction("urn:echo");
    //Callback to handle the response
    Callback callback = new Callback() {
      public void onComplete(AsyncResult result) {
        System.out.println(result.getResponseEnvelope());
      }
      public void onError(Exception e) {
        e.printStackTrace();
      }
    };
    //Non-Blocking Invocation
    sender = new ServiceClient();
    sender.setOptions(options);
    sender.sendReceiveNonBlocking(payload, callback);

    //Wait till the callback receives the response.
    while (!callback.isComplete()) {
       Thread.sleep(1000);
    }

} catch (AxisFault axisFault) {
  axisFault.printStackTrace();
} catch (Exception ex) {
  ex.printStackTrace();
} finally {
   try {
     sender.cleanup();
   } catch (AxisFault axisFault) {
                //
   }
} [/code]

EchoNonBlockingDualClient
[code]
try {
   OMElement payload = ClientUtil.getEchoOMElement();
   Options options = new Options();
   options.setTo(targetEPR);
   options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
   options.setUseSeparateListener(true);
   options.setAction("urn:echo"); // this is the action mapping we put within the service.xml

   //Callback to handle the response
   Callback callback = new Callback() {
      public void onComplete(AsyncResult result) {
         System.out.println(result.getResponseEnvelope());
      }
     public void onError(Exception e) {
       e.printStackTrace();
     }
   };
   //Non-Blocking Invocation
   sender = new ServiceClient();
   sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
   sender.setOptions(options);
   sender.sendReceiveNonBlocking(payload, callback);
   //Wait till the callback receives the response.
   while (!callback.isComplete()) {
      Thread.sleep(1000);
   }
   //Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
   axisFault.printStackTrace();
} catch (Exception ex) {
   ex.printStackTrace();
} finally {
   try {
      sender.finalizeInvoke();
   } catch (AxisFault axisFault) {
   //have to ignore this
   }
} [/code]
 
    在 Server 端添加 Addressing 支持的方式是,在 Addressing Module 中,将 Handlers 的描述放在 ”pre-dispatch” 语句中,那么它的加载则需要通过在 "/webapps/axis2/WEB-INF" 文件夹下的 axis2.xml 中增加一句话来完成: <module ref="addressing"/>
    客户端支持 Addressing 的方式,一种是将 addressing-<version>.mar 放在 classpath 中,另一种就是根据给定的库位置创建一个 ConfigurationContext
    具体的做法是在 sender = new ServiceClient(); 之前加上
ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
    然后将 "sender = new ServiceClient();" 改为 "sender = new ServiceClient(configContext, null);"
  (五):HelloWorld二改进版(ADB)
       1:要想使用Axis2 Databinding Framework (ADB),首先需要根据WSDL来生成在服务端的skeleton文件。进入cmd,设置路径到工程的根下面,运行如下语句:
WSDL2Java -uri classes\META-INF\StockQuoteService.wsdl -p samples.quickstart.service.adb -d adb -s -ss -sd -ssi -o build\service
          运行完成后,会生成一个build的文件夹,里面有很多生成的东西。
          其中:-d:表示是adb; 
                -s:表示是同步调用;
                -ss:表示创建服务端的代码(包括skeleton和相关文件);
                -sd:表示创建services.xml;
                -ssi:表示为skeleton创建接口;
       2:然后就需要开发人员去实现skeleton的接口了,实现类的架子已经生成了,只要去实现就好了,当然,需要将build\service\src的文件夹添加到Eclipse中工程的源代码来源中。实现类如下:

[code]
package samples.quickstart.service.adb;
import java.util.HashMap;
import samples.quickstart.service.pojo.*;
public class StockQuoteServiceSkeleton implements
    StockQuoteServiceSkeletonInterface {
  private static HashMap map = new HashMap();
  public void update(Update param0) {
    map.put(param0.getSymbol(), new Double(param0.getPrice()));
  }
  public GetPriceResponse getPrice(GetPrice param1) {
    Double price = (Double) map.get(param1.getSymbol());
    double ret = 42;
    if (price != null) {
      ret = price.doubleValue();
    }
    GetPriceResponse res = new GetPriceResponse();
    res.set_return(ret);
    return res;
  }
}[/code]

       3:客户端的Stub也同样需要生成,进入cmd,设置路径到工程的根下面,运行如下语句:
WSDL2Java -uri classes\META-INF\StockQuoteService.wsdl -p samples.quickstart.clients -d adb -s -o build\client
          运行完成后,会生成一个build的文件夹,里面有client文件夹。
          需要将build\ client\src的文件夹添加到Eclipse中工程的源代码来源中。

       4:同样需要services.xml文件来描述,如下:
[code]
<service name="StockQuoteService" scope="application">
    <messageReceivers>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                         class="samples.quickstart.service.adb.StockQuoteServiceMessageReceiverInOut"/>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
                         class="samples.quickstart.service.adb.StockQuoteServiceMessageReceiverInOnly"/>
    </messageReceivers>
    <parameter name="ServiceClass">samples.quickstart.service.adb.StockQuoteServiceSkeleton
    </parameter>
    <operation name="update" mep="http://www.w3.org/2004/08/wsdl/in-only">
        <actionMapping>urn:update</actionMapping>
    </operation>
    <operation name="getPrice" mep="http://www.w3.org/2004/08/wsdl/in-out">
        <actionMapping>urn:getPrice</actionMapping>
        <outputActionMapping>http://quickstart.samples/StockQuoteServicePortType/getPriceResponse</outputActionMapping>
    </operation>
</service>[code]
       5:然后写客户端来调用服务,客户端如下:
[code]
package samples.quickstart.service.adb;

import samples.quickstart.clients.StockQuoteServiceStub;

public class Client {
  public static void main(java.lang.String args[]){
        try{
            StockQuoteServiceStub stub =
                new StockQuoteServiceStub
                ("http://localhost:8080/axis2/services/StockQuoteService");

            getPrice(stub);
            update(stub);
            getPrice(stub);

        } catch(Exception e){
            e.printStackTrace();
            System.err.println("\n\n\n");
        }
    }

    /* fire and forget */
    public static void update(StockQuoteServiceStub stub){
        try{
            StockQuoteServiceStub.Update req = new StockQuoteServiceStub.Update();
            req.setSymbol ("ABC");
            req.setPrice (42.35);

            stub.update(req);
            System.err.println("price updated");
        } catch(Exception e){
            e.printStackTrace();
            System.err.println("\n\n\n");
        }
    }

    /* two way call/receive */
    public static void getPrice(StockQuoteServiceStub stub){
        try{
            StockQuoteServiceStub.GetPrice req = new StockQuoteServiceStub.GetPrice();

            req.setSymbol("ABC");

            StockQuoteServiceStub.GetPriceResponse res =
                stub.getPrice(req);

            System.err.println(res.get_return());
        } catch(Exception e){
            e.printStackTrace();
            System.err.println("\n\n\n");
        }
    }
}[/code]
       6:跟ADB的方式类似的还有:XMLBeans、JiBX进行服务邦定的方式,都是通过WSDL2Java来生成服务端的Skeleton和客户端的Stub,还有相应的接口和实现的架子,具体的服务和客户端的调用还是需要开发人员来写的。
 
【后面还有……】

@luodis
java 私塾课堂笔记——WebService 一:什么是WebService WebService(Web服务)...
luodis 2011/05/17 10:00 回答了问题: java 私塾课堂笔记——WebService

  (四):HelloWorld二改进版(AXIOM)
       1:类文件修改成为
[code]
package samples.quickstart.service.axiom;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

import java.util.HashMap;

public class StockQuoteService {
  private HashMap map = new HashMap();
 
  public OMElement getPrice(OMElement element) throws XMLStreamException {
    //构建节点本身
    element.build();
    //从父节点删除本节点
    element.detach();

    //获取节点的第一个子节点
    OMElement symbolElement = element.getFirstElement();
    //获取这个子节点的文本值
    String symbol = symbolElement.getText();

    //准备返回的值
    String returnText = "42";
    Double price = (Double) map.get(symbol);
    if (price != null) {
      returnText = "" + price.doubleValue();
    }

    //组装需要返回的xml,值也包含在这个xml当中
    //<getPriceResponse>
    //   <price>
    //       returnText
    //   </price>
    //</getPriceResponse>
    OMFactory fac = OMAbstractFactory.getOMFactory();
    OMNamespace omNs = fac.createOMNamespace(
        "http://axiom.service.quickstart.samples/xsd", "tns");
    OMElement method = fac.createOMElement("getPriceResponse", omNs);
    OMElement value = fac.createOMElement("price", omNs);
    value.addChild(fac.createOMText(value, returnText));
    method.addChild(value);

    return method;
  }

  public void update(OMElement element) throws XMLStreamException {
    //构建节点本身
    element.build();
    //从父节点删除本节点
    element.detach();

    //获取节点的第一个子节点——symbol
    OMElement symbolElement = element.getFirstElement();
    //获取这个子节点的文本值
    String symbol = symbolElement.getText();
    //获取节点的第二个字节点——price
    OMElement priceElement = (OMElement) symbolElement.getNextOMSibling();
    //获取price的值
    String price = priceElement.getText();

    //把值放置到缓存中
    map.put(symbol, new Double(price));
  }
}[/code]

       2:service.xml如下:
[code]
<service name="StockQuoteService" scope="application">
    <description>
        Stock Quote Service
    </description>
    <operation name="getPrice">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>
    <operation name="update">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
    </operation>
    <parameter name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</parameter>
</service>[/code]

       3:重新打包,然后拷贝到webapps\axis2\WEB-INF\services下面,覆盖ht.aar
       4:客户端:
[code]
package samples.quickstart.service.axiom;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.clustering.MessageSender;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class Client {
  //指定打包的Service在容器中的物理位置
  private static EndpointReference targetEPR =
        new EndpointReference("http://localhost:8080/axis2/services/StockQuoteService");
  /**
   * 准备访问getPrice方法时需要传递的xml节点
   * <getPrice>
   *   <symbol>
   *     value
   *  </symbol>
   * </getPrice>
   * @param symbol
   * @return
   */
    public static OMElement getPricePayload(String symbol) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");

        OMElement method = fac.createOMElement("getPrice", omNs);
        OMElement value = fac.createOMElement("symbol", omNs);
        value.addChild(fac.createOMText(value, symbol));
        method.addChild(value);
        return method;
    }
    /**
   * 准备访问update方法时需要传递的xml节点
   * <update>
   *   <symbol>
   *     value
   *  </symbol>
   *  <price>
   *    price value
   *  </price>
   * </update>
   * @param symbol
   * @return
   */
    public static OMElement updatePayload(String symbol, double price) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd", "tns");

        OMElement method = fac.createOMElement("update", omNs);

        OMElement value1 = fac.createOMElement("symbol", omNs);
        value1.addChild(fac.createOMText(value1, symbol));
        method.addChild(value1);

        OMElement value2 = fac.createOMElement("price", omNs);
        value2.addChild(fac.createOMText(value2, Double.toString(price)));
        method.addChild(value2);
        return method;
    }
    public static void main(String[] args) {
        try {
          //获或得先从服务上查找WSO的值的节点
            OMElement getPricePayload = getPricePayload("WSO");
            //获得修改WSO的值的节点
            OMElement updatePayload = updatePayload("WSO", 123.42);
           
            //准备options,设置要访问的web服务在什么地方
            Options options = new Options();
            options.setTo(targetEPR);
            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
           
            //直接调用In-Only的服务
            sender.fireAndForget(updatePayload);
           
            System.err.println("price updated");
            //直接调用In-Out的服务
            OMElement result = sender.sendReceive(getPricePayload);
            //获取到的返回值也是xml
            String response = result.getFirstElement().getText();
            System.err.println("Current price of WSO: " + response);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}[/code]

【——还有……】

@luodis
java 私塾课堂笔记——WebService 一:什么是WebService WebService(Web服务)...
luodis 2011/05/14 14:43 回答了问题: java 私塾课堂笔记——WebService

四:怎么做
  (一)目前常见的实现方式:
        开源最流行的是Apache的Axis(Apache Extensible Interaction System),可以跟所有的主流服务器结合。
        SUN,早期时JAX-RPC,现在是JAX-WS
        IBM采用的是自行开发的WSDK(IBM WebSphere SDK for Web Services)
        我们采用:tomcat+axis2
  (二):HelloWorld一
       1:构建运行环境
         (1)把axis2-1.4.1-war.zip中的axis2.war包放到tomcat的webapps中,然后启动tomcat,会发布axis2,如果启动没有错误,就可以下一步
         (2)验证:在地址栏输入http://localhost:8080/axis2 ,如果能正常显示,说明axis2的运行环境已经OK了。可以点击Administration,然后输入用户名admin和密码axis2进入管理台。
       2:构建开发环境
          把axis2-1.4.1-bin.zip中lib里面的都引入到当前的开发环境中就好了
       3:写自己的第一个服务的类
[code]
package cn.javass.ws.helloworld.server;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
public class MyService {
   /**
    * 读取client端传递来的参数,然后执行自己的功能,并返回值给客户端
    */
   public OMElement helloWorldService(OMElement in) {
      //1:接收参数,将in转换为String
      String requestMessage = in.getText();

      //2:这里添加服务端的具体处理
    
      //3:准备返回
      //3.1 创建响应用的SOAP包。
      OMFactory f = OMAbstractFactory.getOMFactory();
      //3.2 OMNamespace指定此SOAP文档名称空间,可以随便写
      OMNamespace omNs = f.createOMNamespace("http://www.javass.cn/", "cc");
      //3.3 创建返回元素,并指定其在omNs指代的名称空间中。
      OMElement retElement = f.createOMElement("myRet", omNs);
      //3.4 指定返回元素的文本内容
      String retMessage = requestMessage + ",这是第一个WebService,已经处理!";
      retElement.setText(retMessage);
   
      return retElement;
   }
}[/code]
       4:在src目录下面建立一个META-INF的文件夹,在里面放Services.xml文件
[code]
<service name="HelloWorldService">
  <parameter name="ServiceClass" locked="xsd:false">
    cn.javass.ws.helloworld.server.MyService
  </parameter>
  <operation name="helloWorldService">
    <messageReceiver
      class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver" />
  </operation>
</service>
[/code]
       5:运行cmd,到classes的目录,然后打包,输入:jar cvf hello.aar . ,注意后面的”.”不能少,表示输出到当前位置,然后打出一个hello.aar的包来。
       6:然后可以直接把这个文件拷贝到tomcat的webapps\axis2\WEB-INF\services文件夹下面,就会自动发布了。当然也可以进到axis2的控制台,然后使用upload service的方式也行。如果发布没有错误,那么服务就做好了。
       7:开始写客户端
[code]
package cn.javass.ws.helloworld;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.clustering.MessageSender;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class Client {

  public static void main(String[] args) {
    try {
      //1:targetEPR指定打包的Service(hello.aar文件)在容器中的物理位置
      EndpointReference targetEPR = new EndpointReference(
          "http://localhost:9000/axis2/services/HelloWorldService");
     
      //2:准备客户端调用
      ServiceClient sender = new ServiceClient();
      //2.1 准备options,设置要访问的web服务在什么地方
      Options options = new Options();
      options.setTo(targetEPR);
      sender.setOptions(options);
     
      //2.2 创建request的SOAP包
      OMFactory f = OMAbstractFactory.getOMFactory();
      //2.3 OMNamespace指定此SOAP文档名称空间,要跟服务那边的对应上
      OMNamespace omNs = f.createOMNamespace("http://www.javass.cn/","cc");
      //2.4 创建元素reqElement,并指定其在omNs指代的名称空间中,第一个参数就是要访问的operation
      OMElement reqElement = f.createOMElement("helloWorldService", omNs);
      //2.5 指定元素的文本内容。
      reqElement.setText("测试第一个WebService");

      //3:发出request SOAP,同时将得到的远端由helloWorldService方法返回的信息保存到result
      OMElement result = sender.sendReceive(reqElement);

      System.out.println(result);
    } catch (Exception axisFault) {
      axisFault.printStackTrace();
    }
  }
}[/code]
       8:运行结果如下:
          客户端:
          <cc:myRet xmlns:cc="http://www.javass.cn/">测试第一个WebService,这是第一个WebService,已经处理!</cc:myRet>
  (三):HelloWorld二(Pojo)
       1:把axis2-1.4.1-bin包解开,然后把下面直到bin的路径设置到path中去,还要设置AXIS2_HOME的值
       2:到axis2-1.4.1-bin包的samples文件夹中,找到quickstart,建立一个工程来测试和运行它,类文件如下:
[code]
package samples.quickstart.service.pojo;
import java.util.HashMap;
public class StockQuoteService {
    private HashMap map = new HashMap();
    public double getPrice(String symbol) {
        Double price = (Double) map.get(symbol);
        if(price != null){
            return price.doubleValue();
        }
        return 42.00;
    }
    public void update(String symbol, double price) {
        map.put(symbol, new Double(price));
    }
}[/code]
       3:运行cmd,把路径设置到classes下面,然后运行:java2wsdl -cp . -cn samples.quickstart.service.pojo.StockQuoteService -of META-INF/StockQuoteService.wsdl,就会生成相应的wsdl文件
       4:在META-INF中建立services文件,内容如下:
[code]
<service name="StockQuoteService" scope="application">
    <description>
        Stock Quote Sample Service
    </description>
    <messageReceivers>
        <messageReceiver
            mep="http://www.w3.org/2004/08/wsdl/in-only"
    class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
        <messageReceiver
            mep="http://www.w3.org/2004/08/wsdl/in-out"
    class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass">
        samples.quickstart.service.pojo.StockQuoteService
    </parameter>
</service>[/code]
       5:运行cmd,把路径设置到classes下面,然后运行:jar -cvf ht.aar.,注意后面有个”.”,然后打好包,文件名称叫ht.aar
       6:把ht.aar拷贝到tomcat的webapps\axis2\WEB-INF\services
       7:启动tomcat,然后运行http://localhost:8080/axis2/services/listServices就可以查看所有发布的服务了
       8:可以通过http://localhost:8080/axis2/services/StockQuoteService?wsdl来查看wsdl的文件,对应的schema在http://localhost:8080/axis2/services/StockQuoteService?xsd
[code]
 <?xml version="1.0" ebcoding="UTF-8"?>
-<wsdl:definitiongs xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd"
  xmlsn:ns="http://pojo.javasscn" xmlns:wsaw="http://www.w3org/2006/05/addressing/wsdl"
  xmlsn:http="http://schemas.xmlsoap.org/wsdl/http" xmlsn:xs="http://www.w3org/2001/XMLSchema"
  xmlsn:mime=" http://schemas.xmlsoap.org/wsdl/mime" xmlsn:soap=" http://schemas.xmlsoap.org/wsdl/soap"
  xmlsn:soap12="http://schemas.xmlsoap.org/wsdl/soap12" targetNamespace=http://pojo.javass.cn>
  <wsdl:documentation>MyPojoService</wsdl:documentation>
 +<wsdl:types>
 +<wsdl:message name="testRequest">
 +<wsdl:message name="testResponse">
 +<wsdl:portType name="MyPojoService portType">
 +<wsdl:binding name="MyPojoServiceSoap11Binding"type="ns: MyPojoService portType">
 +<wsdl:binding name="MyPojoServiceSoap12Binding" type="ns:MyPojoService portType">
 +<wsdl:binding name="MyPojoServiceHttpBinding" type="ns:MyPojoService portType">
 +<wsdl:service name="MyPojoService
 </wsdl:definitiongs>
[/code]
       9:可以在IE里面进行测试,测试步骤如下:
         (1)运行下述语句进行查看
http://localhost:8080/axis2/services/StockQuoteService/getPrice?symbol=javasscn会得到如下结果:
<ns:getPriceResponse xmlns:ns="http://pojo.service.quickstart.samples">
  <ns:return>42.0</ns:return>
</ns:getPriceResponse>
         (2)然后运行下述语句进行修改
http://localhost:8080/axis2/services/StockQuoteService/update?symbol=javasscn&price=100
         (3)再次运行(1),你会发现结果变成了:
<ns:getPriceResponse xmlns:ns="http://pojo.service.quickstart.samples">
  <ns:return>100.0</ns:return>
</ns:getPriceResponse>
 
——未完——

@luodis
java 私塾课堂笔记——WebService 一:什么是WebService WebService(Web服务)...
luodis 2011/04/13 11:04 回答了问题: Java 私塾第三、四章笔记整理

学习一下

@luodis
Java 私塾第三、四章笔记整理一.面向对象初步二.面向对象三大特征: 1.封装:把对象的全部属性和全部服务结合在...

JAVA 私塾老师博客:http://chjavach.iteye.com/
JAVA 私塾免费学习视频网址:www.javass.cn

@luodis
2010年51CTO最受读者喜欢的图书与作者评选出炉了 首先恭喜JAVA私塾的老师被评为最受欢迎的作者第1名,同时...
luodis 2011/04/01 09:36 回答了问题: java 私塾随堂笔记——Struts1.0


  创建add.jsp
[code]
<%@ page language="java" contentType="text/html; charset=gb2312";pageEncoding="gb2312"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新增页面</title>
</head>
  <body>
    <html:form action="/cc.do">
      业务编号:<html:text property="uuid"></html:text><br>
      用户编号:<html:text property="userId"></html:text><br>
      用户姓名:<html:text property="name"></html:text><br>
      用户年龄:<html:text property="age"></html:text><br>
      <html:submit value="提交"></html:submit>
    </html:form>
  </body>
</html>[/code]
 
  说明:
     * 添加一个表单,action为cc.do,这个cc.do的意思,将会告诉struts的ActionServlet,它将需要调用哪个Action来处理这个表单的请求
     * 添加输入域name,这个name的表单字段,必须跟UserActionForm中的属性一致
 
  运行流程:
     * 当你从浏览器输入地址:http://localhost:8088/web/pages/add.jsp,Tomcat将按通常情况来处理这个JSP并返回浏览器
     * 当你提交表单,实际上是提交到了这样一个URL地址:http://localhost:8088/web/cc.do,Tomcat将会根据web.xml的配置,将这个请求发送给相应的Servlet,在我们的应用中,Tomcat将会把这个请求发送给org.apache.struts.action.ActionServlet这个类(请参看web.xml的配置)
     * 然后ActionServlet根据struts-config.xml的配置信息,调用UserAction对象去处理这个请求,在此之前,它会将页面表单的请求数据封装到UserForm对象中,并传递给LoginAction
     * UserAction返回一个ActionForward对象,包含了将要转向的路径信息
     * ActionServlet根据这个ActionForward对象所包含的路径信息,调用相应的页面去执行响应
 
Struts1和Struts2的区别和对比:
   * Action 类:
       ·Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
       ·Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
   * 线程模式:
       ·Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
       ·Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
   * Servlet 依赖:
       ·Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
       ·Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。
   * 可测性:
       ·测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
       ·Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
   * 捕获输入:
       ·Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。
       ·Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。
   * 表达式语言:
       ·Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
       ·Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL).
   * 绑定值到页面(view):
       ·Struts 1使用标准JSP机制把对象绑定到页面中来访问。
       ·Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
   * 类型转换:
       ·Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
       ·Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
   * 校验:
       ·Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
       ·Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
   * Action执行的控制:
       ·Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
       ·Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
   * MyEclipse支持struts1,不支持struts2.

@luodis
java 私塾随堂笔记——Struts1.0 一.Struts1是什么? 基于MVC的轻量级,web应用框架。 二...
luodis 2011/03/03 15:11 发布了问题:

没有更多内容

加载失败,请刷新页面

返回顶部
顶部