java xml-remote procedure call
远程过程调用
jax-rpc
---------------------------------------
axis WebService
只需要拿到wsdl的URL地址就可以调用远程WebService
Jws(立即发布)
//使用这种方法发布WebService ,则只有在访问时才会动态生成wsdl。由于没有注册,所以这种方式不会显示在WebService列表中
首先写服务器端方法 建立一个Hello.jws 内容如下:
public class Hello{
public String axis(String message){
return "it's "+message;
}
}
client端调用远程方法步骤
第一种方法:基于代理的方法调用
必须要提供一个VM参数给ServiceFactory
手工配置-Djavax.xml.rpc.ServiceFactory=org.apache.axis.client.ServiceFactory
或者使用程序代码配置 System.setProperty(ServiceFactory.SERVICEFACTORY_PROPERTY, "org.apache.axis.client.ServiceFactory");
首先要根据提供的WSDL的URL参数,创建一个service 对象实例。
建立一个和wsdl中提供的方法一一对应的代理接口(必须为接口,不能是类),这个接口要继承自java.rmi.Remote接口。
通过service对象返回一个实现了此接口的代理对象。
使用代理对象访问service远程方法
example:
//javax.xml.rpc.ServiceFactory
//需要配置虚拟机参数 可以手工配置-Djavax.xml.rpc.ServiceFactory=org.apache.axis.client.ServiceFactory 或者通过System.setProperty()
System.setProperty(ServiceFactory.SERVICEFACTORY_PROPERTY, "org.apache.axis.client.ServiceFactory");
//生成service工厂
ServiceFactory sf=ServiceFactory.newInstance()
//通过ServiceFactory创建一个service实例,需要提供wsdl的URL,QName. Qname需要的两个参数分别是xml的targetNamespace 和 这个service的短名称
Service service= sf.createService(new URL("http://localhost:8080/axis/Hello.jws?wsdl"),new QName("http://localhost:8080/axis/Hello.jws%22,%22HelloService"));
//通过service实例获取一个代理对象,QName的第二个参数为xml中portType 的name值
remoteInteface rie=(remoteInteface) service.getPort(new QName("http://localhost:8080/axis/Hello.jws%22,%22Hello%22),remoteInteface.class);
System.out.println(rie.axis("kkkkkk"));
-----------------
第二种反射的方法调用(更灵活)
这种方式比较灵活,所要调用的方法名是通过参数进行传递的。
ServiceFactory sf=ServiceFactory.newInstance();
Service service= sf.createService(new URL("http://localhost:8080/axis/Hello.jws?wsdl"),new QName("http://localhost:8080/axis/Hello.jws%22,%22HelloService"));
//上面两步和第一种方式相同
//使用service对象创建一个javax.xml.rpc.Call 的实例对象
Call call=service.createCall(new QName("http://localhost:8080/axis/Hello.jws%22,%22Hello"));
//通过Call.invoke() 远程调用方法,
Object resultObj=call.invoke(new QName("http://localhost:8080/axis/Hello.jws%22,%22axis%22),new Object[]{"secondServiceDII call welcome"});
System.out.println(resultObj);
第三种方法调用方式
通过WSDL2Java这一工具类根据所传的wsdl的uri生成java
运行 org.apache.axis.wsdl.gen.WSDL2Java 这个class文件需要配置参数
格式 java org.apache.axis.wsdl.WSDL2Java [options] WSDL-URI
如果使用Eclipse运行则非常简便 只需要配置参数运行即可
example:
-p cn.itcast.stub http://localhost:8080/axis/Hello.jws?wsdl
这样运行后 生成的java文件会添加到当前工程的目录下,不过由于没有在sourse文件夹下所以在Eclipse中并不显示,需要手工调整下位置即可。
接下来只要再写两句简短的java代码即可完成对远程WebService方法的调用。
example:
Hello_PortType helloInstanse=new HelloServiceLocator().getHello();
//远程调用axis() 方法 并返回结果。
String result=helloInstanse.axis(" thirdServiceStub");
System.out.println(result);
--------------------
基于定制的WebService(这种在发布后就进行了注册)
简要步骤:写java类 -》写配置文件(可以自定义namespace)-》用adminclient处理下(参数为配置文件名)-》将方法类放到服务器classes目录下(必须包含与包名对应的目录)。
/************************************************************************************/
ri :reference implement 参考实现
jax-ws api的动态调用
----------------------------
jdk 6 自带了jax-ws WebService 版本为2.0
我们也可以在网上下载2.X的 jar包 ,这个版本包含了一些jdk自带包所没有的功能。
soap消息的格式有四种
使用jdk 6自带的jax-ws访问 WebService 的几种方法
第一种方法
使用jdk提供的 wsimport.exe 自动生成客户端代码,或者也可以直接使用MyEclipse生成,然后调用即可。
但是使用这种生成源代码对服务器端wsdl的soap消息格式有要求,有的格式不支持
第二种方法
使用jdk自带的 javax.xml.ws.Service
创建Service对象进行调用。
Service service=Service.create(URL,Qname);
T obj=service.getPort(Qname,serviceEndpointInterface); //返回代理对象
//之后就可以通过代理对象远程调用 WebService
第三种方法
动态面向消息调用的 javax.xml.ws.Dispatch 实例
这种方法为Dispatch.invoke(T msg)传递的 参数和返回值都为xml形式,拿到结果后还需要进行二次加工,进行解析生成对象。
Service service=Service.create(URL,Qname);
Dispatch<T> dis=service.createDispatch(QName portName, Class<T> type, Service.Mode mode) ;
T obj=dis.invoke(T msg);
------------
创建jax-ws WebService
jax-ws WebService的创建使用到了java中的注解,
目前有两种配置创建方法:
1. 写好Service 接口和其实现类,实现类使用注解指明WebService的配置。
然后在web.xml中注册此Service实现类。这样就可以去发布成为一个WebService了。
注意:由于发布的是一个WebService工程,web.xml的配置中注册的是一个Service类,而不是servlet。所以只能使用包含WebService容器的服务器进行部署,如Jboss。象Tomcat这样的服务器由于只是一个Web container ,所以并不支持对非servlet的注册。
2. 通过sun提供的一个监听器WSServletContextListener,就可以把此service模拟成一个大servlet进行发布。
这种方式主要是添加了两处配置而完成。配置添加/WEB-INF/sun-jaxws.xml文件 和配置web.xml文件 ,其具体配置内容可以参考 JAX-WS WebService API ,基本只需复制修改即可完成。
使用jax-ws创建 WebService 过程中注解释义(详细介绍还请看 API DOC,这里仅作简要介绍):
@WebService 标记此类为WebService
@SOAPBinding
@Oneway 这一注解标记当前方法为单向的 ,即可以理解为没有返回值的方法。由于此注解的保留范围是RUNTIME,所以当部署WebService时就会检查,如果方法的定义不符和要求就会报出异常:com.sun.enterprise.deployment.backend.IASDeploymentException
@WebMethod
如果类中没有方法加此注解,则默认全部为webservice中的方法。否则只显示添加了此注解的方法。
@WebResult
@WebParam 其对方法的参数进行注解。它总是在每一个参数前进行定义
使用jax-ws WebService 时,如果返回的对象为一个List,那么必须使用泛型才可以保留list中的对象类型信息。
Endpoint.publish("http://localhost:7070/Ebay%22,);//jdk1.6 带了一个小型的服务器,在这个上创建一个webservice ,这种方式仅供学习时使用
--------------------------
使用xfire WebService
主要步骤:导入必要的jar包 -》 建立service接口和实现类 -》配置service.xml(可以参考xfire doc) -》 在web.xml中配置xfire的注册映射(基本固定写法,可参考doc)
使用