cxf发布webservice

来源:互联网 发布:淘宝哪家店女装好看 编辑:程序博客网 时间:2024/05/16 06:03

注解和spring配置相结合

使用cxf与spring集成发布webservice的是非常方便的,下面简单写下基本的步骤以备忘.

1.首先当然是引用cxf相关的jar包.这里使用的是2.7.5的版本.

2.在web.xml文件中配置CXFServlet

<servlet><servlet-name>CXFServlet</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><load-on-startup>0</load-on-startup></servlet><servlet-mapping><servlet-name>CXFServlet</servlet-name><url-pattern>/ws/*</url-pattern><!--CXFServlet拦截RootPath/ws/*的请求--></servlet-mapping>


3.在spring配置文件中配置基本的cxf组件

<import resource="classpath:META-INF/cxf/cxf.xml"/><import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/><import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>


4.编写需要发布的POJO类

接口

@WebService(targetNamespace=Constants.TARGETNAMESPACE) public interface TestWebService {@WebMethod(operationName="SendMessage",action="http://xxx.xxx.Webservice/SendMessage")@WebResult(name="SendMessageResult",targetNamespace="http://yyy.yyy.Webservice/")public String receiveMsg(@WebParam(name="msg",targetNamespace=Constants.TARGETNAMESPACE) String msg);}

@WebMethod的属性operationName的值对应wsdl中的operationName,也即ws客户端所谓的方法名称。action的值对应soapAction的值。

@WebResult的属性name,ws会参数转换成xml的格式进行传递,而属性name指定该xml的根节点的名称;targetNameSpace则指定该名称所属的命名空间

@WebParam的属性name指定参数的名称,java虚拟机编译源文件时,通常情况下参数名称不会记录,而会用arg1,arg2之类的替换,转换成xml后对应的节点名称则为<arg0></arg0>,设置name属性可以指定该xml节点的名称为<msg></msg>.

实现

@WebService(serviceName="TestWebService", targetNamespace=Constants.TARGETNAMESPACE, endpointInterface="ws.TestWebService")public class TestWebServiceImpl implements TestWebService {@Overridepublic String receiveMsg(String msg) {              return "接收成功";}}

serviceName对应wsdl中的<wsdl:service name="TestWebService">中的name.

endpointInterface为该实现类的接口的全限定名称.

5.在spring配置文件中发布该pojo为webservice

 <jaxws:endpoint address="SendMessage"  implementor="ws.impl.TestWebServiceImpl">   </jaxws:endpoint>  

address指定了该webservice对应的URI,结合web.xml文件中的CXFServlet配置,访问该webservice的Url为

http://hostip:port/WebRoot/ws/SendMessage

wsdl链接为

http://hostip:port/WebRoot/ws/SendMessage?wsdl

6.部署并通过wsdl链接来验证webservice是否发布成功.

以上发布webservice的方法会把接口中所有的方法发布成webservice接口

 

零配置发布pojo为webservice

第1,2,3步与上面一致.

4.编写需要发布的pojo类

接口

public interface TestWebService {     public String receiveMsg(String msg);
     public String sendMessage(String msg);}

实现

public class TestWebServiceImpl implements TestWebService {@Overridepublic String receiveMsg(String msg) {              return "接收成功";}
         @Override
         public String sendMessage(String msg) 
         { 
              return "接收成功";
         }}

5.发布pojo类为webservice

                  ReflectionServiceFactoryBean rsfb = new ReflectionServiceFactoryBean();List<Method> list = new ArrayList<Method>();Class clazz = Thread.currentThread().getContextClassLoader().loadClass("ws.impl.TestWebService");Method [] methods = clazz.getDeclaredMethods();for(int i=0;i<methods.length;i++){if(methods[i].getName().equals("sendMessage")){list.add(methods[i]);}}
                  //设置需要过滤到的方法,既这些方法不需要被发布成webservice接口rsfb.setIgnoredMethods(list);
                  //指定endpointNamersfb.setEndpointName(new QName("TestEndpointName"));//指定serviceNamersfb.setServiceName(new QName("http://lqin.szse.cn/test","ServiceName1",XMLConstants.DEFAULT_NS_PREFIX));List<AbstractServiceConfiguration>  listAsc = rsfb.getServiceConfigurations();if(listAsc == null){listAsc = new ArrayList<AbstractServiceConfiguration>();}listAsc.add(new AbstractServiceConfiguration(){                            //设置soapAction为"http://lqin.com/sa",可以根据不同的方法返回不同的soapAction@Overridepublic String getAction(OperationInfo op, Method method) {return "http://lqin.com/sa";}                            //设置发布的webservice方法名称,此处可以根据不同的方法返回不同的方法名称@Overridepublic QName getOperationName(InterfaceInfo service, Method method) {return new QName("CustomOperationName");}});ServerFactoryBean sfb = new ServerFactoryBean(rsfb);Object o = SpringUtils.getBean(serviceBeanId);sfb.setServiceClass(clazz);sfb.setServiceBean(new TestServiceImpl());sfb.setAddress("/test");sfb.create();

在前一节中,是通过注解和spring配置的方式配置webservice的,那么在零配置的情况下webservice所需的参数从哪里来呢?答案在于

List<AbstractServiceConfiguration> listAsc = rsfb.getServiceConfigurations();

在获取某一个属性的值时,比如operationName,会遍历listAsc中的AbstractServiceConfiguration#getOperationName方法并返回第一个不为null的值,否则返回空字符串.

ReflectionServiceFactoryBean默认注册了一个DefaultServiceConfiguration,该ServiceConfiguration会返回系统默认生成的属性值,比如operationName默认是方法的名称,soapAction默认为空.如此,如果想要自定义opertaionName的值,那么必须先删除DefaultServiceConfiguration再实现一个AbstractServiceConfiguration返回operationName,或者把返回自定义的operationName放到DefaultServiceConfiguration的前面(建议自定义的放前面).

在上面的代码中,我们提供了一个AbstractServiceConfiguration的实现并重写了getAction方法和getOperationName方法,并且把它加到了DefaultServiceConfiguration的后面,根据上面的分析,soapAction自定义有效,而operationName则无效.

将上面的代理在servlet容器启动之后执行,访问

http://hostip:port/WebRoot/ws/test?wsdl路径可以看到webservice发布成功.

附上ServerFactoryBean#create()方法应用AbstractServiceConfiguration的执行路径:

ServerFactoryBean#create

AbstractWSDLBasedEndPointFactory#createEndPoint

ReflectionServerFactoryBean#create

ReflectionServerFactoryBean#initializeServiceModel

ReflectionServerFactoryBean#buildServiceFromClass//这里还有一个方法叫做buildServiceFromWSDL

ReflectionServerFactoryBean#createInterface

ReflectionServerFactoryBean#createOperation

ReflectionServerFactoryBean#getOperationName

 

 



 




 

0 0
原创粉丝点击