最近在学习WebService,今天尝试用Eclipse的插件生成JAX-WS WebService,结果遇到了不少的问题啊,调试了大半天终于把程序跑通了。现在把步骤和问题记录一下,也为了以后遇到相同的问题时能够及时解决。首先利用Eclipse生成WebService的服务端。
1、 创建一个web工程,DynamicWeb Project (File->New->Dynamic Web Project),取名叫“ws-server”
1、 编写提供服务的接口和实现类
AddService.java,注意两点:(1)在接口定义之前加上@WebService标注,表明这是一个WebService服务,否则在生成服务端时不能找到相应的接口;(2)这里@WebService标注的targetNamespace一定要填写内容,不然在生成WebService服务端的时候会报如下的错误,这个命名空间起始就是包名的倒序。
IWAB0014E Unexpected exception occurred.
The name "" is not legal for JDOM/XML namespaces: Namespace URIs must be non-null and non-empty Strings.
org.jdom.IllegalNameException: The name "" is not legal for JDOM/XML namespaces: Namespace URIs must be non-null and non-empty Strings.
package ws.demo.service;
import javax.jws.WebService;
@WebService(targetNamespace="http://service.demo.ws/")
public interface AddService {
public int add(int a, int b);
}
AddServiceImpl.java,同样的定义这个实现类之前也要加上@WebService标注,并且指向它实现的接口。
package ws.demo.service.impl;
import javax.jws.WebService;
import ws.demo.service.AddService;
@WebService(endpointInterface = "ws.demo.service.AddService")
public class AddServiceImpl implements AddService {
@Override
public int add(int a, int b) {
return a + b;
}
}
写好提供服务的接口和实现类后的项目结构:
3、生成WebService服务(File->New->Other->Web Services->WebService),在Service implementation中选择提供服务的实现类。
可以在Configuration里面选择运行的环境,我使用的是Tomcat 7.0和CXF,在选择CXF作为运行环境的时候需要先将CXF的环境导入进行Eclipse,否则会报Unable to add the follwing facets to project ws-server: CXF 2.x Web Services错误。导入过程如下:
4、以上配置完成后,生成WebService服务(File->New->Other->WebServices->Web Service),选择提供服务的实现类,配置运行环境,然后点击Next,选择或生成一个提供服务的接口,选择完成后,点击Next。
5、 选择需要加标注的内容,包括@WebMethod, @WebParam, @RequestWrapper, @ResponseWrapper, @WebResult等等,选择完成后,点击Next。
6、选择Java2WS的配置信息,同时也可以选择SOAP的版本,然后点击Next,Eclipse会在后台生成相应的文件并在控制台打印日志。
java2ws -cp E:\workspace\ws-server\build\classes -s E:\workspace\ws-server\.cxftmp/src -d E:\workspace\ws-server\.cxftmp/wsdl -classdir E:\workspace\ws-server\build\classes -o addserviceimpl.wsdl -createxsdimports -verbose -frontend jaxws -databinding jaxb -wsdl -wrapperbean ws.demo.service.impl.AddServiceImpl
java2ws - Apache CXF 3.1.6
六月 14, 2016 3:51:03 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://impl.service.demo.ws/}AddServiceImplService from class ws.demo.service.AddService
生成后的项目结构:
生成服务端时要将Eclipse的jre改成jdk包中的jre,否则会报:
Exception in thread "main" java.lang.NullPointerException
at org.apache.cxf.common.util.Compiler.useJava6Compiler(Compiler.java:190)
at org.apache.cxf.common.util.Compiler.compileFiles(Compiler.java:144)
at org.apache.cxf.common.util.Compiler.compileFiles(Compiler.java:139)
同时要将Tomcat会读取默认的jre,这里也需要将Tomcat的jre改掉。修改完成后的jre版本:
7、 按理说现在需要的文件都已经生成了,程序应该可以运行了,但是实际情况并非如此,先启动服务器,结果报错:
严重: Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:META-INF/cxf/cxf-extension-soap.xml]
Offending resource: ServletContext resource [/WEB-INF/cxf-beans.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [META-INF/cxf/cxf-extension-soap.xml]; nested exception is java.io.FileNotFoundException: class path resource [META-INF/cxf/cxf-extension-soap.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
这是因为WEB-INF目录下的cxf-beans.xml文件里有
这几段将cxf.xml、cxf-extension-soap.xml、cxf-servlet.xml引进来了,但是我使用的CXF3.1.6版本并不会生成这几个文件,所以需要将这几段删除。同时还要删除cxf-services-ws-discovery-api-3.1.4.jar、cxf-services-ws-discovery-service-3.1.4.jar、cxf-services-wsn-api-3.1.4.jar、cxf-services-wsn-core-3.1.4.jar这几个jar包,否则在启动后虽然服务可以发布,但是过一段时间就会报prefix wsdp is not bound to a namespace。
严重: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'addservice': Invocation of init method failed; nested exception is javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Could not find definition for service {http://service.demo.ws/}AddServiceImplService.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1572)
可以看到,这里的jaxws:endpoint属性里面有serviceName的属性,属性名为AddServiceImplService,这些都是框架自动生成文件时加上的,现在把这些不需要的删去,改为如下的内容:
再启动服务器,启动成功,访问http://localhost:8080/ws-server/services/,出现如下结果:
再点击wsdl的链接,可以看到生成的wsdl文件: