Web Service学习笔记之----JAX-RPC

本文详细介绍了使用JAX-RPC开发Web Service的步骤,包括创建服务端接口、部署服务、生成客户端代码及不同类型的客户端调用。还涉及了SOAP消息处理器的使用,展示了如何在服务端和客户端实现处理器,以进行日志和消息处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导读:
  导读
  本文是我对学习jwsdp-1.2时所做笔记的整理,其中主要是一些指导性的内容,并没有多少概念以及原理的介绍,读者可能觉得略显简单,如果想要学习基本概念可以参考网上有关Web Service的资料。本文例子所使用的开发环境是WindowXP+JWSDP-1.2。
  一.Web Service简介
  1.定义
  由两部分组成
  ·SOAP--Web Service之间的基本通信协议。
  ·WSDL--Web Service描述语言,它定义了Web Service做什么,怎么做和查询的信息。
  2.简单的Web Service实现
  包含四个基本步骤
  ·创建Web Service的商业逻辑(通常是一些Java类)
  ·将这些Java类部署到一个SOAP服务器上
  ·生成客户访问代码
  ·部署客户应用
  注意:WSDL等文件的生成通常是利用厂商提供的工具来完成
  3.WSDL解析
  WSDL描述语言一般包含三部分
  ·What部分--包括了type、message和portType元素
  Type:定义了Web Service使用的数据结构(使用XML Schema定义)
  Message:一个Message是SOAP的基本通信元素。每个Message可以有一个或多个Part,每个Part代表一个参数。
  PortType:消息汇总为不同的操作并归入到一个被称为portType的实体中。一个portType代表一个接口(Web Service支 持的操作集合),每个Web Service可以有多个接口,它们都使用portType表示。每个操作又包含了input和 output部分。
  ·How部分--包含binding元素
  binding元素将portType绑定到特定的通信协议上(如HTTP上的SOAP协议)
  ·Where部分--由service元素组成
  它将portType,binding以及Web Service实际的位置(URI)放在一起描述
  4.客户端
  通常Web Service可以有三种类型的客户
  ·商业伙伴(Business Partner)--包括分发商,零售商以及大型消费者)
  此类客户通过SOAP、WSDL、ebXML、UDDI等XML技术与Web Service连接
  ·瘦客户--包括Web浏览器、PDA以及无线设备
  该类客户通常经由轻量协议(如HTTP)与Web Service连接
  ·肥客户--包括Applet、各类应用以及现存系统
  通常使用重量级协议(如IIOP)连接Web Service
  二.使用JAX-RPC开发Web Service
  1.JAX-RPC支持的数据类型
  JAX-RPC除了支持Java的基本数据类型外还支持一些自定义对象,但这些对象有一些条件限制
  ·有缺省构造函数的对象
  ·没有实现java.rmi.Remote接口
  ·字段必须是JAX-RPC支持的类型
  ·公有字段不能声明为final或transient
  ·非公有字段必须有对应的setter和getter方法
  2.使用JAX-RPC创建Web Service
  ·基本步骤
  A. 编写服务端接口并实现
  一个服务的end-point有一些规定:必须实现java.rmi.Remot接口而且每个方法需要抛出RemoteException异常。
  B. 编译、生成并且将所有服务需要的类和文件打包成WAR文件
  C. 部署包含服务的WAR文件
  ·如何创建服务
  A. 编译服务所需的类文件
  B. 生成服务所需文件
  可以使用wscompile工具生成model.gz文件,它包含了描述服务的内部数据结构命令如下
  wscompile -define -d build -nd build -classpath build config.xml
  -model build/model.gz
  define标志告诉工具读取服务的 endpoint接口并且创建WSDL文件。-d和-nd标志告诉工具将输出文件写入指定的目录build。工具需要读以下的config.xml文件
  
  
  
name=”HelloService”
targetNamespace=”urn:Star”
typeNamespace=”urn:Star”
packageName=”helloservice”>  name=”HelloService”
  targetNamespace=”urn:Star”
  typeNamespace=”urn:Star”
  packageName=”helloservice”>
  
  
  
  该文件告诉wscompile创建model文件所需的信息
  ·服务名称:MyHelloService
  ·WSDL名字空间:urn:Star
  ·HelloService的所有类在包helloservice中
  ·服务的端点(endpoint)接口:helloservice.HelloIF
  C. 将服务打包为WAR文件
  WEB-INF/classes/hello/HelloIF.class
  WEB-INF/classes/hello/HelloImpl.class
  WEB-INF/jaxrpc-ri.xml
  WEB-INF/model.gz
  WEB-INF/web.xml
  jaxrpc-ri.xml文件如下所述
  
  
version=”1.0”
targetNamespaceBase=”urn:Star”
typeNamespaceBase=”urn:Star”
urlPatternBase=”webservice”>  version=”1.0”
  targetNamespaceBase=”urn:Star”
  typeNamespaceBase=”urn:Star”
  urlPatternBase=”webservice”>
  
displayName=”HelloWorld Service”
description=”A simple web service”
interface=”helloservice.HelloIF”
model=”/WEB-INF/model.gz”
implementation=”helloservice.HelloImpl”/>  displayName=”HelloWorld Service”
  description=”A simple web service”
  interface=”helloservice.HelloIF”
  model=”/WEB-INF/model.gz”
  implementation=”helloservice.HelloImpl”/>
  
  
  D. 处理WAR文件
  使用命令行
  wsdeploy -o hello-jaxrpc.war hello-jaxrpc-original.war
  wsdeploy工具完成以下几个任务
  ·读 hello-jaxrpc-original.war作为输入
  ·从jaxrpc-ri.xml文件中获得信息
  ·为服务生成tie classes
  ·生成名为HelloService.wsdl的WSDL文件
  ·将tie classes和HelloService.wsdl文件打包到新的war文件中
  E. 在服务器上部署服务
  如果你使用的是TOMCAT,你可以将WAR文件拷贝到webapps目录下,然后可以在
   上看是否配置成功
  ·如何使用JAX-RPC创建Web Service客户端
  通常有三种类型的客户:Static Stub、Dynamic Proxy和Dynamic Invocation Interface(DII)
  Static Stub客户
  ·生成Stub
  通过使用config-wsdl.xml和wscompile工具,可以生成stub
  wscompile -gen:client -d build -classpath build config-wsdl.xml
  config-wsdl.xml文件如下
  
  
  
packageName="staticstub"/>  packageName="staticstub"/>
  
  wscompile工具读取服务器上的WSDL文件并生成stub
  ·编写静态客户代码
  Stub stub=(Stub)(new HelloService_Impl().getHelloIFPort());
  HelloIF hello=(HelloIF)stub;
  Hello.sayHello(“starchu”);
  注意:HelloService_Impl类由wscompile生成
  ·编译代码
  ·运行客户端(需要包含saaj API和JAX-RPC API运行)
  Dynamic Proxy客户
  ·生成接口
  通过使用config-wsdl.xml文件和wscompile工具,可以生成客户所需的接口
  wscompile -import -d build -classpath build config-wsdl.xml
  config-wsdl.xml和前面列出的文件内容相同。
  ·编写动态客户代码
  ServiceFactory factory=ServiceFactory.newInstance();
  URL wsdlUrl=new URL(“ ”);
  Service service=factory.createService(wsdlUrl,
  new QName(“urn:Star”,”HelloService”));
  HelloIF hello=(HelloIF)service.getPort(
  new QName(“urn:Star”,”HelloIFPort”),HelloIF.class);
  Hello.sayHello(“starchu”);
  注意:这里不再需要静态客户代码的HelloService_Impl类
  ·编译代码
  ·运行客户端(需要包含saaj API和JAX-RPC API运行)
  Dynamic Invocation Interface客户
  这个方法为我们提供了更有弹性的客户调用方式,客户代码不在需要由wscompile工具生成的运行时类,当然这种代码更加复杂。具体步骤如下:
  ·创建ServiceFactory实例
  ServiceFactory factory=ServiceFactory.newInstance();
  ·创建Service(利用服务名的Qname)
  Service service=factory.createService(new QName(“HelloService”));
  ·创建Call对象(使用端点接口的Qname)
  Call call=service.createCall(new QName(“HelloIF”));
  ·设置端点的地址和一些Call对象属性
  call.setTargetEndpointAddress(args[0]);
  call.setProperty(Call.SOAPACTION_USE_PROPERTY,new Boolean(true));
  call.setProperty(Call.SOAPACTION_URI_PROPERTY,””);
  call.setProperty(“javax.xml.rpc.encodingstyle.namespace.uri”,
  “http://schemas.xmlsoap.org/soap/encoding/”);
  ·设置远程调用的返回类型、操作名和参数
  QName stringType=new Qname(“http://www.w3.org/2001/XMLSchema”,”string”)
  call.setReturnType(stringType);
  call.setOperationName(new Qname(“urn:Star”,”sayHello”));
  call.addParameter(“String_1”,stringType,ParameterMode.IN);
  ·调用call的invoke方法
  String [] param={ “ starchu “ };
  String retValue=call.invoke(param);
  ·编译代码并对Main方法设置 )
  3.SOAP Message Handler的例子
  通常使用JAX-RPC建立的Web Service并不需要开发人员自己处理SOAP消息,但是JAX-RPC提供了一种机制可以使程序员获得这种处理能力,这就是所谓的消息处理器。总的来说,像日志和加解密功能可以通过SOAP消息处理器实现,除此之外,你根本不需要处理SOAP消息。
  ·基本Handler处理过程
  SOAP请求
  ·客户端处理器在请求消息发送到服务器前被调用
  ·服务端处理器在请求消息分发到端点前被调用
  SOAP应答
  ·服务端处理器在应答消息发送回客户前被调用
  ·客户端处理器在应答消息转换成Java方法返回前被调用
  SOAP错误
  处理过程与SOAP应答的方式一样
  注意:处理器可以在任意端组成处理器链
  A.Handler基本编程模型
  服务端
  ·编写服务端点接口代码、实现服务并且实现服务端处理器类
  ·创建jaxrpc-ri.xml文件,以便wscompile使用,其中包含了Handler的信息
  ·创建web.xml文件
  ·编译所有代码
  ·将文件打包为WAR文件
  ·用wsdeploy工具将原始war文件替换为完整可部署的war文件
  ·在服务器上部署war文件
  客户端
  ·编写客户程序以及客户端处理器代码
  ·创建config.xml文件以便wscompile使用,它包含了客户端处理器的信息
  ·编译代码
  ·运行wscompile生成服务端点接口和客户类
  ·编译所有代码,并运行客户应用
  B.建立客户端处理器
  处理器必须扩展javax.xml.rpc.handler.GenericHandler类并且提供至少两个方法的实现init和getHandlers。此外,你可以利用handleXXX方法处理请求、应答和错误SOAP消息。基本步骤如下
  ·编写客户端处理器代码
  Public class ClientHandler extends GenericHandler{
  Public void init(HandlerInfo info){
  This.info=info;
  }
  public QName[] getHeaders(){
  return info.getHeaders();
  }
  public boolean handleRequest(MessageContext context){
  SOAPMessageContext smc=(SOAPMessageContext)context;
  SOAPMessage message=smc.getMessage();
  file://You can use SOAP API to implement your own logic
  file://such as logging and encrypt
  ……
  file://Set a logger element in the SOAPHeader
  SOAPHeaderElement loggerElement=
  header.addHeaderElement(envelope.createName(“loginfo”,
  “ns1”,”urn:Star:headprops”));
  loggerElement.setMustUnderstand(true);
  loggerElement.setValue(“10”);
  file://Set a name element in the SOAP Header
  SOAPHeaderElement nameElement=
  Header.addHeaderElement(envelope.createName(“client”,
  “ns1”,”urn:Star:headprops”));
  nameElement.addTextNode(“Star chu”);
  }
  }
  ·编辑config.xml文件
  
  
  
packageName=”client”>  packageName=”client”>
  
  
  
  
  
  
  
  ·编写静态客户
  C.建立服务端处理器
  ·编写服务端处理器(与客户端结构类似)
  Public boolean handleRequest(MessageContext context){
  SOAPMessageContext smc=(SOAPMessageContext)context;
  ……
  Iterator it=header.examineAllHeaderElements();
  While(it.hasNext()){
  SOAPElement element=(SOAPElement)it.next();
  If(element name is loginfo and must understand it){
  element.getValue();
  element.detach();
  file://Invoke only when the setMustUnderstand(true)
  }
  }
  }
  detach方法用来移除元素,这个需求仅当一个元素设置了mustUnderstand属性在必要。
  ·编辑jaxrpc-ri.xml文件
  
  
version=”1.0”
targetNamespaceBase=”urn:Star:wsdl”
typeNamespaceBase=”urn:Star:types”
urlPatternBase=”/handler”>  version=”1.0”
  targetNamespaceBase=”urn:Star:wsdl”
  typeNamespaceBase=”urn:Star:types”
  urlPatternBase=”/handler”>
  
displayName=”Handler Test”
description=” … …”
interface=”service.HandlerTest”
model=”/WEB-INF/model.gz”
implementation=”service.HandlerTestImpl”>  displayName=”Handler Test”
  description=” … …”
  interface=”service.HandlerTest”
  model=”/WEB-INF/model.gz”
  implementation=”service.HandlerTestImpl”>
  
  
  
headers=”ns1:loginfo”
xmlns:ns1=”urn:Star:headerprops”>  headers=”ns1:loginfo”
  xmlns:ns1=”urn:Star:headerprops”>
  
  
  
  
  
  
  
  
  
urlPattern=”/handler”/>  urlPattern=”/handler”/>
  
  在第一个处理器中,XML使用了属性 headers描述头信息。这是因为客户代码告诉服务端,logger头必须被理解,否则客户将收到SOAP错误消息
  ·生成WAR文件并部署到服务器上
  4.源代码
  ·HelloIF.java(endpoint接口)
  package helloservice;
  import java.rmi.RemoteException;
  import java.rmi.Remote;
  public interface HelloIF extends Remote{
  public String sayHello(String target) throws RemoteException;
  }
  ·HelloImpl.java
  package helloservice;
  public class HelloImpl implements HelloIF{
  private String message="Hello";
  public String sayHello(String target){
  return message+target;
  }
  }
  ·StaticClient.java
  package staticstub;
  import javax.xml.rpc.Stub;
  public class StaticClient{
  private static String endpointAddress;
  public static void main(String [] args){
  if(args.length!=1){
  System.err.println("Usage : java HelloClient [endpoint address]");
  System.exit(-1);
  }
  endpointAddress=args[0];
  System.out.println("Connect to :"+endpointAddress);
  try{
  Stub stub=createStub();
  stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
  endpointAddress);
  HelloIF hello=(HelloIF)stub;
  System.out.println(hello.sayHello(" Starchu!"));
  }catch(Exception e){System.err.println(e.toString());}
  }
  private static Stub createStub(){
  return (Stub)(new HelloService_Impl().getHelloIFPort());
  }
  }
  ·DynamicClient.java
  package dynamicproxy;
  import java.net.URL;
  import javax.xml.namespace.QName;
  import javax.xml.rpc.Service;
  import javax.xml.rpc.ServiceFactory;
  import javax.xml.rpc.JAXRPCException;
  import staticstub.HelloIF;
  public class DynamicClient{
  private static String wsdl;
  private static String namespaceUri="urn:Star:wsdl";
  private static String serviceName="HandlerService";
  private static String portName="HandlerTestPort";
  public static void main(String [] args){
  if(args.length!=1){
  System.err.println("Usage : java DynamicClient [server Url]");
  System.exit(-1);
  }
  System.out.println("Connect to :"+args[0]);
  helloWsdl=args[0]+"?WSDL";
  try{
  URL wsdlUrl=new URL(wsdl);
  ServiceFactory serviceFactory=ServiceFactory.newInstance();
  Service service=
  serviceFactory.createService(wsdlUrl,
  new QName(namespaceUri,serviceName));
  HandlerTest proxy=(HandlerTest)service.getPort(
  new QName(namespaceUri,portName),HandlerTest.class);
  proxy.test();
  }catch(Exception e){
  System.err.println(e.toString());
  }
  }
  }
  ·DIIClient.java
  package dii;
  import javax.xml.rpc.*;
  import javax.xml.namespace.*;
  public class DIIClient{
  private static String qnameService = "HelloService";
  private static String qnamePort = "HelloIF";
  private static String BODY_NAMESPACE_VALUE ="urn:Star";
  private static String ENCODING_STYLE_PROPERTY ="javax.xml.rpc.encodingstyle.namespace.uri";
  private static String NS_XSD ="http://www.w3.org/2001/XMLSchema";
  private static String URI_ENCODING ="http://schemas.xmlsoap.org/soap/encoding/";
  public static void main(String [] args){
  try{
  
  ServiceFactory factory=ServiceFactory.newInstance();
  Service service=factory.createService(new QName(qnameService));
  QName port=new QName(qnamePort);
  Call call=service.createCall(port);
  call.setTargetEndpointAddress(args[0]);
  call.setProperty(Call.SOAPACTION_USE_PROPERTY,new Boolean(true));
  call.setProperty(Call.SOAPACTION_URI_PROPERTY,"");
  call.setProperty(ENCODING_STYLE_PROPERTY,URI_ENCODING);
  QName qnameTypeString=new QName(NS_XSD,"string");
  call.setReturnType(qnameTypeString);
  call.setOperationName(new QName(BODY_NAMESPACE_VALUE,"sayHello"));
  call.addParameter("String_1",qnameTypeString,ParameterMode.IN);
  String [] params = { "Starchu" };
  System.out.println((String)call.invoke(params));
  }catch(Exception e){
  System.err.println(e.toString());
  }
  }
  }
  ·Ant文件build.xml
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  
  
  
  
  
  
  
  
  
  
  
  
  
webxml="${build}/web.xml">  webxml="${build}/web.xml">
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
classpathref="classpath"
fork="true">  classpathref="classpath"
  fork="true">
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
classpathref="classpath"
fork="true">  classpathref="classpath"
  fork="true">
  
  
  
  
  
  
  
  
  
  
  
  
classpathref="classpath"
fork="true">  classpathref="classpath"
  fork="true">
  
  
  
  
  
  ·属性文件(build.xml文件使用)
  server=C:/Java/jwsdp-1.2/webapps
  tomcat.home=C:/Java/jwsdp-1.2
  endpoint=http://localhost:8080/helloWS/hello
  server.port.url=http://localhost:8080/helloWS/hello
  参考资料
  1. Developing Web Service Series www.theserverside.com
  2. JWSDP-1.2 Tutorial java.sun.com
  
  导读本文是我对学习jwsdp-1.2时所做笔记的整理,其中主要是一些指导性的内容,并没有多少概念以及原理的介绍,读者可能觉得略显简单,如果想要学习基本概念可以参考网上有关Web Service的资料。本文例子所使用的开发环境是WindowXP+JWSDP-1.2。一.Web Service简介1.定义 由两部分组成 ·SOAP--Web Service之间的基本通信协议。 ·WSDL--Web Service描述语言,它定义了Web Service做什么,怎么做和查询的信息。2.简单的Web Service实现 包含四个基本步骤 ·创建Web Service的商业逻辑(通常是一些Java类) ·将这些Java类部署到一个SOAP服务器上 ·生成客户访问代码 ·部署客户应用 注意:WSDL等文件的生成通常是利用厂商提供的工具来完成3.WSDL解析 WSDL描述语言一般包含三部分 ·What部分--包括了type、message和portType元素 Type:定义了Web Service使用的数据结构(使用XML Schema定义) Message:一个Message是SOAP的基本通信元素。每个Message可以有一个或多个Part,每个Part代表一个参数。 PortType:消息汇总为不同的操作并归入到一个被称为portType的实体中。一个portType代表一个接口(Web Service支 持的操作集合),每个Web Service可以有多个接口,它们都使用portType表示。每个操作又包含了input和 output部分。 ·How部分--包含binding元素 binding元素将portType绑定到特定的通信协议上(如HTTP上的SOAP协议) ·Where部分--由service元素组成 它将portType,binding以及Web Service实际的位置(URI)放在一起描述4.客户端 通常Web Service可以有三种类型的客户 ·商业伙伴(Business Partner)--包括分发商,零售商以及大型消费者) 此类客户通过SOAP、WSDL、ebXML、UDDI等XML技术与Web Service连接 ·瘦客户--包括Web浏览器、PDA以及无线设备 该类客户通常经由轻量协议(如HTTP)与Web Service连接 ·肥客户--包括Applet、各类应用以及现存系统 通常使用重量级协议(如IIOP)连接Web Service二.使用JAX-RPC开发Web Service1.JAX-RPC支持的数据类型 JAX-RPC除了支持Java的基本数据类型外还支持一些自定义对象,但这些对象有一些条件限制·有缺省构造函数的对象·没有实现java.rmi.Remote接口·字段必须是JAX-RPC支持的类型·公有字段不能声明为final或transient·非公有字段必须有对应的setter和getter方法2.使用JAX-RPC创建Web Service·基本步骤 A. 编写服务端接口并实现一个服务的end-point有一些规定:必须实现java.rmi.Remot接口而且每个方法需要抛出RemoteException异常。 B. 编译、生成并且将所有服务需要的类和文件打包成WAR文件 C. 部署包含服务的WAR文件·如何创建服务 A. 编译服务所需的类文件 B. 生成服务所需文件可以使用wscompile工具生成model.gz文件,它包含了描述服务的内部数据结构命令如下 wscompile -define -d build -nd build -classpath build config.xml -model build/model.gz define标志告诉工具读取服务的 endpoint接口并且创建WSDL文件。-d和-nd标志告诉工具将输出文件写入指定的目录build。工具需要读以下的config.xml文件 < configuration xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/config”>< service name=”HelloService” targetNamespace=”urn:Star” typeNamespace=”urn:Star” packageName=”helloservice”>< interface name=”helloservice.HelloIF”/>该文件告诉wscompile创建model文件所需的信息 ·服务名称:MyHelloService ·WSDL名字空间:urn:Star ·HelloService的所有类在包helloservice中 ·服务的端点(endpoint)接口:helloservice.HelloIF C. 将服务打包为WAR文件 WEB-INF/classes/hello/HelloIF.class WEB-INF/classes/hello/HelloImpl.class WEB-INF/jaxrpc-ri.xml WEB-INF/model.gz WEB-INF/web.xml jaxrpc-ri.xml文件如下所述 < webServices xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/dd” version=”1.0” targetNamespaceBase=”urn:Star” typeNamespaceBase=”urn:Star” urlPatternBase=”webservice”>< endpoint name=”Hello” displayName=”HelloWorld Service” description=”A simple web service” interface=”helloservice.HelloIF” model=”/WEB-INF/model.gz” implementation=”helloservice.HelloImpl”/>< endpointMapping endpointName=”Hello” urlPattern=”/hello”/> D. 处理WAR文件使用命令行 wsdeploy -o hello-jaxrpc.war hello-jaxrpc-original.war wsdeploy工具完成以下几个任务 ·读 hello-jaxrpc-original.war作为输入 ·从jaxrpc-ri.xml文件中获得信息 ·为服务生成tie classes ·生成名为HelloService.wsdl的WSDL文件 ·将tie classes和HelloService.wsdl文件打包到新的war文件中 E. 在服务器上部署服务如果你使用的是TOMCAT,你可以将WAR文件拷贝到webapps目录下,然后可以在< http://localhost:8080/[context]/[servicename>上看是否配置成功·如何使用JAX-RPC创建Web Service客户端 通常有三种类型的客户:Static Stub、Dynamic Proxy和Dynamic Invocation Interface(DII) Static Stub客户·生成Stub通过使用config-wsdl.xml和wscompile工具,可以生成stub wscompile -gen:client -d build -classpath build config-wsdl.xml config-wsdl.xml文件如下 < configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">< wsdl location="http://localhost:8080/helloWS/hello?WSDL" packageName="staticstub"/> wscompile工具读取服务器上的WSDL文件并生成stub·编写静态客户代码 Stub stub=(Stub)(new HelloService_Impl().getHelloIFPort()); HelloIF hello=(HelloIF)stub; Hello.sayHello(“starchu”);注意:HelloService_Impl类由wscompile生成 ·编译代码·运行客户端(需要包含saaj API和JAX-RPC API运行) Dynamic Proxy客户·生成接口通过使用config-wsdl.xml文件和wscompile工具,可以生成客户所需的接口 wscompile -import -d build -classpath build config-wsdl.xml config-wsdl.xml和前面列出的文件内容相同。·编写动态客户代码 ServiceFactory factory=ServiceFactory.newInstance(); URL wsdlUrl=new URL(“ ”); Service service=factory.createService(wsdlUrl, new QName(“urn:Star”,”HelloService”)); HelloIF hello=(HelloIF)service.getPort( new QName(“urn:Star”,”HelloIFPort”),HelloIF.class); Hello.sayHello(“starchu”); 注意:这里不再需要静态客户代码的HelloService_Impl类 ·编译代码·运行客户端(需要包含saaj API和JAX-RPC API运行) Dynamic Invocation Interface客户这个方法为我们提供了更有弹性的客户调用方式,客户代码不在需要由wscompile工具生成的运行时类,当然这种代码更加复杂。具体步骤如下:·创建ServiceFactory实例 ServiceFactory factory=ServiceFactory.newInstance();·创建Service(利用服务名的Qname) Service service=factory.createService(new QName(“HelloService”));·创建Call对象(使用端点接口的Qname) Call call=service.createCall(new QName(“HelloIF”));·设置端点的地址和一些Call对象属性 call.setTargetEndpointAddress(args[0]); call.setProperty(Call.SOAPACTION_USE_PROPERTY,new Boolean(true)); call.setProperty(Call.SOAPACTION_URI_PROPERTY,””); call.setProperty(“javax.xml.rpc.encodingstyle.namespace.uri”, “http://schemas.xmlsoap.org/soap/encoding/”);·设置远程调用的返回类型、操作名和参数 QName stringType=new Qname(“http://www.w3.org/2001/XMLSchema”,”string”) call.setReturnType(stringType); call.setOperationName(new Qname(“urn:Star”,”sayHello”)); call.addParameter(“String_1”,stringType,ParameterMode.IN);·调用call的invoke方法 String [] param={ “ starchu “ }; String retValue=call.invoke(param);·编译代码并对Main方法设置 )3.SOAP Message Handler的例子通常使用JAX-RPC建立的Web Service并不需要开发人员自己处理SOAP消息,但是JAX-RPC提供了一种机制可以使程序员获得这种处理能力,这就是所谓的消息处理器。总的来说,像日志和加解密功能可以通过SOAP消息处理器实现,除此之外,你根本不需要处理SOAP消息。·基本Handler处理过程 SOAP请求 ·客户端处理器在请求消息发送到服务器前被调用 ·服务端处理器在请求消息分发到端点前被调用 SOAP应答 ·服务端处理器在应答消息发送回客户前被调用 ·客户端处理器在应答消息转换成Java方法返回前被调用 SOAP错误 处理过程与SOAP应答的方式一样注意:处理器可以在任意端组成处理器链 A.Handler基本编程模型 服务端 ·编写服务端点接口代码、实现服务并且实现服务端处理器类 ·创建jaxrpc-ri.xml文件,以便wscompile使用,其中包含了Handler的信息 ·创建web.xml文件 ·编译所有代码 ·将文件打包为WAR文件 ·用wsdeploy工具将原始war文件替换为完整可部署的war文件 ·在服务器上部署war文件 客户端 ·编写客户程序以及客户端处理器代码 ·创建config.xml文件以便wscompile使用,它包含了客户端处理器的信息 ·编译代码 ·运行wscompile生成服务端点接口和客户类 ·编译所有代码,并运行客户应用 B.建立客户端处理器处理器必须扩展javax.xml.rpc.handler.GenericHandler类并且提供至少两个方法的实现init和getHandlers。此外,你可以利用handleXXX方法处理请求、应答和错误SOAP消息。基本步骤如下 ·编写客户端处理器代码 Public class ClientHandler extends GenericHandler{ Public void init(HandlerInfo info){ This.info=info; } public QName[] getHeaders(){ return info.getHeaders(); } public boolean handleRequest(MessageContext context){ SOAPMessageContext smc=(SOAPMessageContext)context; SOAPMessage message=smc.getMessage(); file://You can use SOAP API to implement your own logic file://such as logging and encrypt …… file://Set a logger element in the SOAPHeader SOAPHeaderElement loggerElement= header.addHeaderElement(envelope.createName(“loginfo”, “ns1”,”urn:Star:headprops”)); loggerElement.setMustUnderstand(true); loggerElement.setValue(“10”); file://Set a name element in the SOAP Header SOAPHeaderElement nameElement= Header.addHeaderElement(envelope.createName(“client”, “ns1”,”urn:Star:headprops”)); nameElement.addTextNode(“Star chu”); } } ·编辑config.xml文件 < configuration xmlns=”http://java.sun.com/xml/ns/jax-rpc/ri/config”?> < wsdl location=”http://localhost:8080/handlerWS/handler?WSDL packageName=”client”> < handlerChains> < chain runAt=”client”> < handler className=”client.ClientHandler”> < property name=”name” value=”client handler”/> ·编写静态客户 C.建立服务端处理器 ·编写服务端处理器(与客户端结构类似) Public boolean handleRequest(MessageContext context){ SOAPMessageContext smc=(SOAPMessageContext)context; …… Iterator it=header.examineAllHeaderElements(); While(it.hasNext()){ SOAPElement element=(SOAPElement)it.next(); If(element name is loginfo and must understand it){ element.getValue(); element.detach(); file://Invoke only when the setMustUnderstand(true) } } } detach方法用来移除元素,这个需求仅当一个元素设置了mustUnderstand属性在必要。 ·编辑jaxrpc-ri.xml文件 < webServices xmlns=”http://java.sun.com/jax-rpc/config/ri/dd” version=”1.0” targetNamespaceBase=”urn:Star:wsdl” typeNamespaceBase=”urn:Star:types” urlPatternBase=”/handler”> < endpoint name=”HandlerTest” displayName=”Handler Test” description=” … …” interface=”service.HandlerTest” model=”/WEB-INF/model.gz” implementation=”service.HandlerTestImpl”> < handlerChains> < chain runAt=”server”> < handler className=”service.LoggerHandler” headers=”ns1:loginfo” xmlns:ns1=”urn:Star:headerprops”>< property name=”name” value=”Logger”/> < handler className=”service.NameHandler”> < propery name=”name” value=”Name”/> < endpointMapping endpointName=”HandlerTest” urlPattern=”/handler”/> 在第一个处理器中,XML使用了属性 headers描述头信息。这是因为客户代码告诉服务端,logger头必须被理解,否则客户将收到SOAP错误消息·生成WAR文件并部署到服务器上4.源代码·HelloIF.java(endpoint接口) package helloservice; import java.rmi.RemoteException; import java.rmi.Remote; public interface HelloIF extends Remote{ public String sayHello(String target) throws RemoteException;}·HelloImpl.java package helloservice; public class HelloImpl implements HelloIF{ private String message="Hello"; public String sayHello(String target){ return message+target; }}·StaticClient.java package staticstub; import javax.xml.rpc.Stub; public class StaticClient{ private static String endpointAddress; public static void main(String [] args){ if(args.length!=1){ System.err.println("Usage : java HelloClient [endpoint address]"); System.exit(-1); } endpointAddress=args[0]; System.out.println("Connect to :"+endpointAddress); try{ Stub stub=createStub(); stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, endpointAddress); HelloIF hello=(HelloIF)stub; System.out.println(hello.sayHello(" Starchu!")); }catch(Exception e){System.err.println(e.toString());} } private static Stub createStub(){ return (Stub)(new HelloService_Impl().getHelloIFPort()); }} ·DynamicClient.java package dynamicproxy; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; import javax.xml.rpc.JAXRPCException; import staticstub.HelloIF; public class DynamicClient{ private static String wsdl; private static String namespaceUri="urn:Star:wsdl"; private static String serviceName="HandlerService"; private static String portName="HandlerTestPort"; public static void main(String [] args){ if(args.length!=1){ System.err.println("Usage : java DynamicClient [server Url]"); System.exit(-1); } System.out.println("Connect to :"+args[0]); helloWsdl=args[0]+"?WSDL"; try{ URL wsdlUrl=new URL(wsdl); ServiceFactory serviceFactory=ServiceFactory.newInstance(); Service service= serviceFactory.createService(wsdlUrl, new QName(namespaceUri,serviceName)); HandlerTest proxy=(HandlerTest)service.getPort( new QName(namespaceUri,portName),HandlerTest.class); proxy.test(); }catch(Exception e){ System.err.println(e.toString()); } }} ·DIIClient.java package dii; import javax.xml.rpc.*; import javax.xml.namespace.*; public class DIIClient{ private static String qnameService = "HelloService"; private static String qnamePort = "HelloIF"; private static String BODY_NAMESPACE_VALUE ="urn:Star"; private static String ENCODING_STYLE_PROPERTY ="javax.xml.rpc.encodingstyle.namespace.uri"; private static String NS_XSD ="http://www.w3.org/2001/XMLSchema"; private static String URI_ENCODING ="http://schemas.xmlsoap.org/soap/encoding/"; public static void main(String [] args){ try{ ServiceFactory factory=ServiceFactory.newInstance(); Service service=factory.createService(new QName(qnameService)); QName port=new QName(qnamePort); Call call=service.createCall(port); call.setTargetEndpointAddress(args[0]); call.setProperty(Call.SOAPACTION_USE_PROPERTY,new Boolean(true)); call.setProperty(Call.SOAPACTION_URI_PROPERTY,""); call.setProperty(ENCODING_STYLE_PROPERTY,URI_ENCODING); QName qnameTypeString=new QName(NS_XSD,"string"); call.setReturnType(qnameTypeString); call.setOperationName(new QName(BODY_NAMESPACE_VALUE,"sayHello")); call.addParameter("String_1",qnameTypeString,ParameterMode.IN); String [] params = { "Starchu" }; System.out.println((String)call.invoke(params)); }catch(Exception e){ System.err.println(e.toString()); } }} ·Ant文件build.xml< project name="helloWS" basedir="." default="deploy"> < property file="build.properties"/> < property name="build" value="build"/> < property name="dist" value="${build}/classes"/> < property name="lib" value="${build}/lib"/> < property name="src" value="src"/> < property name="etc" value="${src}/etc"/> < target name="clean"> < delete dir="${build}"/> < target name="init"> < mkdir dir="${build}"/> < mkdir dir="${dist}"/> < mkdir dir="${lib}"/> < path id="classpath"> < fileset dir="${tomcat.home}"> < include name="jaxrpc/**/*.jar"/> < include name="jaxb/**/*.jar"/> < include name="jaxp/**/*.jar"/> < include name="saaj/**/*.jar"/> < include name="jwsdp-shared/lib/**/*.jar"/> < pathelement path="${dist}"/> < pathelement location="${lib}"/> < target name="compile-service" depends="init">< javac srcdir="${src}" destdir="${dist}" includes="HelloService/**/*.java"/> < target name="generate-sei-service" depends="compile-service"> < exec executable="wscompile.bat"> < arg line="-define -d ${build} -nd ${build} -classpath ${dist} ${etc}/config-interface.xml -model ${build}/model.gz"/> < copy todir="${build}"> < fileset dir="${etc}" includes="*.xml"/> < target name="package-service" depends="generate-sei-service"> < war warfile="${build}/${ant.project.name}-portable.war" webxml="${build}/web.xml"> < webinf dir="${build}" includes="*.xml,*.gz,*.wsdl" excludes="web.xml"/>< classes dir="${dist}" includes="**/*.class" defaultexcludes="no"/> < target name="process-war" depends="package-service"> < exec executable="wsdeploy.bat">< arg line="-o ${ant.project.name}.war ${build}/${ant.project.name}-portable.war"/> < target name="deploy"> < copy file="${ant.project.name}.war" todir="${server}"/> < target name="undeploy"> < delete file="${server}/${ant.project.name}.war"/> < target name="generate-stubs" depends="init"> < exec executable="wscompile.bat">< arg line="-gen:client -d ${dist} -classpath ${dist} ${etc}/config-wsdl.xml"/> < target name="compile-client" depends="generate-stubs"> < javac srcdir="${src}" destdir="${dist}" includes="StaticStub/**/*.java"> < classpath refid="classpath"/> < target name="package-client" depends="compile-client">< jar destfile="${lib}/client.jar" basedir="${dist}" excludes="HelloService/**/*.class"/> < target name="run-client" depends="package-client"> < java classname="staticstub.HelloClient" classpathref="classpath" fork="true"> < sysproperty key="endpoint" value="${endpoint}"/> < arg value="${server.port.url}"/> < target name="generate-interface" depends="init"> < exec executable="wscompile.bat"> < arg line="-import -d ${dist} -classpath ${dist} ${etc}/config-wsdl.xml"/> < target name="compile-dynamic-client" depends="generate-interface">< javac srcdir="${src}" destdir="${dist}" includes="DynamicProxy/**/*.java"> < classpath refid="classpath"/> < target name="package-dynamic-client" depends="compile-dynamic-client">< jar destfile="${lib}/client.jar" basedir="${dist}" includes="**/HelloIF.class,**/DynamicClient.class"/> < target name="run-dynamic-client" depends="package-dynamic-client"> < java classname="dynamicproxy.DynamicClient" classpathref="classpath" fork="true"> < sysproperty key="endpoint" value="${endpoint}"/> < arg value="${server.port.url}"/> < target name="compile-dii"> < javac srcdir="${src}" destdir="${dist}" includes="DII/**/*.java"> < classpath refid="classpath"/> < target name="run-dii" depends="compile-dii"> < java classname="dii.DIIClient" classpathref="classpath" fork="true"> < sysproperty key="endpoint" value="${endpoint}"/> < arg value="${server.port.url}"/> ·属性文件(build.xml文件使用) server=C:/Java/jwsdp-1.2/webapps tomcat.home=C:/Java/jwsdp-1.2 endpoint=http://localhost:8080/helloWS/hello server.port.url=http://localhost:8080/helloWS/hello参考资料1. Developing Web Service Series www.theserverside.com2. JWSDP-1.2 Tutorial java.sun.com

本文转自
http://www.cn-java.com/www1/?action-viewnews-itemid-2727
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 无锡平芯微半导体科技有限公司生产的A1SHB三极管(全称PW2301A)是一款P沟道增强型MOSFET,具备低内阻、高重复雪崩耐受能力以及高效电源切换设计等优势。其技术规格如下:最大漏源电压(VDS)为-20V,最大连续漏极电流(ID)为-3A,可在此条件下稳定工作;栅源电压(VGS)最大值为±12V,能承受正反向电压;脉冲漏极电流(IDM)可达-10A,适合处理短暂高电流脉冲;最大功率耗散(PD)为1W,可防止器件过热。A1SHB采用3引脚SOT23-3封装,小型化设计利于空间受限的应用场景。热特性方面,结到环境的热阻(RθJA)为125℃/W,即每增加1W功率损耗,结温上升125℃,提示设计电路时需考虑散热。 A1SHB的电气性能出色,开关特性优异。开关测试电路及波形图(图1、图2)展示了不同条件下的开关性能,包括开关上升时间(tr)、下降时间(tf)、开启时间(ton)和关闭时间(toff),这些参数对评估MOSFET在高频开关应用中的效率至关重要。图4呈现了漏极电流(ID)与漏源电压(VDS)的关系,图5描绘了输出特性曲线,反映不同栅源电压下漏极电流的变化。图6至图10进一步揭示性能特征:转移特性(图7)显示栅极电压(Vgs)对漏极电流的影响;漏源开态电阻(RDS(ON))随Vgs变化的曲线(图8、图9)展现不同控制电压下的阻抗;图10可能涉及电容特性,对开关操作的响应速度和稳定性有重要影响。 A1SHB三极管(PW2301A)是高性能P沟道MOSFET,适用于低内阻、高效率电源切换及其他多种应用。用户在设计电路时,需充分考虑其电气参数、封装尺寸及热管理,以确保器件的可靠性和长期稳定性。无锡平芯微半导体科技有限公司提供的技术支持和代理商服务,可为用户在产品选型和应用过程中提供有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值