WebService学习之路一 :http://trylin.iteye.com/blog/1906819
WebService学习之路二 :http://trylin.iteye.com/blog/1907883
WebService学习之路三 :http://trylin.iteye.com/blog/1908269
WebService学习之路四:http://trylin.iteye.com/blog/1910979
根据契约优先原则开发WS
其实前面的方式 我们都可以看作是使用代码优先的模式开发的WS端(代码优先,先开发代码生成WS,然后才有根据WS生成的WSDL;契约优先,先开发规则WSDL,在根据规则生成代码)。
在第二章简单的分析过WSDL的元素,WSDL的元素规律很像java代码中的之间的引用。试着手写出一个符合要求的WSDL。
首先 新建一个WS_WEB的动态WEB项目(我使用的是eclipse,如果用的myeclipse直接新建web项目),这里用WEB项目是为了稍后能够发布到tomcat上启动我们的WS。
然后新建test和resource两个源码包 ,并且在resource下 建立wsdl包,然后在wsdl包下创建UserService.wsdl文件(wsdl文件格式,eclipse可以直接创建,newàotherà输入wsdl选中即可,创建过程,默认就行)。创建后 出现的系统默认的wsdl格式 。
项目结构:
UserService.wsdl
这些个格式,看着应该很熟悉了吧.。。。
好了 ,我们开始手动写WSDL ,先把definitions节点下的所有节点删除,并且修改definitions的默认命名空间。
然后,我们开始定义元素类型和元素。(如果忘记WSDL格式,可以打开之前的项目,然后作为参考,多看几遍,记下来)
定义types
定义 portType和 binding
定义服务项
如上,我们就手动写了一个WSDL,测试的时候,最好还是手动的敲。。。动手实践才是关键。
然后,我们用wsimport命令 ,根据此wsdl生成java类 。
wsimport –d d:/webservice –keep –verbose E:\work\WS_WEB\resource\wsdl\UserService.wsdl
运行命令后,查看d:/webservice 是不是生成了这些文件,这就表示,我们手写的WSDL已经成功了。
然后这里我们需要做两步操作,第一步,将IUserService接口类复制到我们的服务端,第二步,新建一个客户端,然后将所有的java类放到客户端的代码中。
Copy到客户端,这个容易理解,我们做客户端调用需要这些类,但是服务端为什么也要这样copy呢,而且只需要copy一个java类。
这就是契约优先。我们之前先定义了一个WSDL的接口规范,规范定好了,服务端和客户端就可以同时按照WSDL定义的标准进行开发wsdl是xml格式,解释成java代码就服务端copy的接口类(这里是 IUserService),然后服务端就可以根据接口开发对应的功能呢。。。
开发服务端:
IUserService copy到服务端后,会报错,有个错误的引用,把引用的注解删除。
新建一个IUserService的实现类UserService类
@WebService(name="UserService",serviceName="UserService",endpointInterface="com.trylin.service.IUserService"
, targetNamespace = "http://service.trylin.com")
@WebServiceRef(wsdlLocation="wsdl/UserService.wsdl")
public class UserService implements IUserService {
@Override
public int add(int a, int b) {
System.out.println(a+"+"+b+"="+(a+b));
return a+b;
}
@Override
public int minus(int a, int b) {
System.out.println(a+"-"+b+"="+(a-b));
return a-b;
}
}
注意类上面的注解 :
@WebService serviceName 表示服务名
@WebServiceRef wsdlLocation 本地wsdl文件的引用
然后创建main启动服务
/**
* @param args
*/
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:8888/WS", new UserService());
}
浏览器中输入 http://127.0.0.1:8888/WS?wsdl,是不是和之前生成的WSDL一样一样的。。。。
然后在客户端创建测试代码调用(客户端的代码我就不写出来了,和之前的差不多,文章结尾会有测试源码)
@Test
public void test01() throws Exception{
/*IUserService iUser = new UserService().getUserServicePort();*/
//这里使用另外的一种方式调用 手动传QName 这样我们可以指定URL,如果项目迁移,或者是服务换端口,默认的地址就会失效
//所以这里用下这种方式调用
URL url = new URL("http://127.0.0.1:8888/WS");
QName qname = new QName("http://service.trylin.com","UserService");
IUserService iUser = new UserService(url,qname).getUserServicePort();
System.out.println(iUser.add(1, 2));
System.out.println(iUser.minus(3, 2));
}
普通类型的完成,试试复杂类型的创建哦。
主要测试自定义类型User 和 List<User>
首先在节点中添加User对象和List对象,并且新增login方法和getList方法
然后使用 wsimport重新生成 java类,服务端覆盖原有的接口,并且从新实现,由于这里用到的自定义类型User,所以服务端,我们需要自己在建立一个user对象。
<!--EndFragment-->
<spay�ye(�j��ze:10.0pt; font-family:"courier="" new";color:black;mso-font-kerning:0pt'=""> 节点中添加User对象和List对象,并且新增login方法和getList方法
Public class User{
private String userName;
private String userPwd;
private String age;
private String nickName;
}
UserService新增方法
@Override
public List<User> getList() {
List<User> lu = new ArrayList<User>();
Set<String> keySet = DBUser.keySet();
Iterator<String> key_it = keySet.iterator();
while(key_it.hasNext()){
String key = key_it.next();
lu.add(DBUser.get(key));
}
return lu;
}
@Override
public User login(String userName, String userPwd) {
User user = DBUser.get(userName);
if(null!=user && userPwd!=null && userPwd.equals(user.getUserPwd())){
return user;
}
return null;
}
重新发布:
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:8080/UserService", new UserService());
}
客户端调用:
@Test
public void test02(){
IUserService iUser = new UserService().getUserServicePort();
List<User> userList = iUser.getList();
for (User user : userList) {
System.out.println("nickName :"+user.getNickName());
}
User loginUser = iUser.login("zhangsan", "123456");
if(loginUser == null ){
System.out.println("登录失败");
}else{
System.out.println(loginUser.getNickName());
}
}
这样我们的自定义类型也就发布成功了。。。
源代码在下方,欢迎下载,希望看到不足的地方,留下你们的金玉良言。。。
下一章会把基于 tomcat发布的写出来。今天太困了。。。撤退。。。