微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebService学习之路一

闲来无事,根据教学视频学下WS,做下简单的记录…

 

现行的 WS主要有 SOAP XML 、axis2、xfire、CXF 等…

 

不管是哪种接口,哪种平台基于哪种语言开发的WS 都严格按照wsdl标准和soap协议。

 

以下的学习 主要都是基于注解的形式开发,jdk1.6,开发工具eclipse

 

一、第一个简单的示例

首先创建一个WS项目。


代码

Java代码  

收藏代码

  1. //定义接口  
  2.   
  3. @WebService(targetNamespace="com.trylin.ws.service")  
  4. public interface ITest {  
  5.     int add(int a,int b);  
  6.     int minus(int b);  
  7. }  
  8.   
  9. //定义实现类  
  10. @WebService(endpointInterface="com.trylin.ws.service.ITest")  
  11. class TestImpl implements ITest{  
  12.     int b) {  
  13.         return a+b;  
  14.     }  
  15.     return a-b;  
  16.     }  
  17. }  
  18.   
  19. //开启服务  

publicstaticvoid main(String[] args) {

       String address = "http://localhost:8888/WS";

       Endpoint.publish(address, new TestImpl());

}

 
   验证服务

打开浏览器,输入http://localhost:8888/WS?wsdl  显示发布服务的wsdl



 

代码解释

上述代码中实现了一个简单的WS的发布。

首先定义一个接口和实现类 ITest,TestImpl

然后加入@WebService  注解。

targetNamespace 属性表示发布后生成WSDL文件的命名空间(认值:当前类的包路径),对应namespace

<import namespace="http://com.trylin.ws.service/" location="http://localhost:8888/WS?wsdl=1"/>

这里有个小细节,注意到这个namespace是不是觉得有点别扭呢,先想想包命名原则,下面生成客户端调用的时候,简单再说明一下。

 

endpointInterface 属性表示实现的接口

 

Endpoint.publish(address, new TestImpl());

根据地址  和实现类,将接口发布。

发布后的WS地址就是 address ,可以直接访问,在address后加入 ?wsdl 可以查看接口发布后的wsdl。

 

 

客户端调用

上面就算是发布了一个简单的WS,简单吧,然后客户端怎么调用呢?

这里就用到了jdk 1.6自带的 wsimport命令

打开cmd命令窗口 ,输入 wsimport, 如图:(ps:请保证在你运行电脑的jdk环境变量设置正确,没有jdk配置环境变量,百度下)



 简单的介绍几个主要的命令

-d 指明生成WS客户端文件本地存放目录

-verbose 查看生成的详细信息(生成日志)

-p 指定ws客户端生成文件的包名(认按照 @webService定义的命名空间)

-keep 是否生成文件(加 表示生成文件中 包含java和 class,不加只有class)

 

创建本地客户端存放目录

D:/webservice/test

(记得开服务哦运行上面的main)

在cmd中 输入 wsimport -d D:\webservice\test -keep -verbose http://localhost:8888/WS?wsdl



 

generating code...   表示创建的java文件 

compiling code...    表示编译java文件

 

上面不是说过 wsdl上的命名空间有点问题,这下看日志有看出来吗?哈哈,应该有发现吧,生成的java源文件的目录是不是和我们在服务端的源文件目录刚好颠倒了呢。我也是看到这里才发现这个问题的。简单的说下我个人对这个问题的想法吧。

Java关于包,有个简单的命名原则,就是按照域名反向命名,比如 baidu.com 包名就叫com.baidu。我们生成的客户端文件是根据wsdl生成的,包名是根据wsdl中的namespace定义,只不过会将namespace视为一个域名,然后反向生成客户端类的包名。我在第一个示例中的接口中定义了@WebService(targetNamespace="com.trylin.ws.service") 按照反向,生成的包名就是service.ws.trylin.com   然后就出现了我们刚才的客户端文件和服务端文件包名相反的现象了。 

这个只是我个人的一个凭空猜想,没什么依据可言,呵呵。

 

OK,按照我上面的理解,我把命名空间 反向定义  service.ws.trylin.com

重新生成客户端。

然后再创建一个新的clinet项目,把生成的客户端复制到项目中,创建客户端测试类。

 


Java代码   /** 
  •  * @ClassName: ITestCase 
  •  * @Description:  
  •  * @author Try_Lin 
  •  * @date 2013-7-15 下午11:45:06 
  •  * 
  •  */  
  • class ITestCase {  
  •       
  •          * 根据java提供的ws调用 
  •      * @throws Exception 
  •      */  
  •     @Test  
  •     void testClient1() throws Exception{  
  •         URL url = new URL("http://localhost:8888/WS?wsdl");   //wsdl路径  
  •           
  •         //可以从  产生的wsdl中deFinitions 节点属性中 找到   targetNamespace  和 serviceName   
  •         String targetNamespace = "http://impl.service.ws.trylin.com/";//WS指向命名空间  
  •         String serviceName = "TestImplService";//WS发布服务名称  
  •         QName qname = new QName(targetNamespace, serviceName);  
  •         Service service = Service.create(url,qname);  
  •         ITest test = service.getPort(ITest.class);  
  •         System.out.println(test.add(12));  
  •     }  
  •          * 根据wsdl生成的客户端调用 
  • void testClient2(){  
  •         TestImplService service = new TestImplService();  
  •         ITest test = service.getTestImplPort();  
  •         System.out.println(test.add(3,0)">2));  
  •     }  
  •   
  • }  
  •  
     两种调用方式都可以,只是第二种方式看上去更加简洁。

      可以看下 第二种方式的 TestImplService代码 ,其实只是对第一种方式的部分封装。

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

    相关推荐