axis发布webservice客户端
关于axis部署参考http://sducxh.iteye.com/blog/830414
注意这里是axis不是axis2
下载axis1.4地址:axis-bin-1_4.zip
环境配置:
JAVA_HOME C:\Program Files\Java\jdk1.6.0_23
CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
AXIS_HOME E:\soft4develop\axis-1_4
AXIS_LIB %AXIS_HOME%\lib
AXISCLASSPATH %AXIS_LIB%\axis.jar;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis-ant.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\commons-logging-1.0.4.jar;%AXIS_LIB%\commons-discovery-0.2.jar
发布axis用的是tomcat ,发布的时候遇到一个问题
1 No compiler found in your classpath! (you may need to add 'tools.jar')
解决的方式是
Copy the tools.jar in C:\Program Files\Java\jdk1.6.0_18\lib to C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib
也就是将JDK/LIB目录下的tool.jar复制到tamcat/lib目录下,1.5的JDK也没问题。
如果tools.jar版本不对的话,就会爆出如下异常
faultCode: {http://xml.apache.org/axis/}Server.compileError
无法编译你的Jws文件。
当然也可以通过环境变量来设置了。
1:Dynamic Invocation Interface动态调用接口
1 String endpoint = "http://localhost:" +"8080"+ "/axis/HelloWorld.jws";//指明服务所在位置 2 Service service=new Service(); 3 Call call=null; 4 try { 5 call= (Call) service.createCall(); 6 call.setTargetEndpointAddress( new java.net.URL(endpoint) );//为Call设置服务的位置 7 call.setOperationName( "sayHello" );//注意方法名与HelloWorld.java中一样!! 8 String res = (String) call.invoke( new Object[] {} );//返回String,没有传入参数 9 System.out.println( res ); 10 } catch (ServiceException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } catch (MalformedURLException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } catch (RemoteException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 }
2:Dynamic Proxy动态代理方式
1.将DynimicProxy.java编译成DynimicProxy.class,放到%TOMCAT_HOME%\webapps\axis\WEB-INF\classes下
2、在%TOMCAT_HOME%\webapps\axis\WEB-INF下新建deploy.wsdd文件,即SOAP服务发布描述文件deploy.wsdd
1 <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 2 <service name="DynimicProxyService" provider="java:RPC"> 3 <parameter name="className" value="DynimicProxy"/> 4 <parameter name="allowedMethods" value="hello"/> 5 </service> 6 </deployment>
在DOS下转换目录到%TOMCAT_HOME%\webapps\axis\WEB-INF,命令:
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd
你会发现目录下多了一个server-config.wsdd文件,这就是AXIS的配置文件,以后所有的服务发布描述都会在里面找到。(当然,你可以直接修改它,不用再写deploy.wsdd)然后打开浏览器http://localhost:8080/axis/servlet/AxisServlet,你就会看到你的服务已发布
同样用客户端程序访问一下:(注意和上边的差别!!)
客户端访问代码
1 String endpoint = "http://localhost:" +"8080"+ "/axis/services/DynimicProxyService";//注意!差别仅仅在这里!! 2 3 Service service = new Service(); 4 Call call; 5 try { 6 call = (Call) service.createCall(); 7 call.setTargetEndpointAddress( new java.net.URL(endpoint) ); 8 call.setOperationName("hello" ); 9 call.addParameter("msg", XMLType.XSD_STRING, ParameterMode.IN); 10 call.setReturnType(XMLType.XSD_STRING); 11 String res = (String) call.invoke( new Object[] {"lwx"} ); 12 13 System.out.println( res ); 14 } catch (Exception e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 }
打印结果: 您好,lwx
期间出现了两个异常
1 - No returnType was specified to the Call object! You must call setReturnType() if you have called addParameter(). 2 AxisFault 3 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException 4 faultSubcode: 5 faultString: java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class DynimicProxy); nested exception is: 6 java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class DynimicProxy) 7 faultActor: 8 faultNode: 9 faultDetail: 10 {http://xml.apache.org/axis/}hostname:MICROSOF-AA33B2 11 12 java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class DynimicProxy); nested exception is: 13 java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class DynimicProxy) 14 at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222) 15 at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129) 16 at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087) 17 at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:633) 18 at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanEndElement(XMLNSDocumentScannerImpl.java:713) 19 at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1685)
一个是call忘记设置返回类型了
还有一个是编译类的jdk版本跟tomcat的版本不一致造成的。(java.lang.UnsupportedClassVersionError: Bad version number in .class file)
如果用户需要传入和接收自定义对象的参数
如下DEMO可以参考下
1.自定义类User
1 public class User { 2 private String username; 3 private String password; 4 5 public String getUsername() { 6 return username; 7 } 8 9 public void setUsername(String username) { 10 this.username = username; 11 } 12 13 public String getPassword() { 14 return password; 15 } 16 17 public void setPassword(String password) { 18 this.password = password; 19 } 20 21 22 public String toString(){ 23 24 return "username=="+username+"--password=="+password; 25 }
2.服务方法
1 public class DynimicProxy { 2 3 public String hello(String msg) { 4 5 return "您好," + msg; 6 } 7 8 public String checkUser(User user) { 9 if (null == user) 10 return "用户信息错误"; 11 12 return "您好," + user.getUsername(); 13 } 14 15 public User getUser(String password, String username) { 16 User user = new User(); 17 user.setPassword(password); 18 user.setUsername(username); 19 return user; 20 }
3.修改server-config.wsdd
1 <service name="DynimicProxyService" provider="java:RPC"> 2 <parameter name="allowedMethods" value="*"/> 3 <parameter name="className" value="DynimicProxy"/> 4 <beanMapping languageSpecificType="java:User" 5 qname="ns:User" xmlns:ns="urn:BeanService"/> 6 </service>
<parameter name="allowedMethods" value="*"/> --当方法很多个的时候 value的值采用通配符*
<beanMapping languageSpecificType="java:User" qname="ns:User" xmlns:ns="urn:BeanService"/>
默认通过命令是无法生成这句话
需要手动加
languageSpecificType --对应的是用户自定义类
qname-- 对应的是客户端代码的qname
4.客户端调用
1 String wsdlUrl = "http://localhost:8080/axis/services/DynimicProxyService?wsdl"; 2 String nameSpaceUri = "http://localhost:8080/axis/services/DynimicProxyService"; 3 4 Service service = new Service(); 5 Call call; 6 String ret =""; 7 try { 8 // 公共部分 9 call = (Call) service.createCall(); 10 QName qn = new QName("urn:beanservice", "User"); 11 call.registerTypeMapping(User.class, qn, new BeanSerializerFactory( 12 User.class, qn), 13 new BeanDeserializerFactory(User.class, qn)); 14 // end 15 16 // 调用hello 基础类型参数 17 call.setOperationName(new QName(nameSpaceUri, "hello")); 18 call.setTargetEndpointAddress(new java.net.URL(wsdlUrl)); 19 ret = (String) call.invoke(new Object[] { "lwx" }); 20 System.out.println("return value is " + ret); 21 22 // 调用checkUser //自定义对象参数 23 QName getDescQn = new QName(nameSpaceUri, "checkUser"); 24 call.setOperationName(getDescQn); 25 call.setTargetEndpointAddress(new java.net.URL(wsdlUrl)); 26 User user = new User(); 27 user.setPassword("88888"); 28 user.setUsername("lwx"); 29 30 ret = (String) call.invoke(new Object[] { user }); 31 32 //getUser //返回自定义对象参数 33 QName getObjectQn = new QName(nameSpaceUri, "getUser"); 34 call.setOperationName(getObjectQn); 35 call.setTargetEndpointAddress(new java.net.URL(wsdlUrl)); 36 User user2 = (User) call.invoke(new Object[] { "123456","admin" }); 37 System.out.println("return object " +user2.toString()); 38 39 // call.addParameter("msg", XMLType.XSD_STRING, ParameterMode.IN); 40 // call.setReturnType(XMLType.XSD_STRING); 41 42 System.out.println(ret); 43 } catch (Exception e) { 44 // TODO Auto-generated catch block 45 e.printStackTrace(); 46 }
3:stubs方式
默认axis自带的8个包不能满足
需要额外加入activation.jar xerces.jar 和mail.jar 并同时配置环境变量
接着将axisclasspath加入到classpath中。
虽然如此,但是出异常
1 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/axis/wsdl/WSDL2Java
各种尝试都失败了。真是蛋疼中。。
最后的问题是必须切换到jws或则wsdl的根目录下,才可以正常编译
正常编译后出现
通过这个命令: java org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true AddressBook.wsdl
来生成deploy.wsdd和undeploy.wsdd 文件
更多的请参考http://blog.csdn.net/manjianghong86/article/details/7311611
来到整体
我们使用自己的接口
则会在目录下多了一个localhost的文件夹
HelloWorld.java 定义了Web服务接口,此例中只有一个sayHello方法。
HelloWorldService.java 定义了用于获取Web服务接口的方法。
HelloWorldServiceLocator.java 接口HelloService的具体实现。
HelloWorldSoapBindingStub.java Web服务客户端桩,通过该类与服务器交互。
这四个JAVA类帮我们处理了大部分的逻辑,我们需要的仅仅是把这些类加到我们的项目然后创建一个我们自己的类来调用它们即可。为此我们新加一个类Main.java,为了方便,让这个类与刚产生的四个类都在同一个包下。内容如下:
HelloWorld.jws源码
1 public class HelloWorld { 2 public String sayHello() 3 { 4 return "HELLO WORLD!"; 5 } 6 }
客户端调用
1 HelloWorldService helloWorldService =new HelloWorldServiceLocator(); 2 3 try { 4 HelloWorld helloWorld =helloWorldService.getHelloWorld(); 5 System.out.println(helloWorld.sayHello()); //HELLO WORLD! 6 } catch (ServiceException e) { 7 // TODO Auto-generated catch block 8 e.printStackTrace(); 9 } catch (RemoteException e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 }
当然也可以直接调用命令来完成
使用以下命令进行编译:
javac -classpath lib\axis.jar;lib\jaxrpc.jar localhost\axis\HelloWorld_jws\*.java
如果编译没有问题的话执行该测试程序:
java -Djava.ext.dirs=lib -cp . localhost.axis.HelloWorld_jws.Main//运行结果
1 package localhost.axis.Hello_jws; 2 public class Main 3 { 4 public static void main(String[] args) throws Exception 5 { 6 HelloService service = new HelloServiceLocator(); 7 Hello hello = service.getHello(); 8 System.out.println("Response:"+hello.hello("BeatBLOG")); 9 } 10 }
好了 先如此了
关于axis2 aegis,webservice安全校验 等日后在说吧 。
未完,待续。
java常见异常:http://wenku.baidu.com/view/2f931f7ea26925c52cc5bf35.html
java常用Jar介绍:http://picker.blog.51cto.com/60843/712839
使用Eclipse的Axis1.4插件开发Web Service及客户端