使用远程服务——WebService(JDK版)
使用JDK编写WebService示例
概述
近几年,最流行的一个TLA(三个字母缩写)就是SOA(面向服务的架构)。SOA对不同的人意味着不同的意义。但是,SOA的核心理念是,应用程序可以并且应该被设计成依赖于一组公共的核心服务,而不是为每个应用都重新实现相同的功能。
例如,一个金融机构可能有若干个应用,其中很多都需要访问借款者的账户信息。在这种情况下,应用应该都依赖于一个公共的获取账号信息的服务,而不应该在每一个应用中都建立账户访问逻辑(其中大部分逻辑都是重复的)。
关于WebService更多详细的解释参见:WebService学习总结 - 随笔分类 - 孤傲苍狼 - 博客园
在本篇中,使用java的jax-ws支持把使用远程服务——RMI(java版)_szuaudi的博客-CSDN博客中的user服务发布为web服务并使用此web服务。
编码
新建工程
在eclipse中新建java工程
输入工程名称webservice-java
点击“Finish”,这样就创建了一个空的java工程
目录结构
在工程中/webservice-java/src添加如下包
- me.aodi包::应用程序跟目录;
- me.aodi.model:模拟数据模型;
- me.aodi.service:服务接口;
- me.aodi.service.impl:接口实现类;
编写WebService功能
- 新建me.aodi.model.User类模拟数据模型;
package me.aodi.model;
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 新建
me.aodi.service.UserService
接口
package me.aodi.service;
import java.rmi.RemoteException;
import java.util.List;
import me.aodi.model.User;
public interface UserService{
/**
* 返回所有user
* @return
* @throws RemoteException
*/
public List<User> all();
}
- 新建
me.aodi.service.impl.UserServiceImpl
实现类
package me.aodi.service.impl;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebService;
import me.aodi.model.User;
import me.aodi.service.UserService;
@WebService(serviceName = "user", targetNamespace = "http://service.aodi.me/")
public class UserServiceImpl implements UserService {
/**
* 模拟返回所有user
*/
@Override
public List<User> all()
{
User user = new User();
user.setId(1);
user.setName("用户1");
List<User> list = new ArrayList<User>(1);
list.add(user);
return list;
}
}
- 新建
me.aodi.WebServiceServer
服务端类
package me.aodi;
import javax.xml.ws.Endpoint;
import me.aodi.service.UserService;
import me.aodi.service.impl.UserServiceImpl;
/**
* 服务器端
* @author audi
*
*/
public class WebServiceServer {
public static void main(String[] args) {
String address = "http://localhost:8001/user";
UserService userService = new UserServiceImpl();
/**
* 发布WebService服务
*/
Endpoint.publish(address, userService);
System.out.println("user service publiced!");
}
}
- 编写WebService客户端
SOAP基于HTTP协议之上,那么WebService就具有了夸平台,夸语言的性质。我们尝试编写php脚本,对UserServer进行调用:
编辑webservice_client.php文件:
<?php
$soapClient = new SoapClient("http://localhost:8001/user?wsdl");
$response = $soapClient->__soapCall('all', []);
var_dump($response);
补充:关于PHP的SoapClient更多参见:PHP: SoapClient - Manual
运行实例
- 编辑后的工程目录结构
- 运行服务端应用
在WebServiceServer打断点,防止程序立马执行完退出
- 调试模式运行WebServiceServer.java
程序会在断点处停止
如果控制台没有错误日志,那么WebService已经发布成功,WebService传输协议采用基于的SOAP,我们可以通过在浏览器输入http://localhost:8001/user?wsdl
查看web服务的wsdl格式描述:
- 运行webservice_client.php
在控制台输入php webservice_client.php
可以看到输出结果:
也可以开启服务器后,在浏览器中运行webservice_client.php:
总结
使用JDK自带的jax-ws发布web服务看起来并不是特别麻烦,但使用web服务却不像php的SoapClient那样简洁,在下一篇中,我们将使用Spring来发布和使用Web服务,Spring提供了一个jax-ws服务导出器SimpleJaxWsServiceExporter,像使用RmiServiceExporter创建RMI服务一样,这些服务导出器很神奇地将Spring配置的POJO抓换成了远程服务。Spring还提供了一个装配jax-ws的代理工厂bean JaxWsProxyFactoryBean,它能生成一个知道如何与SOAP Web服务交互的代理。所创建的代理实现了服务结构,我们可以像使用本地POJO一样使用远程web服务。