`
schy_hqh
  • 浏览: 558150 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

基于契约优先的隐式头信息处理

 
阅读更多
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
					xmlns:tns="http://www.example.org/my/" 
					xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
					xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
					name="myServiceImplService" targetNamespace="http://www.example.org/my/">
<!-- TYPE -->			
  <wsdl:types>
  	<!-- 定义schema,通过tns引用该schema中的元素 -->
    <xsd:schema targetNamespace="http://www.example.org/my/">
      <xsd:element name="add" type="tns:addType"/>
      <xsd:element name="addResponse" type="tns:addResponseType"/>
      <!-- 为license创建element元素 -->
	  <xsd:element name="license" type="xsd:string"/>
	  
	  <xsd:complexType name="addType">
	  	<xsd:sequence>
	  		<xsd:element name="a" type="xsd:int"/>
	  		<xsd:element name="b" type="xsd:int"/>
	  	</xsd:sequence>
	  </xsd:complexType>
	  
	  <xsd:complexType name="addResponseType">
	  	<xsd:sequence>
	  		<xsd:element name="addResult" type="xsd:int"/>
	  	</xsd:sequence>
	  </xsd:complexType>	  	 
	  
    </xsd:schema>
  </wsdl:types>
  
<!-- MESSAGE -->  
  <wsdl:message name="add">
    <wsdl:part element="tns:add" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="addResponse">
    <wsdl:part element="tns:addResponse" name="parameters"/>
  </wsdl:message>
  <!-- 为license创建新的message -->
  <wsdl:message name="license">
  	<wsdl:part name="license" element="tns:license"></wsdl:part>
  </wsdl:message>
  
<!-- PORTTYPE 指定接口和方法 -->  
  <wsdl:portType name="IMyservice">
    <wsdl:operation name="add">
      <wsdl:input message="tns:add"/>
      <wsdl:output message="tns:addResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  
<!-- BINDING 指定编码方式 -->  
  <wsdl:binding name="MyServiceImplPortBinding" type="tns:IMyservice">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="add">
      <wsdl:input>
      	<!-- add方法的header中加入license消息 -->
        <soap:header use="literal" part="license" message="tns:license"></soap:header>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  
 <!-- 
 	SERVICE服务
  	注意:service name必须与wsdl definition中的name一致
  --> 
  <wsdl:service name="MyServiceImplService">
    <wsdl:port binding="tns:MyServiceImplPortBinding" name="MyServiceImplPort">
      <!-- 指定服务发布的地址 -->
      <soap:address location="http://localhost:7777/ms"/>
    </wsdl:port>
  </wsdl:service>
  
</wsdl:definitions>




package org.example.my;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
/**
 * 接口
 */

/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.6 in JDK 6
 * Generated source version: 2.1
 * 
 */
@WebService(name = "IMyservice", targetNamespace = "http://www.example.org/my/")
public interface IMyservice {


    /**
     * 
     * @param b
     * @param a
     * @param license 头信息
     * @return
     *     returns int
     */
    @WebMethod
    @WebResult(name = "addResult", targetNamespace = "")
    @RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/my/", className = "org.example.my.AddType")
    @ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/my/", className = "org.example.my.AddResponseType")
    public int add(
        @WebParam(name = "a", targetNamespace = "")
        int a,
        @WebParam(name = "b", targetNamespace = "")
        int b,
        @WebParam(name = "license", header=true)
        String license);

}



package org.example.my;

import javax.jws.WebService;
/**
 * 实现类
 * 指定wsdlLocation="META-INF/wsdl/my.wsdl",使用本地以及编写好的wsdl文件
 */
@WebService(endpointInterface="org.example.my.IMyservice",
			targetNamespace = "http://www.example.org/my/",
			wsdlLocation="META-INF/wsdl/my.wsdl")
public class MyServiceImpl implements IMyservice {

	@Override
	public int add(int a, int b, String license) {
		//如果客户端没有传递头信息,则license为null
		System.out.println("MyServiceImpl.add() "+license);
		return a+b;
	}

}


开启服务
package org.example.my;

import javax.xml.ws.Endpoint;

public class MyServer {
	public static void main(String[] args) {
		String address = "http://localhost:7777/ms";
		IMyservice implementor = new MyServiceImpl();
		Endpoint.publish(address, implementor);
	}

}



基于契约优先的方式,wsdl中定义的头信息,在客户端生成的代码中不体现


package org.example.my;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.6 in JDK 6
 * Generated source version: 2.1
 * 
 */
@WebService(name = "IMyservice", targetNamespace = "http://www.example.org/my/")
@XmlSeeAlso({
    ObjectFactory.class
})
public interface IMyservice {


    /**
     * 
     * @param b
     * @param a
     * @return
     *     returns int
     */
    @WebMethod
    @WebResult(name = "addResult", targetNamespace = "")
    @RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/my/", className = "org.example.my.AddType")
    @ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/my/", className = "org.example.my.AddResponseType")
    public int add(
        @WebParam(name = "a", targetNamespace = "")
        int a,
        @WebParam(name = "b", targetNamespace = "")
        int b);

}



客户端调用服务端的服务
package org.example.my.test;

import static org.junit.Assert.*;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;

import org.example.my.IMyservice;
import org.example.my.MyServiceImplService;


public class Test {
	/**
	 * 使用本地接口调用服务端的服务
	 */
	@org.junit.Test
	public void testNoHeader() {
		MyServiceImplService serviceImpl = new MyServiceImplService();
		IMyservice service = serviceImpl.getMyServiceImplPort();
		int result = service.add(1, 2);
		System.out.println(result);
	}
	
	/**
	 * 通过SOAP发送消息
	 * 并在header中传递隐式的头信息
	 * 隐式的原因:客户端根据wsdl生成的代码中,接口方法中的参数并没有增加
	 * 客户端可以在header中传递信息,服务端可以解析出来
	 */
	@org.junit.Test
	public void testHeader() throws Exception {
		String ns = "http://www.example.org/my/";
		String localPart = "MyServiceImplService";
		String address = "http://localhost:7777/ms";
		String prefix = "ns";
		
		URL wsdlDocumentLocation = new URL(address);
		QName serviceName = new QName(ns,localPart,prefix);
		//创建服务
		Service service = Service.create(wsdlDocumentLocation,serviceName);
		
		String prot = "MyServiceImplPort";
		QName portName = new QName(ns, prot);
		//创建dispatcher
		Dispatch<SOAPMessage> dispatcher = 
				service.createDispatch(portName,SOAPMessage.class,Service.Mode.MESSAGE);
		
		SOAPMessage message = MessageFactory.newInstance().createMessage();
		SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
		SOAPHeader header = envelope.getHeader();
		SOAPBody body = envelope.getBody();
		if(header==null)
			header = envelope.addHeader();
		
		//添加header
		String hearderLoaclPart = "license";
		QName headerQName = new QName(ns, hearderLoaclPart, prefix);
		SOAPHeaderElement headerEle = header.addHeaderElement(headerQName);
		headerEle.setValue("this is 隐式头消息");
		
		//添加body
		//指名访问的方法名:add
		String bodyLoaclPart = "add";
		QName bodyQName = new QName(ns, bodyLoaclPart, prefix);
		SOAPBodyElement bodyEle = body.addBodyElement(bodyQName);
		bodyEle.addChildElement("a").setValue("99");
		bodyEle.addChildElement("b").setValue("101");
		
		message.writeTo(System.out);
		System.out.println("\n invoking...");
		
		SOAPMessage retMsg = dispatcher.invoke(message);
		retMsg.writeTo(System.out);
		
	}
}


运行结果
testNoHeader()
客户端:3
服务端:MyServiceImpl.add() null


testHeader()
客户端:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	<SOAP-ENV:Header>
		<ns:license xmlns:ns="http://www.example.org/my/">this is 隐式头消息</ns:license>
	</SOAP-ENV:Header>
	<SOAP-ENV:Body>
		<ns:add xmlns:ns="http://www.example.org/my/">
			<a>99</a>
			<b>101</b>
		</ns:add>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
 invoking...
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Header />
	<S:Body>
		<ns2:addResponse xmlns:ns2="http://www.example.org/my/">
			<addResult>200</addResult>
		</ns2:addResponse>
	</S:Body>
</S:Envelope>

服务端:
MyServiceImpl.add() this is 隐式头消息
分享到:
评论

相关推荐

    c#实用编程规范

    以下是一些核心的C#编程规范,这些都是基于实践中提炼出的良好习惯: 1. **命名规范**: - 类(Class):使用 PascalCase,如 `MyClassName`。 - 方法(Method):使用 PascalCase,如 `DoSomething()`。 - 变量...

    C#入门学习示例

    根据给定的文件信息,以下是对C#编程语言的一些关键知识点的详细解释: ### C#入门学习示例 #### Bike2 在这个示例中,我们看到了C#中的类和对象的概念。`Bike` 类包含了行为(即方法),如 `AcceptBikeDetail()`...

    JAVA 面向对象资料

    面向对象编程基于“对象”的理念,对象是现实世界中的实体在程序中的抽象。它包含了数据(属性)和操作这些数据的方法(行为)。类是创建对象的模板,定义了一组具有相同属性和方法的对象的蓝图。在Java中,我们使用...

    c#文档微软.pdfc#文档微软.pdfc#文档微软.pdf

    预定义类型涵盖了数值、布尔等基础类型,而类型转换则提供了显式和隐式的转换机制,数组类型则允许程序员处理固定大小的数据集合。 - **变量与参数**:详细阐述了变量的声明、初始化和使用,以及函数参数的传递方式...

    Effective C# 中文版改善C#程序的50种方法

    19. **利用强类型避免隐式类型转换**:虽然var简化了代码,但过度使用可能隐藏类型信息,导致错误难以发现。 20. **理解并使用枚举类型**:枚举提供了一种方便的方式来表示一组相关的常量,便于使用和理解。 以上...

    C#编程规范.rar

    10. **错误处理**:尽量提供有意义的错误信息,帮助调试。避免返回错误代码,而是抛出异常。 以上只是C#编程规范的一部分,实践中还需要根据团队的约定和个人习惯进行调整。通过遵循这些规范,开发者可以创建出高...

    中文第三版 Effective C++

    6. **异常安全**:书中讲解了异常处理策略,包括基本异常安全、强烈异常安全和不抛异常的契约。他提倡编写能够优雅处理异常的代码,确保在异常发生时资源得到正确释放。 7. **设计与实现**:Meyers还探讨了多态、虚...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    11.1.1 第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息 11.1.2 第二步:定义事件成员 11.1.3 第三步:定义负责引发事件的方法来通知事件的登记对象 11.1.4 第四步:定义方法将输入转化为期望...

    CLR.via.C#.(中文第3版)(自制详细书签)

    CLR.via.C#.(中文第3版)(自制详细书签)Part2 CLR via C#(第3版) Jeffrey Richter 著 周靖 译 ...27.11 基于事件的异步模式 27.11.1 将EAP转换为Task 27.11.2 APM和EAP的对比 27.12 编程模型的泥沼...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    · 借助于异常处理来进行状态管理 · 使用CLR寄宿、AppDomain、程序集加载、反射和C#的dynamic类型来构造具有动态扩展能力的应用程序 本书作者作者Jeffrey Richter,.NET和Windows编程领域当之无愧的大师和权威,以...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    · 借助于异常处理来进行状态管理 · 使用CLR寄宿、AppDomain、程序集加载、反射和C#的dynamic类型来构造具有动态扩展能力的应用程序 本书作者作者Jeffrey Richter,.NET和Windows编程领域当之无愧的大师和权威,以...

    数据类型.rar

    数据类型在计算机科学和编程领域是至关重要的概念,它们决定了我们如何存储和处理信息。数据类型定义了变量的性质和行为,是编程语言的基础组成部分。在这个“数据类型.rar”压缩包中,包含了一个名为“数据类型.md...

    J2EE中文版指南 CHM格式 带全文检索

    隐式对象 181 特定应用程序对象 181 共享对象 182 JSP scripting 元素 182 声明 182 脚本(scriptlets) 183 表达式 184 在JSP页面中包含内容 185 转换控制到另一网络组件 185 参数元素 185 包含Java小程序(applet) ...

    C#高效编程改进C#代码的50个行之有效的办法( 第2版) 中文版

    5. **理解并使用var关键字**:var用于隐式类型推断,有助于提高代码的可读性,但需注意其与动态类型的区别。 6. **利用Auto-Properties减少冗余代码**:自动属性可以减少getter和setter的代码量,使代码更简洁。 7...

    C#文档中文版(微软)

    - **转换**:C# 提供了显式和隐式的类型转换机制。 - **数组类型**:数组是一种固定大小的数据结构,用于存储同类型的元素集合。 - **类型系统的统一性**:C# 中的所有类型都直接或间接地派生自 `object` 类型。 ...

    java代码-实训4 31号卢永康

    - 类型转换:在需要不同数据类型之间进行操作时,可能需要显式或隐式类型转换。 - 控制流:包括条件语句(if-else)、循环(for、while、do-while)以及分支结构(switch)。 - 方法定义:编写可重用代码块,通过...

    C# 快速入门

    .NET的目标是构建一个基于组件的互联网,在这个平台上,不同的组件能够无缝地进行交互,无论它们是由何种语言编写的。 - **1.1.2 .NET框架** .NET框架由两个主要部分组成:公共语言运行时(CLR)和.NET Framework...

    c#f教程

    - **参数**:用于传递信息到方法,支持按值传递、按引用传递、输出参数等多种方式。 **11.3 静态和非静态的方法** - **静态方法**:属于类本身,而不是类的实例,可以通过类名直接调用。 - **非静态方法**:属于类...

    c#系列教程(pdf)

    - 接口定义了组件的公共契约,使得组件之间可以相互协作。 - **接口定义** - 接口是一组方法、属性、事件和索引指示器的集合,没有具体实现。 - **接口的成员** - 成员声明了操作的签名,但没有实现细节。 - *...

Global site tag (gtag.js) - Google Analytics