Home  >  Article  >  php教程  >  WebService working principle

WebService working principle

高洛峰
高洛峰Original
2016-12-15 15:14:211212browse

I have been writing WebService for a while, and I will summarize what I have collected and understood about the working principle of WebService.

WebService mainly uses the Http protocol, which is an application layer protocol based on Tcp/Ip: (Note: Most of the current WebService development has been able to support socket real-time communication very well. But http is still its essence.)

 Http adopts the "request-----response" mode;

 Http communication is serialized communication through XML The...

 Http communication process: calling .asmx handle, XML, XSD, SOAP and WSDL processing,

  There are three main aspects provided in XML: (The following article is quoted from: http://dev.csdn .net/article/19/19185.shtm)

Personally, I feel that the main thing to master is the xml format of the SOAP request message and response message...

Message dispatch

When the .asmx handle is called by the HTTP pipeline, by viewing The WebService declaration in the .asmx file determines which .NET class is checked. It then observes the information in the incoming HTTP message and determines which method in the referenced class to call. In order to call the Add method in the previous example, the HTTP request message should look like the following:

WebService working principle

There are two pieces of information in the above HTTP request message that can be used to determine which method in the class to call: the SOAPAction header or the soap body of the request The name of the element. In this example, each method indicates the name of the method the sender wants to call.

.asmx handle uses the value of the SOAPAction header to implement message dispatch. Therefore, the .asmx handle looks at the SOAPAction header in the message and uses the .NET mapping to check for the method in the referenced class. It only considers methods marked with the [WebMethod] attribute, but determines specifically which method to call by looking at the SOAPAction value of each method. Because we did not explicitly specify the value of SOAPAction in the class, the .asmx handle assumes that the value of SOAPAction is the namespace of the Web service plus the method name. And we didn't specify a namespace, so the handler defaults to http://tempuri.org. In this way, the default SOAPAction value of the Add method is http://tempuri.org/Add.

You can customize the namespace of the web service as follows. Mark the class with the [WebService] attribute and mark the WebMethods with the [SoapDocumentMethod] attribute to specify the specific SOAPAction value. Example is as follows:

using System.Web.Services;
using System.Web.Services.Protocols;
 
[WebService(Namespace="http://example.org/math")]
public class MathService
{
   [WebMethod]
   public double Add(double x, double y) {
      return x + y;
   }
   [WebMethod]
   [SoapDocumentMethod(Action="urn:math:subtract")]
   public double Subtract(double x, double y) {
      return x - y;
   }
   ...
}

Now the .asmx handle thinks that the SOAPAction value of the Add method is http://example.org/math/Add and the SOAPAction value of the SubTract method is urn:math:subtract (because we explicitly defined it in the class) . For example, the following HTTP request message calls Subtract:

WebService working principle

If the .asmx handle does not find a SOAPAction match for the HTTP request message, an exception will be thrown. If you don't want to rely on the SOAPAction header to dispatch messages, you can direct the .asmx handle to use the request element name. To adopt this approach, you need to mark the class with the RoutingStyle attribute of the [SoapDocumentService] attribute. You should also point out that WebMethods do not require a SOAPAction value (set its value to empty in the class). As shown below:

using System.Web.Services;
using System.Web.Services.Protocols;
 
[WebService(Namespace="http://example.org/math")]
[SoapDocumentService(
  RoutingStyle=SoapServiceRoutingStyle.RequestElement)]
public class MathService
{
   [WebMethod]
   [SoapDocumentMethod(Action="")]
   public double Add(double x, double y) {
      return x + y;
   }
   [WebMethod]
   [SoapDocumentMethod(Action="")]
   public double Subtract(double x, double y) {
      return x - y;
   }
    ...
}

In this case, the handler doesn't even care about the value of SOAPAction, it uses the name of the request element to determine the calling method. For example, in the following HTTP request message, it hopes that the name of the request element that calls the Add method is Add:

So when the .asmx handle receives the HTTP message, the first thing it does is to decide how to dispatch the message to the corresponding WebMethod. Before it can actually call the method, it also needs to map the incoming XML to a .NET object.

Mapping XML to Objects

Once the WebMethod handle decides which method to call, it deserializes the XML message into a .NET object. As the message is dispatched, the handler checks the class via reflection and then decides how to handle the XML message. The XmlSerializer class automatically completes the mapping of XML to classes in the System.Xml.Serialization namespace.

XmlSerializer can map any .NET public type to XML Schema type. With this appropriate mapping, it can automatically map .NET objects to XML instance documents (see Figure 4). XmlSerializer is limited by the functions supported by XML Schema. Although it cannot handle all complex modern object models (such as non-tree object graphs), it can handle complex types commonly used by developers.

Looking at the previous Add example, XmlSerializer will map the x and y elements to .NET double values ​​(must be provided when calling the Add method). The Add method returns a double type value to the caller, which also needs to be serialized into an XML element in the SOAP response message.

Figure 4. Mapping XML to objects

XmlSerializer也能自动处理一些复杂类型(除了上面说到的一些限制)。比如,下面的WebMethod计算两个点结构之间的距离。

using System;
using System.Web.Services;
public class Point {
  public double x;
  public double y;
}
[WebService(Namespace="urn:geometry")]
public class Geometry {
  [WebMethod]
  public double Distance(Point orig, Point dest) {
    return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) +
                     Math.Pow(orig.y-dest.y, 2));
  }
}

请求此操作的SOAP消息将包含一个Distance元素,它包含了两个子元素,一个称作orig,另一个是dest,每一个都包括了x和y元素,如下所示:

WebService working principle

这种情况下SOAP应答消息将包含一个DistanceResponse元素,它包含一个double 类型的DistanceResult子元素。

WebService working principle

缺省的XML映射使用方法名作为请求元素名,参数名作为子元素名。每个参数的结构依赖于类型的结构。公共字段和属性的名字简单映射为子元素,如Point类中的x和y。应答元素的名字缺省为请求元素的名字后面附加上“Response”,应答元素也包含一个子元素,是请求元素名字后面附加“Result”。也有可能使用一些固定的映射属性来打破标准的XML映射。比如,你可以使用[XmlType]属性来定制类型的名字和名称空间,使用[XmlElement]和[XmlAttribute]属性来控制如何将参数或类成员分别映射为元素或属性,也可以使用[SoapDocumentMethod]属性控制怎样把方法本身映射为请求/响应消息中的元素名。比如,检查下面重新定义的Distance。

using System;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
 
public class Point {
  [XmlAttribute]
  public double x;
  [XmlAttribute]
  public double y;
}
[WebService(Namespace="urn:geometry")]
public class Geometry {
  [WebMethod]
  [SoapDocumentMethod(RequestElementName="CalcDistance",
     ResponseElementName="CalculatedDistance")]
  [return: XmlElement("result")]
  public double Distance(
    [XmlElement("o")]Point orig, [XmlElement("d")]Point dest) {
    return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) +
                     Math.Pow(orig.y-dest.y, 2));
  }
}

它所期望的SOAP请求消息如下:

WebService working principle

.asmx句柄使用SOAP document/literal风格来实现和描述上面显示的默认映射。意思上说WSDL定义将包含literal XML schema定义,它描述了SOAP消息中用到的请求和响应元素。

.asmx句柄也能使用SOAP rpc/encoded风格。这意味着SOAP体中包含一个RPC调用的XML代表(representation),参数用SOAP编码规则来串行化。实现这些仅需将[SoapDocumentService] and [SoapDocumentMethod]替换为[SoapRpcService] and [SoapRpcMethod]属性。

正如你所看到的,我们可能完全定制一个从给定方法到SOAP消息的映射。XmlSerializer提供了一个强大的串行化引擎。

除了处理参数的反串行化,.asmx句柄也能串行化/反串行化SOAP头。SOAP头的处理不同于参数,因为它们被认为是典型的无法控制的信息,和具体的方法没有直接的联系。由于这些,头处理主要是通过中间层(interception layers),完全为WebMethods屏蔽了头处理。

然而如果想涉足于WebMethod中的头信息,你必须提供一个.NET类,从SoapHeader派生而来,它代表了头的XML schema类型。然后定义一个此类型的成员变量作为每一个头实例的占位符。最后标记每个要访问头的WebMethod,指定你想要到达的域名。

比如,下面的SOAP请求包括一个用来进行身份验证的UsernameToken头。

WebService working principle



更多WebService working principle相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn