最近的一个项目需要提供一些webservice 服务,其中的WSDL文件已经提供,下面将这个服务的开发过程整理一下。
一.相关框架和工具
所用框架:JAX-WS
开发工具:MyEclipse 10
二.服务端开发:
1.新建web项目或者 web service项目,这个就不说了。
2.根据wsdl文件生成代码,过程如下:
右击包名,选择New->Other
在MyEclipse下Web Services 下选择Web Service
然后点Next
这里已经提供WSDL文件,需要通过WSDL文件生成服务端,所以我们选择上面一项,Create web service from WSDLcdocument,然后Next,到选择文件的界面,
对于文件可以有网络文件和本地文件两种形式,分别对应不同的选项。这里我用的是本地文件,然后再点Next,
好了,你也看到了,Finish来了,就它了。
3.文件生成之后,看看相关配置和代码的实现。
Finish之后会生成一些Java类文件,web.xml里也会增加相关配置的代码,如果是第一个接口还会增加sun-jaxws.xml这个文件,用来配置接口。如图所示是代码生成后的结构,下面的4个Java类都是实体类。上面的msgheader包下是头信息,也是实体类。 SBSCCMSSHImportFrameConChangeInfoSrv 是一个接口,除了注解,跟一般的接口看上去差不多,里面有未实现的方法,外部也是调用这个接口里的方法。不过接口里的方法是不能实现的,不用我说,接口实现类就是我们要实现接口的地方。
先看看web.xml文件的配置,这些都是自动生成的,一般除了 <url-pattern> 不需要修改。这个 <url-pattern> 就是这个服务的访问路径。这个服务的路径就是项目运行时候的路径+ <url-pattern> 。
再来看看另一个配置文件sun-jaxws.xml,
下面看看接口实现类 SB_SC_CMS_SHImportFrameConChangeInfoSrvPortImpl 这个文件,看看 javax.jws.WebService 这个注解:
endpointInterface :这个属性是服务端点接口,它的值就是 供其他系统调用的接口所在包+接口名。
targetNamespace : 命名空间。
serviceName :服务名称。
portName :端口名称。
在这里码上你想要实现的功能的代码就OK了。
4.加入需要的jar包
在发布项目之前我们还要加入相关的jar包。右击项目名选择 Build Path → Add Libraries
选择MyEclipse Libraries ,然后Next
选择我们要的包。如图,点击Finish,到这里我们的服务可以发布了。
好了,服务已经起来了,在浏览器里输入项目的运行路径+ url-pattern ,看看服务发布成功没,下面这个是我这个服务的路径:可以看到服务已经成功发布了。我们还要通过客户端调用测试一下接口能否被正常调用。
http://localhost:8080/demo/services/SB_SC_CMS_SHImportFrameConChangeInfoSrvPort
三.客户端开发(JAX-WS)
1.同服务端一样我们先用WSDL文件生成客户端代码,生成方式跟上面服务端的基本差不多,只有下面这里不一样:客户端应该选择Web Service Client。
生成后的代码结构如下图所示,其中的Test测试类不是自动生成的而是手动添加的。
2.下面是SBSCCMSSHImportFrameConChangeInfoSrv_Service 里面的代码,其中黄色标记的地方就是刚才生成客户端用的那个WSDL文件的地址,需要修改成想要访问的Webservice 服务的WSDL文件地址,我这里是用刚刚上面在本机上发布的服务端来生成的。
@WebServiceClient(name = "SB_SC_CMS_SHImportFrameConChangeInfoSrv",
targetNamespace = "http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv",
wsdlLocation = "http://localhost:8080/demo/services/SB_SC_CMS_SHImportFrameConChangeInfoSrvPort?wsdl") //这个是WSDL的地址 需要修改成服务端生成的WSDL地址
public class SBSCCMSSHImportFrameConChangeInfoSrv_Service extends Service {
private final static URL SBSCCMSSHIMPORTFRAMECONCHANGEINFOSRV_WSDL_LOCATION;
private final static Logger logger = Logger
.getLogger(com.cmcc.mss.sb_sc_cms_shimportframeconchangeinfosrv.SBSCCMSSHImportFrameConChangeInfoSrv_Service.class
.getName());
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.cmcc.mss.sb_sc_cms_shimportframeconchangeinfosrv.SBSCCMSSHImportFrameConChangeInfoSrv_Service.class
.getResource(".");
url = new URL(
baseUrl,
"http://localhost:8080/demo/services/SB_SC_CMS_SHImportFrameConChangeInfoSrvPort?wsdl"); //这个是WSDL的地址 需要修改成服务端生成的WSDL地址
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'http://localhost:8080/demo/services/SB_SC_CMS_SHImportFrameConChangeInfoSrvPort?wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SBSCCMSSHIMPORTFRAMECONCHANGEINFOSRV_WSDL_LOCATION = url;
}
public SBSCCMSSHImportFrameConChangeInfoSrv_Service(URL wsdlLocation,
QName serviceName) {
super(wsdlLocation, serviceName);
}
public SBSCCMSSHImportFrameConChangeInfoSrv_Service() {
super(SBSCCMSSHIMPORTFRAMECONCHANGEINFOSRV_WSDL_LOCATION, new QName(
"http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv",
"SB_SC_CMS_SHImportFrameConChangeInfoSrv"));
}
/**
*
* @return returns SBSCCMSSHImportFrameConChangeInfoSrv
*/
@WebEndpoint(name = "SB_SC_CMS_SHImportFrameConChangeInfoSrvPort")
public SBSCCMSSHImportFrameConChangeInfoSrv getSBSCCMSSHImportFrameConChangeInfoSrvPort() {
return super.getPort(new QName(
"http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv",
"SB_SC_CMS_SHImportFrameConChangeInfoSrvPort"),
SBSCCMSSHImportFrameConChangeInfoSrv.class);
}
}
看上面代码中最后一个方法getSBSCCMSSHImportFrameConChangeInfoSrvPort()
它的返回值就是我们想要的服务SBSCCMSSHImportFrameConChangeInfoSrv 。
所以我们可以通过这个方法获取Webservice服务。
3.新建一个带主方法的java类Test。在这里测试一下客户端能否调用我们刚刚发布的服务端。
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
SBSCCMSSHImportFrameConChangeInfoSrv_Service service = new SBSCCMSSHImportFrameConChangeInfoSrv_Service() ;
SBSCCMSSHImportFrameConChangeInfoSrv test = service.getSBSCCMSSHImportFrameConChangeInfoSrvPort() ;
SBSCCMSSHImportFrameConChangeInfoSrvRequest request = new SBSCCMSSHImportFrameConChangeInfoSrvRequest() ;
SBSCCMSSHImportFrameConChangeInfoSrvResponse response = test.process(request) ;
if(response != null){
System.out.println(response.getErrorFlag());
System.out.println(response.getErrorMessage());
}
}
}
看控制的输出,就是服务端设置的值,所以服务端和客户端都完成了。现在看看用另外一个框架XFire来完成客户端,,这个框架在服务端基本不使用了,配置比较繁琐。这个框架MyEclipse10已经不支持代码自动生成了,而且也没相关Jar包了,需要自己去网上找了,不过MyEclipse8.5还是可以的。 这个框架要求必须是web service项目才能使用wsdl文件自动生成代码,所以我们可以新建一个web service项目,用文件自动生成代码,再将代码拷到我们时间的项目里,也是可以用的。在生成代码的时候Framework选择XFire,其他完全一样。
下面是代码的结构,主要看看SB_SC_CMS_SHImportFrameConChangeInfoSrvClient 这个类
public SB_SC_CMS_SHImportFrameConChangeInfoSrvClient() {
create0();
Endpoint SB_SC_CMS_SHImportFrameConChangeInfoSrvLocalEndpointEP = service0 .addEndpoint(new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvLocalEndpoint"), new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvLocalBinding"), "xfire.local://SB_SC_CMS_SHImportFrameConChangeInfoSrv");
endpoints.put(new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvLocalEndpoint"), SB_SC_CMS_SHImportFrameConChangeInfoSrvLocalEndpointEP);
Endpoint SB_SC_CMS_SHImportFrameConChangeInfoSrvPortEP = service0 .addEndpoint(new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvPort"), new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvBinding"), "http://soa440:7001/soa-infra/services/wwk/SB_SC_CMS_SHImportFrameConChangeInfoSrv/SB_SC_CMS_SHImportFrameConChangeInfoSrv_ep");
endpoints.put(new QName("http://mss.cmcc.com/SB_SC_CMS_SHImportFrameConChangeInfoSrv", "SB_SC_CMS_SHImportFrameConChangeInfoSrvPort"), SB_SC_CMS_SHImportFrameConChangeInfoSrvPortEP);
}
上面标记的地方是服务的地址,不是WSDL的地址哦,不过这个地址+?wsdl就是wsdl的地址了,修改一下地址就可以了。
在这个类的最后是个主方法,可以在这个方法里直接调用服务端,这里service已经自动生成了,我们只要new 一个参数,调用service的到这里用XFire是实现的客户端的方法就好了。