160 likes | 344 Views
J2EE —— 第 8 章 利用 JAX-RPC 构建 Web 服务. 什么是 JAX-RPC. Java API for XML-based RPC SOAP: Simple Object Access Protocol 信封结构 编码规则 远程过程调用和响应的转换 JAX-RPC 隐藏了 SOAP 的复杂性 平台独立性: Java 灵活性: HTTP, SOAP, WSDL. JAX-RPC Web 服务和客户端之间的通信. 创建 Web 服务和客户端的基本步骤. 编写 SEI 和实现类以及接口配置文件的代码 编译 SEI 和实现类
E N D
什么是JAX-RPC • Java API for XML-based RPC • SOAP: Simple Object Access Protocol • 信封结构 • 编码规则 • 远程过程调用和响应的转换 • JAX-RPC隐藏了SOAP的复杂性 • 平台独立性:Java • 灵活性:HTTP, SOAP, WSDL
创建Web服务和客户端的基本步骤 • 编写SEI和实现类以及接口配置文件的代码 • 编译SEI和实现类 • 使用wscompile生成所需的文件,以部署服务 • 使用deploytool将文件打包为WAR文件 • 部署WAR文件,生成tie • 编写客户端类和WSDL配置文件的代码 • 使用wscompile生成和编译stub • 编译客户端类 • 运行客户端
编码服务端点接口和实现类 package helloservice; import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloIF extends Remote { public String sayHello(String s) throws RemoteException; } public class HelloImpl implements HelloIF { public String message ="Hello"; public String sayHello(String s) { return message + s; } }
构建服务 wscompile -define -mapping build/mapping.xml -d build -nd build -classpath build config-interface.xml • 根据class文件和config-interface.xml生成MyHelloService.wsdl和mapping.xml <?xml version="1.0" encoding="UTF-8"?> <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <service name="MyHelloService" targetNamespace="urn:Foo" typeNamespace="urn:Foo" packageName="helloservice"> <interface name="helloservice.HelloIF"/> </service> </configuration>
打包服务 • deploytool的New Web Component • 输入build目录,WSDL,mapping,HelloIF,HelloImpl • 创建Web程序部署描述符,打包WAR文件 • 指定端点地址 http://localhost:8080/hello-jaxrpc/hello • 部署服务 http://localhost:8080/hello-jaxrpc/hello?WSDL
静态存根客户端 import javax.xml.rpc.Stub; public class HelloClient { public static void main(String[] args) { try { Stub stub = createProxy(); stub.setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]); HelloIF hello = (HelloIF)stub; System.out.println(hello.sayHello("Duke!")); } catch (Exception ex) { ex.printStackTrace(); } } private static Stub createProxy() { return (Stub) (new MyHelloService_Impl().getHelloIFPort()); } }
编译并运行静态存根客户端 • generate-stubs wscompile -gen:client -d build -classpath build config-wsdl.xml <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location="http://localhost:8080/hello-jaxrpc/hello?WSDL" packageName="staticstub"/> </configuration> • compile-client • package-client
JAX-RPC支持的类型 • Boolean Byte Double Float Integer Long Short String BigDecimal BigInteger URI Calendar Date • boolean byte double float int long short • []数组 • 值类型:可以在客户端和远程服务间作为参数和返回值传递的类 • 必须有一个公有的默认构造函数 • 必须没有实现java.rmi.Remote接口 • 字段必须得到JAX-RPC类型的支持 • 公有字段不能为final或transient • 非公有字段必须具备相应的getter和setter方法
动态代理客户端 public class HelloClient { public static void main(String[] args) { try { String UrlString = args[0] + "?WSDL"; String nameSpaceUri = "urn:Foo"; String serviceName = "MyHelloService"; String portName = "HelloIFPort"; URL helloWsdlUrl = new URL(UrlString); ServiceFactory serviceFactory = ServiceFactory.newInstance(); Service helloService = serviceFactory.createService(helloWsdlUrl, new QName(nameSpaceUri, serviceName)); dynamicproxy.HelloIF myProxy = (dynamicproxy.HelloIF) helloService.getPort(new QName(nameSpaceUri, portName), dynamicproxy.HelloIF.class); System.out.println(myProxy.sayHello("Buzz")); }
编译并运行动态代理客户端 • generate-interface • 读取MyHelloSercie.wsdl • 生成服务端点接口类HelloIF.class • compile-client • package-dynamic
动态调用接口客户端 public class HelloClient { private static String qnameService = "MyHelloService"; private static String qnamePort = "HelloIF"; private static String BODY_NAMESPACE_VALUE = "urn:Foo"; 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) {
动态调用接口客户端 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 QNAME_TYPE_STRING = new QName(NS_XSD, "string"); call.setReturnType(QNAME_TYPE_STRING); call.setOperationName( new QName(BODY_NAMESPACE_VALUE,"sayHello")); call.addParameter("String_1", QNAME_TYPE_STRING, ParameterMode.IN); String[] params = { "Murph!" }; String result = (String)call.invoke(params); System.out.println(result);
应用程序客户端 Context ic = new InitialContext(); MyHelloService myHelloService = (MyHelloService) ic.lookup("java:comp/env/service/MyJAXRPCHello"); appclient.HelloIF helloPort = myHelloService.getHelloIFPort(); ((Stub)helloPort)._setProperty (Stub.ENDPOINT_ADDRESS_PROPERTY,args[0]); System.out.println(helloPort.sayHello("Jake!"));
编译、打包、部署、运行 • generate-stubs • deploytool • 运行 appclient –client HelloServiceAppClient.jar http://localhost:8080/hello-jaxrpc/hello